title: Camera starts to lag when using setPreviewCallbackWithBuffer
body: <p>In my camera application I want to use <code>setPreviewCallbackWithBuffer()</code> instead of the normal <code>setPreviewCallback()</code> method. However, I noteced that when I use <code>setPreviewCallbackWithBuffer()</code> the camera preview starts to lag a couple of <code>ms</code> wheras when using <code>setPreviewCallback()</code> without any buffers the lag dous not occur. Any idea what I am doing wrong? Here is my source code of CameraView.</p>
  
  <pre><code>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 &amp;&amp; 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 &lt; 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 &amp;&amp; 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;
  
  
  }
  </code></pre>