背景
在iOS里,我们经常能看到 CVPixelBufferRef 这个类型,在Camera 采集返回的数据里得到一个CMSampleBufferRef,而每个CMSampleBufferRef里则包含一个 CVPixelBufferRef,在视频硬解码的返回数据里也是一个 CVPixelBufferRef(里面包好了所有的压缩的图片信息)。
一、CVPixelBufferRef类型
由于可以有不同的PixelFormatType,说明他可以支持多种位图格式,除了常见的 RGB32以外,还可以支持比如 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,这种YUV多平面的数据格式,这个类型里 BiPlanar 表示双平面,说明它是一个 NV12的YUV,包含一个Y平面和一个UV平面。通过CVPixelBufferGetBaseAddressOfPlane可以得到每个平面的数据指针。在得到 Address之前需要调用CVPixelBufferLockBaseAddress,这说明CVPixelBufferRef的内部存储不仅是内存也可能是其它外部存储,比如现存,所以在访问前要lock下来实现地址映射,同时lock也保证了没有读写冲突。
由于是C对象,它是不受 ARC 管理的,所以需要自己手动的进行释放:可以CVPixelBufferRetain,CVPixelBufferRelease函数用来加减引用计数,其实和CFRetain和CFRelease是等效的,所以可以用 CFGetRetainCount来查看当前引用计数。
二、CVPixelBufferRef使用Core Graphics进行渲染
+(UIImage*)uiImageFromPixelBuffer:(CVPixelBufferRef)p {
CIImage* ciImage = [CIImage imageWithCVPixelBuffer : p];
CIContext* context = [CIContext contextWithOptions : @{kCIContextUseSoftwareRenderer : @(YES)
}];
CGRect rect = CGRectMake(0, 0, CVPixelBufferGetWidth(p), CVPixelBufferGetHeight(p));
CGImageRef videoImage = [context createCGImage : ciImage fromRect : rect];
UIImage* image = [UIImage imageWithCGImage : videoImage];
CGImageRelease(videoImage);
return image;
}
参考:https://blog.csdn.net/fanyun_01/article/details/115338407
网友评论