从CMSampleBufferRef中取出NV12数据,转换为i420,对i420数据做镜像,然后把镜像的i420转换为NV12,再把NV12包装成CVPixelBufferRef。
+ (CVPixelBufferRef)mirrorSampleBuffler:(CMSampleBufferRef)sampleBufRef {
//CVPixelBufferRef是CVImageBufferRef的别名,两者操作几乎一致。
//获取CMSampleBuffer的图像地址
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBufRef);
if (!pixelBuffer) {
return nil;
}
//表示开始操作数据
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
//图像宽度(像素)
size_t buffer_width = CVPixelBufferGetWidth(pixelBuffer);
//图像高度(像素)
size_t buffer_height = CVPixelBufferGetHeight(pixelBuffer);
//获取CVImageBufferRef中的y数据
uint8_t *src_y_frame = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
//获取CMVImageBufferRef中的uv数据
uint8_t *src_uv_frame =(unsigned char *) CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
//y stride
size_t plane1_stride = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0);
//uv stride
size_t plane2_stride = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1);
//y height
size_t plane1_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
//uv height
size_t plane2_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
//y_size
size_t plane1_size = plane1_stride * plane1_height;
//uv_size
size_t plane2_size = plane2_stride * plane2_height;
//yuv_size(内存空间)
size_t frame_size = plane1_size + plane2_size;
// 1.NV12转换为I420
// 开辟buffer_frame大小的内存空间用于存放转换好的i420数据
uint8* buffer_y = (unsigned char *)malloc(frame_size);
uint8* buffer_u = buffer_y + plane1_size;
uint8* buffer_v = buffer_u + plane1_size / 4;
libyuv::NV12ToI420(/*const uint8 *src_y*/ src_y_frame,
/*int src_stride_y*/ (int)plane1_stride,
/*const uint8 *src_uv*/ src_uv_frame,
/*int src_stride_uv*/ (int)plane2_stride,
/*uint8 *dst_y*/ buffer_y,
/*int dst_stride_y*/ (int)plane1_stride,
/*uint8 *dst_u*/ buffer_u,
/*int dst_stride_u*/ (int)plane1_stride >> 1,
/*uint8 *dst_v*/ buffer_v,
/*int dst_stride_v*/ (int)plane1_stride >> 1,
/*int width*/ (int)buffer_width,
/*int height*/ (int)buffer_height);
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
uint8* mirror_y = (unsigned char *)malloc(frame_size);
uint8* mirror_u = mirror_y + plane1_size;
uint8* mirror_v = mirror_u + plane1_size / 4;
libyuv::I420Mirror(/*const uint8* src_y*/buffer_y,
/*int src_stride_y*/(int)plane1_stride,
/*const uint8* src_u*/buffer_u,
/*int src_stride_u*/(int)plane1_stride >> 1,
/*const uint8* src_v*/buffer_v,
/*int src_stride_v*/(int)plane1_stride >> 1,
/*uint8* dst_y*/mirror_y,
/*int dst_stride_y*/(int)plane1_stride,
/*uint8* dst_u*/mirror_u,
/*int dst_stride_u*/(int)plane1_stride >> 1,
/*uint8* dst_v*/mirror_v,
/*int dst_stride_v*/(int)plane1_stride >> 1,
/*int width*/(int)buffer_width,
/*int height*/(int)buffer_height);
free(buffer_y);
uint8 *nv12_y = (uint8 *)malloc(frame_size);
uint8* nv12_uv = nv12_y + plane1_stride * plane1_height;
libyuv::I420ToNV12(/*const uint8 *src_y*/ mirror_y,
/*int src_stride_y*/ (int)plane1_stride,
/*const uint8 *src_u*/ mirror_u,
/*int src_stride_u*/ (int)plane1_stride >> 1,
/*const uint8 *src_v*/ mirror_v,
/*int src_stride_v*/ (int)plane1_stride >> 1,
/*uint8 *dst_y*/ nv12_y,
/*int dst_stride_y*/ (int)plane1_stride,
/*uint8 *dst_uv*/ nv12_uv,
/*int dst_stride_uv*/ (int)plane1_stride,
/*int width*/ (int)buffer_width,
/*int height*/ (int)buffer_height);
free(mirror_y);
// 4.NV12转换为CVPixelBufferRef
NSDictionary *pixelAttributes = @{(id)kCVPixelBufferIOSurfacePropertiesKey : @{}};
CVPixelBufferRef dstPixelBuffer = NULL;
CVReturn result = CVPixelBufferCreate(kCFAllocatorDefault,
buffer_width, buffer_height, kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
(__bridge CFDictionaryRef)pixelAttributes, &dstPixelBuffer);
CVPixelBufferLockBaseAddress(dstPixelBuffer, 0);
uint8_t *yDstPlane = (uint8*)CVPixelBufferGetBaseAddressOfPlane(dstPixelBuffer, 0);
memcpy(yDstPlane, nv12_y, plane1_size);
uint8_t *uvDstPlane = (uint8*)CVPixelBufferGetBaseAddressOfPlane(dstPixelBuffer, 1);
memcpy(uvDstPlane, nv12_uv, plane2_size);
if (result != kCVReturnSuccess) {
NSLog(@"Unable to create cvpixelbuffer %d", result);
}
CVPixelBufferUnlockBaseAddress(dstPixelBuffer, 0);
free(nv12_y);
return dstPixelBuffer;
}
网友评论