OC CVPixelBuffer不同圖像格式間轉換

1.YUV轉RGB,調用libYUV

- (BOOL)NV12ToRgbaPixelBuffer:(CVPixelBufferRef)pixelBufferNV12 pixelBufferRGBA:(CVPixelBufferRef)pixelBufferRGBA
{
    CVPixelBufferLockBaseAddress(pixelBufferNV12, 0);
    unsigned char* y = (unsigned char*)CVPixelBufferGetBaseAddressOfPlane(pixelBufferNV12,0);
    unsigned char* uv = (unsigned char*)CVPixelBufferGetBaseAddressOfPlane(pixelBufferNV12,1);
    CVPixelBufferLockBaseAddress(pixelBufferRGBA, 0);
    uint8_t* data = (uint8_t*)CVPixelBufferGetBaseAddress(pixelBufferRGBA);
    
    int32_t width  = (int32_t)CVPixelBufferGetWidth(pixelBufferNV12);
    int32_t height = (int32_t)CVPixelBufferGetHeight(pixelBufferNV12);
    
    size_t bgraStride = CVPixelBufferGetBytesPerRowOfPlane(pixelBufferRGBA,0);
    size_t y_stride = CVPixelBufferGetBytesPerRowOfPlane(pixelBufferNV12,0);
    size_t uv_stride  = CVPixelBufferGetBytesPerRowOfPlane(pixelBufferNV12, 1);
    libyuv::NV12ToARGB(y,
                       int(y_stride),
                       uv,
                       int(uv_stride),
                       data,
                       int(bgraStride),
                       width,
                       height);
    
    CVPixelBufferUnlockBaseAddress(pixelBufferRGBA, 0);
    CVPixelBufferUnlockBaseAddress(pixelBufferNV12, 0);
    return true;
}

2.RGB轉YUV

- (BOOL)RgbaToNV12PixelBuffer:(CVPixelBufferRef)pixelBufferRGBA pixelBufferYUV:(CVPixelBufferRef)pixelBufferNV12
{
    CVPixelBufferLockBaseAddress(pixelBufferNV12, 0);
    unsigned char* y = (unsigned char*)CVPixelBufferGetBaseAddressOfPlane(pixelBufferNV12,0);
    unsigned char* u = (unsigned char*)CVPixelBufferGetBaseAddressOfPlane(pixelBufferNV12,1);
    CVPixelBufferLockBaseAddress(pixelBufferRGBA, 0);
    uint8_t* data = (uint8_t*)CVPixelBufferGetBaseAddress(pixelBufferRGBA);
    
    int32_t width  = (int32_t)CVPixelBufferGetWidth(pixelBufferNV12);
    int32_t height = (int32_t)CVPixelBufferGetHeight(pixelBufferNV12);
    unsigned char* v = u + width*height/4;
    
    size_t bgraStride = CVPixelBufferGetBytesPerRowOfPlane(pixelBufferRGBA,0);
//    size_t y_stride = CVPixelBufferGetBytesPerRowOfPlane(pixelBufferNV12,0);
//    size_t uv_stride  = CVPixelBufferGetBytesPerRowOfPlane(pixelBufferNV12, 1);
    libyuv::ARGBToI420(data,
               (int)bgraStride,
               y,
               width,
               u,
               width/2,
               v,
               width/2,
               width,
               height);
    
    CVPixelBufferUnlockBaseAddress(pixelBufferRGBA, 0);
    CVPixelBufferUnlockBaseAddress(pixelBufferNV12, 0);
    return true;
}

3.YUV保存本地

-(BOOL) savePixelBufferYUV:(CVPixelBufferRef)CVPixelBufferYUV
{
    int32_t width  = (int32_t)CVPixelBufferGetWidth(CVPixelBufferYUV);
    int32_t height = (int32_t)CVPixelBufferGetHeight(CVPixelBufferYUV);
    
    CVPixelBufferLockBaseAddress(CVPixelBufferYUV, 0);
    unsigned char* y = (unsigned char*)CVPixelBufferGetBaseAddressOfPlane(CVPixelBufferYUV,0);
    unsigned char* uv = (unsigned char*)CVPixelBufferGetBaseAddressOfPlane(CVPixelBufferYUV,1);
    FILE *VTcaptureFile = NULL;
    if (!VTcaptureFile)
    {
        NSString *path_document = NSHomeDirectory();
        NSString *imagePath = [path_document stringByAppendingFormat:@"%@",@"/Documents/previewYUV.yuv"];
        //   VTcaptureFile = fopen(captureTestName, "aw");
        const char * captureTestName = [imagePath UTF8String];
        VTcaptureFile = fopen(captureTestName, "aw");
        if (!VTcaptureFile)
        {
            NSLog(@"fopen file  error!! \n");
            return NO ;
        }
        fwrite(y, 1, width*height, VTcaptureFile);
        fflush(VTcaptureFile);
        fwrite(uv, 1, width*height/2, VTcaptureFile);
        fflush(VTcaptureFile);
    }
    CVPixelBufferUnlockBaseAddress(CVPixelBufferYUV, 0);
    return YES;
}

4.Creat YUV PixelBuffer

    CVPixelBufferRef _pixelBufferYUV = NULL;
    const void *keys[] = {
        kCVPixelBufferOpenGLCompatibilityKey,
        kCVPixelBufferIOSurfacePropertiesKey,
    };
    const void *values[] = {
        (__bridge const void *)([NSNumber numberWithBool:YES]),
        (__bridge const void *)([NSDictionary dictionary])
    };

    OSType bufferPixelFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;

    CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 2, NULL, NULL);
    CVReturn err __unused = CVPixelBufferCreate(kCFAllocatorDefault,
                                       encodedWidth,
                                       encodedHeight,
                                       bufferPixelFormat,
                                       optionsDictionary,
                                       &_pixelBufferYUV);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章