ios - 在 iOS 上显示 CVImageBufferRef 的最有效方法是什么

标签 ios opengl-es core-graphics avfoundation video-toolbox

我有 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 session 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,因为解压缩的输入是可用的。

最佳答案

更新:下面的原始答案无效,因为 kCVPixelBufferIOSurfaceCoreAnimationCompatibilityKey 不适用于 iOS。


UIViewCALayer 支持,其 contents 属性支持多种类型的图像。详见my answer对于 macOS 的类似问题,可以使用 CALayer 来呈现 CVPixelBuffer 的支持 IOSurface。 (注意:我只在 macOS 上测试过。)

关于ios - 在 iOS 上显示 CVImageBufferRef 的最有效方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32850012/

相关文章:

iphone - 优化 iPhone OpenGL ES 填充率

uikit - 核心图形和 UIKit 交互

iphone - 希望在 iPhone Storyboard应用程序中最大限度地重用

iphone - UILabel 改变位置

android - GLSL 2D 旋转不起作用

javascript - webGL 中的短纹理

ios - 如何使用 ACEDrawingView 添加清除按钮

ios - 使用 UIBezierPath 和 CoreGraphics 自由手绘和删除

ios - 如何在快速多部分请求中了解上传进度

ios - 找到匹配项后,如何停止RxSwift ble扫描仪?