我正在尝试将 Planar YpCbCr 转换为 RGBA,但失败并出现错误 kvImageRoiLargerThanInputBuffer。我尝试了两种不同的方法。这是一些代码片段。注意“thumbnail_buffers + 1”和“thumbnail_buffers + 2”的宽度和高度是“thumbnail_buffers + 0”的一半,因为我正在处理 4:2:0 并且具有 (1/2)*(1/2) 一样多的色度每个样本作为亮度样本。这静默失败(即使我要求解释(kvImagePrintDiagnosticsToConsole)。
error = vImageConvert_YpCbCrToARGB_GenerateConversion(
kvImage_YpCbCrToARGBMatrix_ITU_R_709_2,
&fullrange_8bit_clamped_to_fullrange,
&convertInfo,
kvImage420Yp8_Cb8_Cr8, kvImageARGB8888,
kvImagePrintDiagnosticsToConsole);
uint8_t BGRA8888_permuteMap[4] = {3, 2, 1, 0};
uint8_t alpha = 255;
vImage_Buffer dest;
error = vImageConvert_420Yp8_Cb8_Cr8ToARGB8888(
thumbnail_buffers + 0, thumbnail_buffers + 1, thumbnail_buffers + 2,
&dest,
&convertInfo, BGRA8888_permuteMap, alpha,
kvImagePrintDiagnosticsToConsole //I don't think this flag works here
);
所以我再次尝试使用 vImageConvert_AnyToAny:
vImage_CGImageFormat cg_BGRA8888_format = {
.bitsPerComponent = 8,
.bitsPerPixel = 32,
.colorSpace = baseColorspace,
.bitmapInfo =
kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
.version = 0,
.decode = (CGFloat*)0,
.renderingIntent = kCGRenderingIntentDefault
};
vImageCVImageFormatRef vformat = vImageCVImageFormat_Create(
kCVPixelFormatType_420YpCbCr8Planar,
kvImage_ARGBToYpCbCrMatrix_ITU_R_709_2,
kCVImageBufferChromaLocation_Center,
baseColorspace,
0);
vImageConverterRef icref = vImageConverter_CreateForCVToCGImageFormat(
vformat,
&cg_BGRA8888_format,
(CGFloat[]){0, 0, 0},
kvImagePrintDiagnosticsToConsole,
&error );
vImage_Buffer dest;
error = vImageBuffer_Init( &dest, image_height, image_width, 8, kvImagePrintDiagnosticsToConsole);
error = vImageConvert_AnyToAny( icref, thumbnail_buffers, &dest, (void*)0, kvImagePrintDiagnosticsToConsole); //kvImageGetTempBufferSize
我得到了同样的错误,但这次我将以下消息打印到控制台。
<Error>: kvImagePrintDiagnosticsToConsole: vImageConvert_AnyToAny: srcs[1].height must be >= dests[0].height
但这对我来说没有任何意义。当我有 4:2:0 数据时,我的 Cb 高度怎么可能是 Yp 高度的一半(与我的 dest RGB 高度相同)?(宽度也是如此?)我到底做错了什么?我还将进行其他转换(4:4:4、4:2:2 等),因此我们将不胜感激任何对这些 API 的澄清。此外,我的站点应该用于这些转换吗?上面我使用了 kCVImageBufferChromaLocation_Center。那是对的吗?
一些新信息: 自从发布此信息后,我看到了一个明显的错误,但修复它并没有帮助。请注意,在上面的 vImageConvert_AnyToAny 案例中,我只使用图像宽度而不是 4*width 来初始化目标缓冲区,以便为 RGBA 腾出空间。应该是这个问题吧?没有。
进一步注意,在 vImageConvert_* 案例中,我根本没有初始化目标缓冲区。也解决了这个问题,但没有帮助。
到目前为止,我已经尝试了六种不同的转换方式,从 (vImageConvert_* | vImageConvert_AnyToAny) 中选择一种,从 (kvImage420Yp8_Cb8_Cr8 | kvImage420Yp8_CbCr8 | kvImage444CrYpCb8) 中选择一种,每次都输入适当数量的输入缓冲区——仔细检查缓冲区是否考虑在内每个平面每个像素的样本数。每次我得到:
<Error>: kvImagePrintDiagnosticsToConsole: vImageConvert_AnyToAny: srcs[0].width must be >= dests[0].width
这对我来说毫无意义。如果我的亮度平面是 100 宽,我的 RGBA 缓冲区应该是 400 宽。请从 YCC 到 RGBA 的任何指导或工作代码将不胜感激。