Y420P -> nv12 -> CIImage -> image

1,558 阅读1分钟

静态库libYUV--iOS版,GitHub地址:https://github.com/PangDuTechnology/AFOlibyuv.git


- (void)dispatchAVFrame:(AVFrame*) frame

block:(void (^)(UIImage *image))block{

if(!frame || !frame->data[0]){

return;

}

///--- 420P -> nv12

int numBytes = av_image_get_buffer_size(AV_PIX_FMT_NV12,frame->width,frame->height, 1);

uint8_t *bufferY = (uint8_t *)malloc(numBytes * sizeof(uint8_t));

uint8_t *bufferUV = (uint8_t *)malloc(numBytes / 2 * sizeof(uint8_t));

I420ToNV12(frame->data[0],

frame->linesize[0],

frame->data[1],

frame->linesize[1],

frame->data[2],

frame->linesize[2],

bufferY,

frame->linesize[0],

bufferUV,

frame->linesize[1] + frame->linesize[2],

frame->width,

frame->height

);

///---

NSMutableDictionary *attributes = [AFOMediaYUV dictionary:frame->width height:frame->height lineSize:frame->linesize[0]];

[self pixelBufferPoolRef:attributes];

CVPixelBufferRef pBuffer = [self pixelBufferWidth:frame->width height:frame->height dictionary:attributes];

///---

CVPixelBufferLockBaseAddress(pBuffer, 0);

size_t bytePerRowY = CVPixelBufferGetBytesPerRowOfPlane(pBuffer, 0);

size_t bytesPerRowUV = CVPixelBufferGetBytesPerRowOfPlane(pBuffer, 1);

void *base = CVPixelBufferGetBaseAddressOfPlane(pBuffer, 0);

memcpy(base,bufferY, bytePerRowY * frame->height);

base = CVPixelBufferGetBaseAddressOfPlane(pBuffer, 1);

memcpy(base,bufferUV, bytesPerRowUV * frame->height/2);

CVPixelBufferUnlockBaseAddress(pBuffer, 0);

///---

CIImage *coreImage = [CIImage imageWithCVPixelBuffer:pBuffer];

CIContext *temporaryContext = [CIContext contextWithOptions:nil];

CGImageRef videoImage = [temporaryContext createCGImage:coreImage

fromRect:CGRectMake(0, 0, frame ->width, frame -> height)];

///------ UIImage Conversion

UIImage *image = [[UIImage alloc] initWithCGImage:videoImage scale:1.0 orientation:UIImageOrientationUp];

block(image);

free(bufferY);

free(bufferUV);

bufferY = NULL;

bufferUV = NULL;

base = NULL;

CGImageRelease(videoImage);

}

+ (NSMutableDictionary *)dictionary:(int)width

height:(int)height

lineSize:(int)lineSize{

NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];

[attributes setObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];

[attributes setObject:[NSNumber numberWithInt:width] forKey: (NSString*)kCVPixelBufferWidthKey];

[attributes setObject:[NSNumber numberWithInt:height] forKey: (NSString*)kCVPixelBufferHeightKey];

[attributes setObject:@(lineSize) forKey:(NSString*)kCVPixelBufferBytesPerRowAlignmentKey];

[attributes setObject:[NSDictionary dictionary] forKey:(NSString*)kCVPixelBufferIOSurfacePropertiesKey];

return attributes;

}

- (CVPixelBufferPoolRef)pixelBufferPoolRef:(NSMutableDictionary *)dictionary{

if (!_pixelBufferPool) {

CVPixelBufferPoolCreate(kCFAllocatorDefault,

NULL,

(__bridge CFDictionaryRef)dictionary,

&_pixelBufferPool);

}

return _pixelBufferPool;

}

- (CVPixelBufferRef)pixelBufferWidth:(int)width

height:(int)height

dictionary:(NSMutableDictionary *)dictionary{

if (!_pixelBuffer) {

CVPixelBufferPoolCreatePixelBuffer(NULL,self.pixelBufferPool, &_pixelBuffer);

CVPixelBufferCreate(kCFAllocatorDefault,

width,

height,

kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,

(__bridge CFDictionaryRef)(dictionary),

&_pixelBuffer);

}

return _pixelBuffer;

}