Search code examples
android-cameraandroid-camera2

Camera2: onCaptureCompleted() is not called


I recently started learning camera2 api, but I have some trouble. This code can be run when camera is emulated. However, when I use Webcam0 or virtual scene it will stuck after executing captureburst(), and without error message. It only shows that "The application may be doing too much work on its main thread." I check that it will call onCaptureStarted(), but will not call onCaptureCompleted(). AVD Manager: API30 Pixel 3

    public void takePicture(){

    if(cameraDevice == null){
        return ;
    }
    try {

        picturesRequestBuilder = cameraDevice.createCaptureRequest(cameraDevice.TEMPLATE_STILL_CAPTURE);
        //
        mImageReader.setOnImageAvailableListener(new OnImageAvailableListener(),mainHandler);
        //imageSurface = mImageReader.getSurface();
        //
        picturesRequestBuilder.addTarget(imageSurface);
        picturesRequestBuilder.addTarget(surface);
        picturesRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
        //
        CaptureRequest captureRequest = picturesRequestBuilder.build();

        ArrayList<CaptureRequest> captureRequests = new ArrayList<>();
       for(int i=0;i<5;i++){
            captureRequests.add(captureRequest);
        }
         mCameraCaptureSession.captureBurst(captureRequests, new CaptureCallback(),mainHandler);
    }
    catch (CameraAccessException e) {
        e.printStackTrace();
    }
    Log.d("test","finished");
}

///////////////

private void setupCamera(){
    cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);

    try{
        cameraIdList = cameraManager.getCameraIdList();
        cameraId = cameraManager.getCameraIdList()[0]; // 取得後置鏡頭
        cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
    } catch (CameraAccessException e){
        e.printStackTrace();
    }

    StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
    Size[] outputSizes = streamConfigurationMap.getOutputSizes(ImageFormat.JPEG);

    /////camera支援最大的高與寬////
    cameraWidth = outputSizes[0].getWidth();
    cameraHeight = outputSizes[0].getHeight();
    //////////////////////////////
    REQUIRED_PERMISSIONS.add(android.Manifest.permission.CAMERA);
    REQUIRED_PERMISSIONS.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
}

/////////

public void setPreview(){
    List<Surface> outputSurface = new ArrayList<>(2);
    SurfaceTexture surfaceTexture = cameraPreview.getSurfaceTexture();
    ImageReader imageReader = ImageReader.newInstance( 1920 , 1080, ImageFormat.JPEG, 1);
    imageReader.setOnImageAvailableListener(new OnImageAvailableListener(), childHandler);
    mImageReader = imageReader;
    imageSurface = imageReader.getSurface();
    surface = new Surface(surfaceTexture);

    outputSurface.add(surface);
    outputSurface.add(imageSurface);
    try{
        previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        previewRequestBuilder.addTarget(surface);

        cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                if(cameraDevice == null){
                    return;
                }
                mCameraCaptureSession = cameraCaptureSession;
                try {
                    previewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);

                    mCameraCaptureSession.setRepeatingRequest(previewRequestBuilder.build(), null, childHandler);
                }catch (CameraAccessException e) {
                    Log.d("TAG", "Error creating the preview session");
                    Log.d("TAG", e.getMessage());
                }
            }

            @Override
            public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
                Log.d("fail","Failed");
            }
        }, childHandler);
    } catch (CameraAccessException e) {
         Log.d("TAG", "Error setting up the camera preview");
         Log.d("TAG", e.getMessage());
    }
}

Solution

  • If you're using the emulator virtual scene for Android 11 beta (API level 30), there's a known bug in JPEG capture, which you may be running into: https://buganizer.corp.google.com/issues/160382725

    If it's the bug in question, the entire system logcat should show a crash involving a JPEG library for the camera HAL process.

    This will be fixed in a later update to the Android 11 SDK.