加快camera2的图像捕捉速度

时间:2017-06-22 21:20:02

标签: java android android-camera camera2

我正在使用Android应用程序,该应用程序通过camera2 api拍摄照片。我面临的问题是在拍摄照片和照片之间的巨大延迟。按钮和实际的图像捕捉 - 约1800-2000毫秒左右,我个人认为是不可接受的。

如果有人能指出改进方法,我真的很感激。为了它的价值,我稍后将JPEG输出图像处理成位图,如果这有所不同。

"拍照"课程如下所示。

protected void takePicture() {
    if (null == cameraDevice) {
        Log.e(TAG, "cameraDevice is null");
        return;
    }
    debugTime(1,"");
    try {
        Log.e(TAG, "Taking a picture");
        int width, height;

        Size trySize = defineSize();
        width = trySize.getWidth();
        height = trySize.getHeight();

        debugTime(3,"Defining sizes took ");
        ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
        List<Surface> outputSurfaces = new ArrayList<>(2);

        outputSurfaces.add(reader.getSurface());
        outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));

        debugTime(3,"Defining output surfaces took ");

        final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        captureBuilder.addTarget(reader.getSurface());
        captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

        debugTime(3,"Creating capture request took ");

        // Orientation
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

        debugTime(3,"Defining rotation took ");

        final File file = new File(Environment.getExternalStorageDirectory() + "/pic.jpg");

        debugTime(3,"Creating new file took ");

        ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {
                Log.e(TAG, "Running method onImageAvailable");
                Image image = null;
                try {
                    debugTime(3,"Image becoming available took ");
                    image = reader.acquireLatestImage();
                    debugTime(2,"");
                    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                    bytes = new byte[buffer.capacity()];
                    buffer.get(bytes); //My final output

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (image != null) {
                        image.close();
                    }
                }
            }
        };

        reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);

        final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
                super.onCaptureCompleted(session, request, result);
                Log.e(TAG, "Invoking running method sendToScan");
                sendToScan();
            }
        };

        cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(CameraCaptureSession session) {
                Log.e(TAG, "Running method onConfigured");
                try {
                    session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                debugTime(3,"Configuring capture session took ");
            }

            @Override
            public void onConfigureFailed(CameraCaptureSession session) {
            }
        }, mBackgroundHandler);
        //stopBackgroundThread();

    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

这是日志

E/CameraActivity: Taking a picture
E/CameraActivity: Defining Size
E/CameraActivity: CHOOSING at size 720x1280
E/DEBUG_TIME: Defining sizes took 25 ms
E/DEBUG_TIME: Defining output surfaces took 20 ms
E/DEBUG_TIME: Creating capture request took 4 ms
E/DEBUG_TIME: Defining rotation took 1 ms
E/DEBUG_TIME: Creating new file took 5 ms
I/RequestQueue: Repeating capture request cancelled.
I/CameraDeviceState: Legacy camera service transitioning to state IDLE
I/CameraDeviceState: Legacy camera service transitioning to state CONFIGURING
I/RequestThread-0: Configure outputs: 2 surfaces configured.
D/Camera: app passed NULL surface
I/RequestThread-0: configureOutputs - set take picture size to 1280x720
I/CameraDeviceState: Legacy camera service transitioning to state IDLE
E/CameraActivity: Running method onConfigured
I/Choreographer: Skipped 38 frames!  The application may be doing too much work on its main thread.
W/art: Long monitor contention event with owner method=void java.lang.Object.wait!() from Object.java:4294967294 waiters=0 for 563ms
W/LegacyRequestMapper: convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
W/LegacyRequestMapper: Only received metering rectangles with weight 0.
E/DEBUG_TIME: Configuring capture session took 586 ms
E/BufferQueueProducer: [SurfaceTexture-0-17825-3] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=13 undequeued=0)
E/BufferQueueProducer: [SurfaceTexture-0-17825-3] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=12 undequeued=1)
I/CameraDeviceState: Legacy camera service transitioning to state CAPTURING
I/RequestThread-0: Received jpeg.
I/RequestThread-0: Producing jpeg buffer...
E/CameraActivity: Running method onImageAvailable
E/DEBUG_TIME: Image becoming available took 1110 ms
D/ImageReader_JNI: ImageReader_lockedImageSetup: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.
W/ImageReader_JNI: Unable to acquire a lockedBuffer, very likely client tries to lock more than maxImages buffers
E/DEBUG_TIME: Taking picture took 1752 ms in TOTAL

根据它,配置捕获会话(!)需要大约500-600ms,但更糟糕的是,图像在imageReader中可用大约需要1100-1200ms! / p>

显然有些不对劲,我无法弄明白。我很乐意提供任何帮助。

P.S。为了记录,我试图将结果保存为YUV_420_888格式,但这只能加速到我总共1000左右。

0 个答案:

没有答案