Android 使用setPreviewCallbackWithBuffer时,相机开始滞后
在我的相机应用程序中,我想使用Android 使用setPreviewCallbackWithBuffer时,相机开始滞后,android,android-camera,Android,Android Camera,在我的相机应用程序中,我想使用setPreviewCallbackWithBuffer()而不是普通的setPreviewCallback()方法。但是,我注意到,当我使用setPreviewCallbackWithBuffer()时,相机预览开始滞后几毫秒。知道我做错了什么吗?这是我的CameraView源代码 class CameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallba
setPreviewCallbackWithBuffer()
而不是普通的setPreviewCallback()
方法。但是,我注意到,当我使用setPreviewCallbackWithBuffer()
时,相机预览开始滞后几毫秒。知道我做错了什么吗?这是我的CameraView源代码
class CameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
private final String TAG = CameraView.class.getSimpleName();
private final SurfaceHolder mHolder;
private Camera mCamera;
public CameraView(Context context, Camera camera) {
super(context);
Log.d(TAG, "Creating Camera View.");
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(CameraView.this);
}
/**
* Stopping cameraPreview
*/
public void stopPreview() {
if (isPreviewOn && mCamera != null) {
Log.d(TAG, "Stopping Preview and releasing Camera.");
isPreviewOn = false;
mCamera.stopPreview();
mCamera.release();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "SURFACE CREATED");
//Some callback buffers to increase performance
initBuffer();
//start preview once the surface is created.
try {
//stopPreview();
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
//now it's time to initialize the ffmpeg recorder
//initRecorder();
}
private void initBuffer() {
Log.d(TAG, "Initialize Callback Buffers: " + BUFFER_SIZE);
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.setPreviewCallbackWithBuffer(this);
for (int i = 0; i < NUM_CAMERA_PREVIEW_BUFFERS; i++) {
mCamera.addCallbackBuffer(new byte[BUFFER_SIZE]);
}
}
/**
* Setting Camera parameters.
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters camParams = mCamera.getParameters();
camParams.setPreviewSize(imageWidth, imageHeight);
camParams.setPreviewFpsRange(30000, 30000);
mCamera.setParameters(camParams);
startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
try {
//mHolder.addCallback(null);
mHolder.removeCallback(this);
mCamera.setPreviewCallbackWithBuffer(null);
} catch (RuntimeException ignored) {
}
}
/**
* Starting camera preview.
*/
public void startPreview() {
if (!isPreviewOn && mCamera != null) {
Log.d(TAG, "Starting Preview.");
isPreviewOn = true;
mCamera.startPreview();
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
//...
mCamera.addCallbackBuffer(data);
}
private final int BUFFER_SIZE = (int) (imageWidth * imageHeight * 1.5);
private final int NUM_CAMERA_PREVIEW_BUFFERS = 3;
}
类CameraView扩展了SurfaceView实现了SurfaceHolder.Callback、Camera.PreviewCallback{
私有最终字符串标记=CameraView.class.getSimpleName();
私人最终出庭律师;
私人摄像机麦卡梅拉;
公共摄影机视图(上下文、摄影机){
超级(上下文);
Log.d(标记“创建摄影机视图”);
mCamera=摄像机;
mHolder=getHolder();
mHolder.addCallback(CameraView.this);
}
/**
*停止摄像检查
*/
公众谘询(){
if(ispreviewn&&mCamera!=null){
Log.d(标签“停止预览并释放相机”);
ispreviewn=false;
mCamera.stopPreview();
mCamera.release();
}
}
@凌驾
已创建的公共空白表面(表面持有人){
Log.d(标记“创建的表面”);
//一些回调缓冲区可以提高性能
initBuffer();
//创建曲面后开始预览。
试一试{
//回顾();
mCamera.setPreviewDisplay(支架);
}捕获(IOException异常){
mCamera.release();
mCamera=null;
}
//现在是初始化ffmpeg录像机的时候了
//initRecorder();
}
私有void initBuffer(){
Log.d(标记“初始化回调缓冲区:”+缓冲区大小);
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.setPreviewCallbackWithBuffer(此);
对于(int i=0;i
复制数据以在字节[]缓冲区中使用它会增加开销。预览分辨率越大,速度越慢?是的。有时,它突然停下来滞后,然后慢慢开始重新开始。。。我使用缓冲区是为了获得更稳定的帧速率。你想做什么?如果你把每一帧都复制到一个byte[]缓冲区中,我怀疑你能否跟上30fps的视频。