android - 我如何区分 imageReader 相机 API 2 中的 NV21 和 YV12 编码?

标签 android android-camera2 yuv

我正在开发自定义相机 API 2 应用程序,我注意到当我使用 ImageReader 回调时,捕获格式转换在某些设备上是不同的。

例如,在 Nexus 4 中无法正常工作,而在 Nexus5X 中看起来正常,这是输出。

enter image description here

我以这种形式初始化 ImageReader:

mImageReader = ImageReader.newInstance(320, 240, ImageFormat.YUV_420_888,2); 

我的回调是简单的回调 ImageReader 回调。

 mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {

    @Override
    public void onImageAvailable( ImageReader reader) {

       try {
             mBackgroundHandler.post(
                 new ImageController(reader.acquireNextImage())
             );
        }
        catch(Exception e)
        {
          //exception
        }
        }

};

对于 Nexus 4:我遇到了这个错误。

D/qdgralloc: gralloc_lock_ycbcr: Invalid format passed: 0x32315659

当我尝试在两个设备中写入原始文件时,我得到了这些不同的图像。所以我了解到 Nexus 5X 图像具有 NV21 编码,而 Nexus 4 具有 YV12 编码。 enter image description here

我找到了 image format 的规范我尝试在 ImageReader 中获取格式。 有 YV12 和 NV21 选项,但显然,当我尝试获取格式时,我得到的是 YUV_420_888 格式。

 int test=mImageReader.getImageFormat();

那么有什么方法可以获取相机输入格式(NV21 或 YV12)来区分相机类中的这种编码类型?也许是 CameraCharacteristics?

提前致谢。

乌奈。 PD:我使用 OpenGL 显示 RGB 图像,并使用 Opencv 转换为 YUV_420_888。

最佳答案

YUV_420_888 是一个包装器,可以托管(以及其他)NV21 和 YV12 图像。您必须使用平面和步幅来访问各个颜色:

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

如果底层像素采用 NV21 格式(如 Nexus 4),则 pixelStride 将为 2,并且

int getU(image, col, row) {
    return getPixel(image.getPlanes()[1], col/2, row/2);
}

int getPixel(plane, col, row) {
    return plane.getBuffer().get(col*plane.getPixelStride() + row*plane.getRowStride());
}

我们采用半列半行,因为这是 U 和 V(色度)平面在 420 图像中的存储方式。

此代码仅供说明,效率很低,您可能想使用 get(byte[], int, int) 批量访问像素,或通过 fragment 着色器,或通过 native 代码中的 JNI 函数 GetDirectBufferAddress。您不能使用的是方法 plane.array(),因为这些平面保证是直接字节缓冲区。

关于android - 我如何区分 imageReader 相机 API 2 中的 NV21 和 YV12 编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40676704/

相关文章:

php - 在 PhoneGap 应用程序上显示 SQL 数据 - 可以使用 URL 吗?

java - 显示方法不正常

java - php 服务器端和 java (Android) 客户端之间的 RSA。

安卓相机2 : the most optimal and fast way to change the output surface set on-the-fly

android - 为什么我在 CameraDevice.StateCallback 的 onError 方法中得到 ERROR_CAMERA_DEVICE

linux - 如何使用 mplayer 查看原始 yuv 文件?

javascript - Angular.JS 未捕获类型错误 : Cannot assign to read only property

java - 无法解析符号 'FragmentCompat' - Camera2VideoJava - 目标为 API 29

c++ - YUV 图像中的像素

android - Android 版 OpenCV : Convert Camera preview from YUV to RGB with Imgproc. cvtColor