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);