捕获Camera2预览帧返回空缓冲区 [英] Capturing Camera2 preview frames returns empty buffer

查看:129
本文介绍了捕获Camera2预览帧返回空缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究一个简单的Android应用,该应用旨在将流式摄像机帧从Android Camera2 API管道传递到我的算法中。我已经制作了多个应用程序,这些应用程序使用Android Camera1 API进行了忠实的处理,但是即使经过检查(Google文档,论坛)以确认正确的编码,我仍然无法在onImageAvailable()中从ImageReader捕获任何真实数据。请注意以下相关代码:

I've been working on a simple Android app designed to pass streaming camera frames from the Android Camera2 API pipeline to my algorithm. I've made several applications already that faithfully do this using the Android Camera1 API, but even after checking (Google docs, forums) to confirm correct coding, I am unable to capture any real data from the ImageReader in onImageAvailable(). Please note the following relevant code:


  1. 设置ImageReader:

  1. Setting up the ImageReaders:

private void setUpCameraOutputs(int width, int height) {

[....code....]

mImageReader = ImageReader.newInstance(smallestJPEG.getWidth(), 
                                       smallestJPEG.getHeight(),
                                       ImageFormat.JPEG, /*maxImages*/2);
// mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
mPreviewImageReader = ImageReader.newInstance(smallest.getWidth(), 
                                              smallest.getHeight(), 
                                              ImageFormat.YUV_420_888, 2);
mPreviewImageReader.setOnImageAvailableListener(mOnPreviewImageAvailableListener,
                                                mBackgroundHandler);

[....code....]

}







  1. 设置CaptureSession:

  1. Setting up the CaptureSession:

private void createCameraPreviewSession() {
try {
    //Create Texture from Screen's TextureView
    SurfaceTexture texture = mTextureView.getSurfaceTexture();

    assert texture != null;

    //Configure Default Buffer Size
    texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

    //Create Output Surface from Texture
    Surface surface = new Surface(texture);

    // Set up a CaptureRequest.Builder with the output Surface.
    mPreviewRequestBuilder
            = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

    //Add Output Display surface
    mPreviewRequestBuilder.addTarget(surface);

    //Add Preview frame-grabbing surface 
    mPreviewRequestBuilder.addTarget(mPreviewImageReader.getSurface());

    mCameraDevice.createCaptureSession(Arrays.asList(surface, mPreviewImageReader.getSurface()),
            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. [...code...]
                        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                        // Flash is automatically enabled when necessary.
                        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

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

                @Override
                public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
                    [...code...]
                }
            }, null
    );
} catch (CameraAccessException e) {
    [...code...]
}
}







  1. 设置OnImageAvailableListener:

  1. Setting up the OnImageAvailableListener:

private ImageReader mPreviewImageReader;
private final ImageReader.OnImageAvailableListener mOnPreviewImageAvailableListener
= new ImageReader.OnImageAvailableListener() {

@Override
public void onImageAvailable(ImageReader reader) {

    //Acquire Image, ByteBuffer, then byte array
    Image image = reader.acquireLatestImage();
    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    byte[] bytes = new byte[buffer.remaining()];

    //Check bytes array for anydata
    int cnt = 0;
    for (int i = 0; i < bytes.length; i++){
        if (bytes[i] != 0)cnt++;
    }
    Log.i(TAG, "cnt = " + cnt);
    image.close();

    //At this point, byte[] bytes is empty (all zero)
    [...code...]
}

};


在代码段#3,无论ImageReader格式如何,我的字节缓冲区始终返回空(全零)。有人遇到过这个问题吗?我是否缺少任何代码?

In code snippet #3, my byte buffer always returns empty (all zeros), regardless of ImageReader format. Has anyone had this issue? Am I missing any code?

推荐答案

之后添加 buffer.get(bytes); byte [] bytes = new byte [buffer.remaining()];

add buffer.get(bytes); after byte[] bytes = new byte[buffer.remaining()];

这篇关于捕获Camera2预览帧返回空缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆