title: Camera onPreviewFrame not called on some devices
body: <p>I am expecting the LogCat to be logging <code>#onPreviewFrame()</code> multiple times, but it only works on selected devices like:</p>
  
  <ul>
  <li>Samsung Galaxy S6 (7.0)</li>
  <li>Samsung Galaxy S6 (6.0.1)</li>
  <li>LG Leon (5.0.1)</li>
  </ul>
  
  <p>But does not on the following devices:</p>
  
  <ul>
  <li>LG G4 (6.0)</li>
  <li>Huawei 6X (7.0)</li>
  <li>Nexus 6P (7.0)</li>
  </ul>
  
  <p>Below is the code snippet:</p>
  
  <pre><code>public CameraSurfaceView(Context context, AttributeSet set) {
    super(context, set);
    Log.d(TAG, "CameraSurfaceView(context, set)");
  
    // Get the Surface Holder
    this.holder = this.getHolder();
    this.holder.addCallback(this);
    this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  }
  
  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    try {
      // Turn on the Camera
      this.camera = Camera.open();
    } catch (Exception ex) {
      Log.e(TAG, "#surfaceCreated() error=" + ex.getMessage(), ex);
    }
  }
  
  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    Log.d(TAG, "#surfaceChanged()");
  
    if (holder.getSurface() == null) {
      // preview surface does not exist
      return;
    }
    if (camera == null) {
      // camera does not exist
      return;
    }
  
    // This allows us to make our own draw calls to this canvas
    this.setWillNotDraw(false);
    // Initialize canvas variables
    previewPaint = new Paint();
    // Initialize preview variables
    deviceWidth = width;
    deviceHeight = height;
    Camera.Size previewSize = this.camera.getParameters().getPreviewSize();
    previewWidth = previewSize.width;
    previewHeight = previewSize.height;
    previewBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888);
  
    // Initialize Scale Variables
    previewScaleMatrix = new Matrix();
    previewScaleMatrix.setScale(deviceWidth / (float) previewWidth,
        deviceHeight / (float) previewHeight, deviceWidth / 2.0f, deviceHeight / 2.0f);
  
    // Initialize RenderScript variables
    rs = RenderScript.create(getContext());
  
    // RenderScript YUV to RGB
    yuvToRgbScript = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
    Type.Builder previewRgbaType =
        new Type.Builder(rs, Element.RGBA_8888(rs)).setX(previewWidth).setY(previewHeight);
    yuvToRgbOut = Allocation.createTyped(rs, previewRgbaType.create(), Allocation.USAGE_SCRIPT);
  
    // RenderScript Invert
    invertScript = new ScriptC_invert(rs);
    invertOut = Allocation.createTyped(rs, yuvToRgbOut.getType(), Allocation.USAGE_SCRIPT);
  
    // Set color effect to none
    parameters.setColorEffect(Camera.Parameters.EFFECT_NONE);
    camera.setParameters(parameters);
  
    // Set the preview callback
    Log.d(TAG, "#surfaceChanged() camera.setPreviewCallback()");
    camera.setPreviewCallback(new Camera.PreviewCallback() {
      @Override
      public void onPreviewFrame(byte[] data, Camera camera) {
        Log.d(TAG, "#onPreviewFrame()");
      }
    });
  
    // Start the camera preview
    Log.d(TAG, "#surfaceChanged() camera.startPreview()");
    camera.startPreview();
  }
  
  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when replaced with a new screen
    // Always make sure to release the Camera instance
    if (camera != null) {
      camera.setPreviewCallback(null);
      camera.stopPreview();
      camera.release();
      camera = null;
    }
  }
  </code></pre>
  
  <p>My LogCat displays as follows:</p>
  
  <pre><code>D/CameraSurfaceView: #surfaceChanged()
  D/CameraSurfaceView: #surfaceChanged() camera.setPreviewCallback()
  D/CameraSurfaceView: #surfaceChanged() camera.startPreview()
  </code></pre>
  
  <p>The <code>ScriptC_invert</code> is from the <code>RenderScript</code> sample in <a href="https://developer.android.com/guide/topics/renderscript/compute.html#writing-an-rs-kernel" rel="noreferrer">https://developer.android.com/guide/topics/renderscript/compute.html#writing-an-rs-kernel</a></p>
  
  <p>And even if I remove all RenderScript stuff, the same problem.</p>
  
  <p>I've also tried the following:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/7042377/camera-onpreviewframe-not-called">Camera onPreviewFrame not called</a></li>
  <li><a href="https://stackoverflow.com/questions/14412618/android-onpreviewframe-is-not-called">Android onPreviewFrame is not called</a></li>
  </ul>
  
  <p><strong>NOTE:</strong></p>
  
  <p>One fix would need a <code>camera.setPreviewDisplay(holder)</code> in my <code>surfaceChanged()</code> method. But this will create another issue for me since I would need to do a <code>holder.lockCanvas()</code> in <code>onPreviewFrame()</code> and encounter the following exception:</p>
  
  <pre><code>E/SurfaceHolder: Exception locking surface
                   java.lang.IllegalArgumentException
                       at android.view.Surface.nativeLockCanvas(Native Method)
                       at android.view.Surface.lockCanvas(Surface.java:264)
                       at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:842)
                       at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:830)
                       at com.arcanys.ar.CameraSurfaceView.onPreviewFrame(CameraSurfaceView.java:204)
  </code></pre>
  
  <p>There might be some things that I've missed or misconfigured.</p>