0

I try to implement high speed capture session by click on button. Here is my state callback:

private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {

    @Override
    public void onOpened(CameraDevice cameraDevice) {
        mCameraDevice = cameraDevice;
        startPreview();
    }

    @Override
    public void onDisconnected(CameraDevice cameraDevice) {
        mCameraOpenCloseLock.release();
        cameraDevice.close();
        mCameraDevice = null;
    }

    @Override
    public void onError(CameraDevice cameraDevice, int error) {
        mCameraOpenCloseLock.release();
        cameraDevice.close();
        mCameraDevice = null;
    }

};

open camera method:

 private void openCamera() throws CameraAccessException {
     CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
    try {
        mCameraCharacteristics = manager.getCameraCharacteristics(String.valueOf(currentCamID));
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
    manager.openCamera(String.valueOf(currentCamID), mCameraDeviceStateCallback, mHandler);
}

called when started preview and onClick event

  private void createCaptureSession(List<Surface> surfaces) throws CameraAccessException {

    if(mPreviewSession!=null){
        mPreviewSession.close();
        mPreviewSession = null;
    }
    if (!isHighSpeed) {
        Log.d(LOG_TAG, "createCaptureSession isHighSpeed" +isHighSpeed );

        mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {

            @Override
            public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                Log.i(LOG_TAG, "CameraCaptureSession onConfigured :" + cameraCaptureSession.hashCode());
                mPreviewSession = cameraCaptureSession;
                updatePreview();
            }

            @Override
            public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {

            }
        }, mHandler);
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Log.d(LOG_TAG, "createCaptureSession isHighSpeed" +isHighSpeed );
            mCameraDevice.createConstrainedHighSpeedCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {

                @Override
                public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                    Log.i(LOG_TAG, "CameraCaptureSession onConfigured :" + cameraCaptureSession.hashCode());

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        mPreviewSession = cameraCaptureSession;
                    }
                    updatePreview();
                }

                @Override
                public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
                    Log.e(LOG_TAG, "failed");
                }
            }, mHandler);
        }
    }
}

update preview is called above

private void updatePreview() {

    try {
        List<CaptureRequest> captureList = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M && isHighSpeed) {
            StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            Range<Integer>[] highSpeedVideoFpsRanges = map.getHighSpeedVideoFpsRanges();
            mPreviewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, highSpeedVideoFpsRanges[3]);//hardcode, 3 is the highest size for nexus6p

            captureList = ((CameraConstrainedHighSpeedCaptureSession) mPreviewSession).createHighSpeedRequestList(mPreviewBuilder.build());

            mPreviewSession.setRepeatingBurst(captureList, new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
                    super.onCaptureStarted(session, request, timestamp, frameNumber);
                }
            }, mHandler);
        } else {
            mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

The first time all is went right, but, when I try to start app again there is an error while open camera device, error code 1 in callback. Without running high fps all is good. To escape this issue device must be rebooted, that mystified me

releasingCamera:

@Override
public void onCamPause() {
   // super.onCamPause();
    stopPreview();
    closeCamera();
    stopBackgroundThread();
}

private void closePreviewSession() {
    if (mPreviewSession != null) {
        mPreviewSession.close();
        mPreviewSession = null;
    }
}

private void closeCamera() {
    try {
        mCameraOpenCloseLock.acquire();
        if (null != mCamera) {
            mCamera.close();
            mCamera = null;
        }

    } catch (InterruptedException e) {
        throw new RuntimeException("Interrupted while trying to lock camera closing.");
    } finally {
        mCameraOpenCloseLock.release();
    }
}

private void stopBackgroundThread() {
    if (mCameraThread != null) {
        mCameraThread.quitSafely();

        try {
            mCameraThread.join();
            mCameraThread = null;
            mCameraHandler = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}`

Here is a background thread for camera:

private void initCameraThread() {
    Log.e(TAG, "init camera thread begin.");
    mCameraThread = new HandlerThread("Camera Handler Thread");
    mCameraThread.start();
    mHandler = new Handler(mCameraThread.getLooper());
    Log.e(TAG, "nit camera thread done");
}
dur
  • 15,689
  • 25
  • 79
  • 125
Chickin Nick
  • 517
  • 1
  • 6
  • 21
  • also native camera app is not avaliable – Chickin Nick Jun 29 '16 at 15:37
  • Looks like you not release Camera device, when your app goes to background. You need to do it in onPause() or onStop() methods. – Maxim Metelskiy Jul 13 '16 at 08:41
  • I've done it, also in CameraDevice.StateCallback method OnClosed worked – Chickin Nick Jul 13 '16 at 08:49
  • Can you post the code of camera releasing. And what is mHandler? In what thread it is created? Also you may add additional check, that cameraDevice parametr in onDisconnected() is the same camera devise, you are using. – Maxim Metelskiy Jul 13 '16 at 09:05
  • But onDisconnected called when cameraDevice is already unavailable, when I switch camera to frontal all is works fine (no high speed session) – Chickin Nick Jul 13 '16 at 09:22
  • May be it happens, that thread is killed, before camera device is fully released. High speed camera session is more heavy, and that's why frontal camera works fine. – Maxim Metelskiy Jul 13 '16 at 09:54
  • I tried to stop background therad in onClose, but it is not helped – Chickin Nick Jul 13 '16 at 10:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/117189/discussion-between-chickin-nick-and-maxim-metelskiy). – Chickin Nick Jul 13 '16 at 10:25

0 Answers0