我无法通过vImage加速框架将420Yp8_Cb8_Cr8平面转换为ARGB8888

如何解决我无法通过vImage加速框架将420Yp8_Cb8_Cr8平面转换为ARGB8888

我正在尝试将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,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},kvImagePrintDiagnosticsToConsole,&error );


vImage_Buffer dest;
error = vImageBuffer_Init( &dest,image_height,image_width,8,kvImagePrintDiagnosticsToConsole);
error = vImageConvert_AnyToAny( icref,thumbnail_buffers,(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的任何指导或工作代码,将不胜感激。

解决方法

好吧,我知道了-部分用户错误,部分Apple错误。我在想vImage_Buffer的宽度和高度错误。例如,我将输出缓冲区I指定为4 * image_width,每个像素8位,而本来应该只是image_width和每个像素32位-相同的内存量,但向API发送了错误的消息。我猜那行上的文字“ 8”使我无法记住那个插槽是什么。我一定已经学过很多课了-给你的魔术数字命名。

无论如何,现在是错误部分。使输入和输出缓冲区在宽度,高度,像素深度方面正确无误,将所有调用固定为低级vImageConvert_420Yp8_Cb8_Cr8ToARGB8888和朋友。例如,在平面YCC情况下,您的Cb和Cr缓冲区自然会具有Yp平面的一半宽度和一半高度。但是,在vImageConvert_AnyToAny情况下,这些缓冲区导致调用失败并保释-说一些愚蠢的事情,例如,我需要Cb平面具有与Yp平面相同的尺寸,即使是4:2:0。这似乎是Apple在调用完成该工作的较低级代码之前进行的一些预检中的错误。

我通过简单地制作太大的输入缓冲区并仅在左上象限填充Cb和Cr数据来解决vImageConvert_AnyToAny错误。在转换期间在那里找到数据就好了。我使用vImageBuffer_Init()制作了这些太大的缓冲区,其中Apple分配了太大的malloc浪费了。我没有尝试手工制作vImage_Buffer -只是大小和分配我需要的内存。这可能行得通,或者也许苹果会相信宽度和高度而爬入杂草。如果您手工制作一个,则最好说出关于rowBytes的真相。

在将其标记为正确之前,我将稍等一下,希望苹果公司的人能够看到并解决该错误,并可能会得到启发,以改善我们those绊绊的文档。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?