音视频从入门到放弃

如何Copy CVPixelBufferRef

2019-05-06  本文已影响0人  little_ma

在图像的编辑过程中,有可能会遇到需要CVPixelBufferRef需要copy的情况,毕竟CVPixelBufferRef需要手动释放,自己有需要的时候copy一份也是比较安全的,但是Copy后一定不要忘记自己需要手动释放CVPixelBufferRelease(buffer)

对于CVPixelBufferRef的额复制,需要注意两种类型,一种RGB类型:
参考代码:

// RGB/BGR buffer copy
+ (CVPixelBufferRef)RBGBuffereCopyWithPixelBuffer:(CVPixelBufferRef)pixelBuffer
{
    // Get pixel buffer info
    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
    int bufferWidth = (int)CVPixelBufferGetWidth(pixelBuffer);
    int bufferHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
    uint8_t *baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer);
    OSType pixelFormat = inputPixelFormat();
    
    // Copy the pixel buffer
    CVPixelBufferRef pixelBufferCopy = NULL;
    CFDictionaryRef empty = CFDictionaryCreate(kCFAllocatorDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // our empty IOSurface properties dictionary
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             empty, kCVPixelBufferIOSurfacePropertiesKey,
                             nil];
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, bufferWidth, bufferHeight, pixelFormat, (__bridge CFDictionaryRef) options, &pixelBufferCopy);
    if (status == kCVReturnSuccess) {
        CVPixelBufferLockBaseAddress(pixelBufferCopy, 0);
        uint8_t *copyBaseAddress = CVPixelBufferGetBaseAddress(pixelBufferCopy);
        memcpy(copyBaseAddress, baseAddress, bufferHeight * bytesPerRow);
    }else {
        NSLog(@"RBGBuffereCopyWithPixelBuffer :: failed");
    }
    
    CVPixelBufferUnlockBaseAddress(pixelBufferCopy, 0);
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
    
    return pixelBufferCopy;
}

YUV类型:

// YUV buffer copy
+ (CVPixelBufferRef)YUVBufferCopyWithPixelBuffer:(CVPixelBufferRef)pixelBuffer
{
    // Get pixel buffer info
    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
    int bufferWidth = (int)CVPixelBufferGetWidth(pixelBuffer);
    int bufferHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
    OSType pixelFormat = inputPixelFormat();
    
    // Copy the pixel buffer
    CVPixelBufferRef pixelBufferCopy = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, bufferWidth, bufferHeight, pixelFormat, NULL, &pixelBufferCopy);
    if (status != kCVReturnSuccess) {
        NSLog(@"YUVBufferCopyWithPixelBuffer :: failed");
    }
    
    CVPixelBufferLockBaseAddress(pixelBufferCopy, 0);

    uint8_t *yDestPlane = CVPixelBufferGetBaseAddressOfPlane(pixelBufferCopy, 0);
    //YUV
    uint8_t *yPlane = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
    memcpy(yDestPlane, yPlane, bufferWidth * bufferHeight);
    uint8_t *uvDestPlane = CVPixelBufferGetBaseAddressOfPlane(pixelBufferCopy, 1);
    uint8_t *uvPlane = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
    memcpy(uvDestPlane, uvPlane, bufferWidth * bufferHeight/2);
    CVPixelBufferUnlockBaseAddress(pixelBufferCopy, 0);
    
    return pixelBufferCopy;
}
上一篇下一篇

猜你喜欢

热点阅读