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

use*_*268 8 opengl-es core-graphics avfoundation ios 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 ...
Run Code Online (Sandbox Code Playgroud)

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

Apple的iOS SampleCode GLCameraRipple显示了一个显示YUV CVPixelBufferRef的示例,它使用2个OpenGLES显示YUV和UV组件的单独纹理,以及使用GPU执行YUV到RGB色彩空间转换计算的片段着色器程序 - 这是真正需要的,或者是如何做到这一点有一些更简单的方法?

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

Sab*_*Ali 0

如果您从 中获取CVImageBufferReffrom CMSampleBufferRef,则captureOutput:didOutputSampleBuffer:fromConnection:无需进行该转换,并且可以直接从 中获取 imageData CMSampleBufferRef。这是代码:

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:sampleBuffer];
UIImage *frameImage = [UIImage imageWithData:imageData];
Run Code Online (Sandbox Code Playgroud)

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

  • 谢谢,但是帧是在其他地方捕获的,编码的 H.264 NALU 与其他应用程序数据一起通过网络传输。因此,通过网络接收这些编码帧的应用程序首先需要解码其 CMBlockBuffers 中包含 H.264 的 CMSampleBuffers,以访问解码的帧和像素数据,然后需要显示这些解码的视频帧。现在我正在寻找最有效的方法(CPU 和 GPU 内存之间的内存复制更少,最佳的电池和整体计算效率......) (4认同)