9

我有 CMSampleBufferRef(s),我使用 VTDecompressionSessionDecodeFrame 解码,这会在帧解码完成后产生 CVImageBufferRef,所以我的问题是..

在 UIView 中显示这些 CVImageBufferRefs 的最有效方法是什么?

我已成功将 CVImageBufferRef 转换为 CGImageRef 并通过将 CGImageRef 设置为 CALayer 的内容来显示它们,但随后 DecompressionSession 已配置为 @{ (id)kCVPixelBufferPixelFormatTypeKey: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] };

这是我如何将 CVImageBufferRef 转换为 CGImageRef 的示例/代码(注意:cvpixelbuffer 数据必须采用 32BGRA 格式才能正常工作)

    CVPixelBufferLockBaseAddress(cvImageBuffer,0);
    // get image properties 
    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(cvImageBuffer);
    size_t bytesPerRow   = CVPixelBufferGetBytesPerRow(cvImageBuffer);
    size_t width         = CVPixelBufferGetWidth(cvImageBuffer);
    size_t height        = CVPixelBufferGetHeight(cvImageBuffer);

    /*Create a CGImageRef from the CVImageBufferRef*/
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef    cgContext  = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    CGImageRef cgImage = CGBitmapContextCreateImage(cgContext);

    // release context and colorspace 
    CGContextRelease(cgContext);
    CGColorSpaceRelease(colorSpace);

    // now CGImageRef can be displayed either by setting CALayer content
    // or by creating a [UIImage withCGImage:geImage] that can be displayed on
    // UIImageView ...

#WWDC14 会话 513 ( https://developer.apple.com/videos/wwdc/2014/#513 ) 暗示可以避免 YUV -> RGB 颜色空间转换(使用 CPU?),并且如果使用支持 YUV 的 GLES 魔法 -想知道这可能是什么以及如何实现?

Apple 的 iOS SampleCode GLCameraRipple 显示了一个示例,该示例显示使用 2 个 OpenGLES 从相机捕获的 YUV CVPixelBufferRef,Y 和 UV 组件具有单独的纹理,以及使用 GPU 执行 YUV 到 RGB 颜色空间转换计算的片段着色器程序 - 是真正需要的,或者是有一些更直接的方法可以做到这一点吗?

注意:在我的用例中,我无法使用 AVSampleBufferDisplayLayer,因为事实上解压缩的输入是可用的。

4

2 回答 2

1

更新:下面的原始答案不起作用,因为kCVPixelBufferIOSurfaceCoreAnimationCompatibilityKeyiOS 不可用。


UIView由其属性支持多种类型的图像支持CALayercontents正如我对 macOS 的类似问题的回答中所详述的那样,可以使用CALayer来渲染 aCVPixelBuffer的 backing IOSurface。(警告:我只在 macOS 上测试过。)

于 2019-01-22T03:39:22.850 回答
0

如果您从 from 获取您的CVImageBufferReffrom CMSampleBufferRefcaptureOutput:didOutputSampleBuffer:fromConnection:您不需要进行该转换,并且可以直接将 imageData 从CMSampleBufferRef. 这是代码:

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:sampleBuffer];
UIImage *frameImage = [UIImage imageWithData:imageData];

API 描述不提供有关其 32BGRA 是否支持的任何信息,并以jpeg未应用任何压缩的格式生成 imageData 以及任何元数据。如果您的目标是在屏幕上显示图像或使用UIImageView,这是快捷方式。

于 2015-10-02T20:10:25.280 回答