使用 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。
我目前正在使用 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。