我收到YUV帧(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),当从CVPixelBufferRef创建CIImage时,我得到:
initWithCVPixelBuffer失败,因为CVPixelBufferRef不是非IOSurface支持的。
CVPixelBufferRef pixelBuffer;
size_t planeWidth[] = { width, width / 2 };
size_t planeHeight[] = { height, height / 2};
size_t planeBytesPerRow[] = { width, width / 2 };
CVReturn ret = CVPixelBufferCreateWithBytes(
kCFAllocatorDefault, width, height, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
data, bytesPerRow, 0, 0, 0, &pixelBuffer
);
if (ret != kCVReturnSuccess)
{
NSLog(@"FAILED");
CVPixelBufferRelease(pixelBuffer);
return;
}
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
// fails
CIImage * image = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer];
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
CVPixelBufferRelease(pixelBuffer);
[image release];
答案 0 :(得分:6)
我会假设问题是:“为什么我会收到此错误?”
要使CVPixelBuffer支持IOSurface,您需要在创建CVPixelBuffer时设置它们的属性。现在你传递“0”作为CVPixelBufferCreateWithBytes中的倒数第二个参数。
在CVPixelBufferCreate中传递带有kCVPixelBufferIOSurfacePropertiesKey键的字典和值为空字典(使用默认IOSurface选项,其他未记录)的字典(因为您不能将kCVPixelBufferIOSurfacePropertiesKey与CVPixelBufferCreateWithBytes一起使用),将正确的字节复制到创建的CVPixelBuffer (不要忘记字节对齐)。这就是你如何使它成为IOSurface支持的。
虽然我不确定它是否会因像素格式而删除所有错误。我的理解是GPU必须能够以像素格式保存纹理才能用作IOSurfaces,尽管我不是100%肯定。
注意:正确复制kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange的像素字节可以在this SO answer中找到。