0

我收到 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];
4

1 回答 1

7

我假设问题是:“为什么会出现这个错误?”

要支持 CVPixelBuffer IOSurface,您需要在创建 CVPixelBuffer 时设置属性。现在,您将“0”作为 CVPixelBufferCreateWithBytes 中的倒数第二个参数传递。

在 CVPixelBufferCreate(因为您不能将 kCVPixelBufferIOSurfacePropertiesKey 与 CVPixelBufferCreateWithBytes 一起使用)传递一个带有 kCVPixelBufferIOSurfacePropertiesKey 键的字典和一个空字典的值(使用默认 IOSurface 选项,其他未记录),复制正确的字节到创建的 CVPixelBuffer(不要'不要忘记字节对齐)。这就是你如何让它支持 IOSurface。

虽然我不确定它是否会因为像素格式而为您消除所有错误。我的理解是,GPU 必须能够以该像素格式保存纹理才能用作 IOSurface,尽管我不确定 100%。

注意:可以在这个 SO answer中找到正确复制 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange 的像素字节。

于 2012-04-20T15:41:16.350 回答