在iOS 7+上最快的方式从BGRA字节获取CVPixelBufferRef

时间:2015-01-23 03:01:28

标签: ios video textures

iOS 7+上将BGRA / UIImage数据的原始字节转换为CVPixelBufferRef的最快方法是什么? BGRA顺序中每个像素的字节数为4个字节。

有没有机会直接投射,而不是将数据复制到二级存储中?

我考虑过CVPixelBufferCreateWithBytes,但我有预感它正在复制记忆......

1 个答案:

答案 0 :(得分:4)

您必须使用CVPixelBufferCreate因为CVPixelBufferCreateWithBytes不允许使用Core Video纹理缓存快速转换为OpenGL纹理。我不确定为什么会出现这种情况,但至少就像iOS 8那样。我用探查器测试了这个,CVPixelBufferCreateWithBytes导致每次核心视频纹理都要进行texSubImage2D调用从缓存中访问。

如果宽度不是16的倍数,

CVPixelBufferCreate会做有趣的事情,所以如果你打算在CVPixelBufferGetBaseAddress上进行CPU操作,你希望它像{{1}那样布局或者CGImage,您需要将宽度填充到16的倍数,或者确保使用CVPixelBufferGetRowBytes并将其传递给您创建的任何CGBitmapContext

我测试了宽度和高度尺寸从16到2048的所有组合,只要它们被填充到16的下一个最高倍数,就会正确布局。

CGBitmapContext

有趣的是,如果您要求Core Video缓存中的纹理尺寸小于填充尺寸,它将立即返回纹理。不知何故,它下面能够引用原始纹理,但宽度和高度较小。

总而言之,您无法使用+ (NSInteger) alignmentForPixelBufferDimension:(NSInteger)dim { static const NSInteger modValue = 16; NSInteger mod = dim % modValue; return (mod == 0 ? dim : (dim + (modValue - mod))); } + (NSDictionary*) pixelBufferSurfaceAttributesOfSize:(CGSize)size { return @{ (NSString*)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA), (NSString*)kCVPixelBufferWidthKey: @(size.width), (NSString*)kCVPixelBufferHeightKey: @(size.height), (NSString*)kCVPixelBufferBytesPerRowAlignmentKey: @(size.width * 4), (NSString*)kCVPixelBufferExtendedPixelsLeftKey: @(0), (NSString*)kCVPixelBufferExtendedPixelsRightKey: @(0), (NSString*)kCVPixelBufferExtendedPixelsTopKey: @(0), (NSString*)kCVPixelBufferExtendedPixelsBottomKey: @(0), (NSString*)kCVPixelBufferPlaneAlignmentKey: @(0), (NSString*)kCVPixelBufferCGImageCompatibilityKey: @(YES), (NSString*)kCVPixelBufferCGBitmapContextCompatibilityKey: @(YES), (NSString*)kCVPixelBufferOpenGLESCompatibilityKey: @(YES), (NSString*)kCVPixelBufferIOSurfacePropertiesKey: @{ @"IOSurfaceCGBitmapContextCompatibility": @(YES), @"IOSurfaceOpenGLESFBOCompatibility": @(YES), @"IOSurfaceOpenGLESTextureCompatibility": @(YES) } }; } 使用CVPixelBufferRef包装现有内存并有效使用Core Video纹理缓存。您必须使用CVPixelBufferCreateWithBytes并使用CVPixelBufferCreate