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的视频。