Search code examples
androidyuvcamera2

Android Camera2, I aquire YUV image from ImageReader. U and V buffers have only one row(stride) data, the rest is zero


This is how I instantiate the ImageReader.

Size[] sizes = configs.getOutputSizes(ImageFormat.YUV_420_888);
        mImageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, 2);

        mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);

        Surface rgbCaptureSurface = mImageReader.getSurface();
        List<Surface> surfaces = new ArrayList<Surface>();
        surfaces.add(rgbCaptureSurface);

        //surfaces.add(surface);

        mPreviewRequestBuilder
                = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        //mPreviewRequestBuilder.addTarget(surface);

        mPreviewRequestBuilder.addTarget(rgbCaptureSurface);

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


            @Override
            public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                // The camera is already closed
                if (null == mCameraDevice) {
                    return;
                }

                // When the session is ready, we start displaying the preview.
                mCaptureSession = cameraCaptureSession;
                try {
                    // Auto focus should be continuous for camera preview.
                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                            CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);

                    // Flash is automatically enabled when necessary.
                    //setAutoFlash(mPreviewRequestBuilder);

                    // Finally, we start displaying the camera preview.
                    mPreviewRequest = mPreviewRequestBuilder.build();
                    mCaptureSession.setRepeatingRequest(mPreviewRequest,
                            mCaptureCallback, null);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

Reading is done like this:

  public void onImageAvailable(ImageReader reader) {
        Image image;
        while (true) {
            image = reader.acquireLatestImage();

            if (image == null) return;


            Image.Plane Y = image.getPlanes()[0];
            Image.Plane U = image.getPlanes()[1];
            Image.Plane V = image.getPlanes()[2];

            int Yb = Y.getBuffer().remaining();
            int Ub = U.getBuffer().remaining();
            int Vb = V.getBuffer().remaining();

            byte[] data = new byte[Yb + Ub + Vb];


            Y.getBuffer().get(data, 0, Yb);
            U.getBuffer().get(data, Yb, Ub);
            V.getBuffer().get(data, Yb + Ub, Vb);

I tried several different ImageFormats. I'm testing on LG G3, API 21 and the problem occurs.On Nexus 4 I do not have the problem, API 22.


Solution

  • Your observation is correct. API 21 does not properly support Camera2. This has been found by several people independently here on SO, see e.g. Camera2 API21 not working

    So it is reasonable to start using Camera2 not before API22. It is not understandable why documentation hasn't been amended in the meantime.

    Personally I am continuing to perform Camera2 studies, but I am still reluctant to use Camera2 in my app now. I first want to test it on many many devices first and for the near future I don't expect "Camera1" not being supported anymore by new devices.