使用 Vulkan 从 Android Camera2 硬件缓冲区中采样 - 图像格式问题

Using Vulkan to sample from Android Camera2 hardware buffer - Issue with image formats

我目前正在使用 Android ndk 在 C++ 中开发一个应用程序,我需要创建一个采样器来访问相机输出图像。

我使用 AIMAGE_FORMAT_YUV_420_888 完成了此操作,并使用 VkSamplerYcbcrConversion 访问硬件缓冲区中的图像。我在着色器中进行了 yuv -> rgb 转换,在我的 phone.

上看起来一切都很好

后来我发现这在三星 phones 上不起作用,在我的情况下特别是三星 Galaxy S10/S10+。

原因是当我使用 AIMAGE_FORMAT_YUV_420_888 设置图像 reader 时,我使用三星时出现相机错误。在我的 OnePlus 和另一个 phone 上,我尝试了管道完全按预期工作。我创建了一个非常简单的测试设置,甚至尝试在三星 S10 的 ImageReader 中打开具有该图像格式的相机并出现错误,但是当我将 ImageReader 格式更改为 AIMAGE_FORMAT_JPEG 时,错误消失了,相机似乎按预期开始。

AImageReader* SimpleCamera::CreateJpegReader()
{
    AImageReader* reader = nullptr;
   // media_status_t status = AImageReader_new(640, 480, AIMAGE_FORMAT_JPEG,
    //AIMAGE_FORMAT_RGBA_8888
    //media_status_t status = AImageReader_new(640, 480, AIMAGE_FORMAT_RGB_565,4, &reader);
    media_status_t status = AImageReader_newWithUsage(640, 480, 
        //AIMAGE_FORMAT_RGBA_8888,
        //AIMAGE_FORMAT_RGB_565,
        //AIMAGE_FORMAT_RGB_888,
        AIMAGE_FORMAT_JPEG,
        AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
        4, &reader);

    if (status != AMEDIA_OK) {
        LOGE("Couldn't create new image reader");
        return nullptr;
    }

    AImageReader_ImageListener listener{
            .context = nullptr,
            .onImageAvailable = imageCallback1,
    };

    AImageReader_setImageListener(reader, &listener);

    return reader;
}

None除AIMAGE_FORMAT_JPEG外其他格式保证支持,但由于图像布局不同,此格式似乎不适用于VkSamplerYcbcrConversion。

以前有人遇到过这个问题吗?如果是,您是如何解决的?

高层次的目标是:在 C++ 中,将图像从 camera2 api 中取出并放到 VkImage 上。如果有人知道这样做的替代方法,我也洗耳恭听。

尝试使用 ImageFormat.PRIVATE with USAGE_GPU_SAMPLED_IMAGE 标志。这尤其适用于上述三星设备。

请务必阅读 Vulkan specification,因为有很多 android 特定要求和 VkSamplerYcbcrConversion 要求。 我还可以推荐看一下 this great project,它使用 android camera2 api 和 vulkan。