首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我无法让vImage (加速框架)将420Yp8_Cb8_Cr8 (平面)转换为ARGB8888

我无法让vImage (加速框架)将420Yp8_Cb8_Cr8 (平面)转换为ARGB8888
EN

Stack Overflow用户
提问于 2020-10-12 19:35:53
回答 1查看 561关注 0票数 1

我正在尝试将Planar YpCbCr转换为RGBA,但是它在错误kvImageRoiLargerThanInputBuffer方面失败了。我尝试了两种不同的方法。这是一些代码片段。注意'thumbnail_buffers + 1‘和'thumbnail_buffers + 2’的宽度和高度是'thumbnail_buffers + 0‘的一半,因为我处理的是4:2:0,并且(1/2)*(1/2)每个颜色样本的数量都是luma样本。尽管我要求一个解释(kvImagePrintDiagnosticsToConsole),但这还是失败了。

代码语言:javascript
复制
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:

代码语言:javascript
复制
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

我也得到了同样的错误,但是这次我得到了输出到控制台的以下消息。

代码语言:javascript
复制
<Error>: kvImagePrintDiagnosticsToConsole: vImageConvert_AnyToAny: srcs[1].height must be >= dests[0].height

但这对我来说没有任何意义。当我有4:2:0的数据时,我的Cb高度怎么能比我的Yp高(和我的最RGB的身高一样)更高呢?(宽度也一样?)我到底做错了什么?我还将进行其他转换(4:4:4,4:2:2,等等),因此非常希望对这些API进行任何澄清。此外,对于这些转换,我的位置应该是什么?上面我使用kCVImageBufferChromaLocation_Center。对吗?

一些新的信息:发布后,我看到了一个明显的错误,但修复它没有帮助。注意,在上面的vImageConvert_AnyToAny中,我只使用图像宽度而不是4*宽度初始化了目标缓冲区,以便为RGBA腾出空间。那一定是问题所在,对吧?不是的。

进一步注意,在vImageConvert_*的情况下,我根本没有初始化目标缓冲区。把这个也修好了,也没什么用。

到目前为止,我已经尝试了六种不同的转换方式--选择一种从(vImageConvert_* \ vImageConvert_AnyToAny)中选择一种,从其中选择一种--每次提供适当数量的输入缓冲区--仔细检查缓冲区是否考虑到每个平面上每个像素的样本数。每次我得到:

代码语言:javascript
复制
<Error>: kvImagePrintDiagnosticsToConsole: vImageConvert_AnyToAny: srcs[0].width must be >= dests[0].width

这对我来说毫无意义。如果我的luma飞机是100宽,我的RGBA缓冲区应该是400宽。请提供从YCC到RGBA的任何指导或工作代码将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-13 04:42:51

好吧,我想出来了--部分是用户错误,一部分是苹果的错误。我在想vImage_Buffer的宽度和高度是错误的。例如,我指定为4 * image_width的输出缓冲区,以及每像素8位,而它应该只是image_width和每像素32位--内存数量相同,但给API发送了错误的信息。我想,这一行上的文字'8‘使我无法记住那个插槽是什么。我一定学过很多次了--说出你的神奇数字吧。

不管怎么说,现在是窃听器部分。使输入和输出缓冲区正确的宽度,高度,像素深度固定所有对低级别vImageConvert_420Yp8_Cb8_Cr8ToARGB8888和朋友的调用。例如,在平面YCC情况下,您的Cb和Cr缓冲器的宽度和高度自然只有Yp平面的一半。然而,在vImageConvert_AnyToAny的情况下,这些缓冲区导致呼叫失败,说一些愚蠢的事情,比如我需要我的Cb平面具有与我的Yp平面相同的维度,即使是4:2:0。这似乎是苹果在调用底层代码之前所做的一些预谋中的一个缺陷。

我通过简单地制作太大的输入缓冲区,并且只在左上象限中填充Cb和Cr数据来解决vImageConvert_AnyToAny错误。这些数据是在转换过程中发现的。我用vImageBuffer_Init()做了这些太大的缓冲,苹果在这里分配了浪费的太大的malloc。我并没有试着手工制作vImage_Buffer--按我所需的大小和内存分配。这可能会奏效,或者苹果会爬到杂草里,相信它的宽度和高度。如果你手工制作rowBytes,你最好说出关于rowBytes的真相。

我要先给这个答案留一段时间,然后再给它打上记号,希望苹果公司的人能看到这个问题,修复这个错误,或许还会得到灵感,来改进我们这些蹒跚而行的人的文档。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64324316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档