Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save b9AobJ/b9b65c1386ec32c9c1d6796e0bec36a4 to your computer and use it in GitHub Desktop.
Save b9AobJ/b9b65c1386ec32c9c1d6796e0bec36a4 to your computer and use it in GitHub Desktop.
Convert an AVFrame to CVPixelbuffer
-(void)getPixelBuffer:(CVPixelBufferRef *)pbuf {
@synchronized (self) {
if(!_pFrame || !_pFrame->data[0])
return;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
// [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
// [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
@(_pFrame->linesize[0]), kCVPixelBufferBytesPerRowAlignmentKey,
[NSNumber numberWithBool:YES], kCVPixelBufferOpenGLESCompatibilityKey,
[NSDictionary dictionary], kCVPixelBufferIOSurfacePropertiesKey,
nil];
if (_pFrame->linesize[1] != _pFrame->linesize[2]) {
return;
}
size_t srcPlaneSize = _pFrame->linesize[1]*_pFrame->height/2;
size_t dstPlaneSize = srcPlaneSize *2;
uint8_t *dstPlane = malloc(dstPlaneSize);
// interleave Cb and Cr plane
for(size_t i = 0; i<srcPlaneSize; i++){
dstPlane[2*i ]=_pFrame->data[1][i];
dstPlane[2*i+1]=_pFrame->data[2][i];
}
int ret = CVPixelBufferCreate(kCFAllocatorDefault,
_pFrame->width,
_pFrame->height,
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
(__bridge CFDictionaryRef)(options),
pbuf);
CVPixelBufferLockBaseAddress(*pbuf, 0);
size_t bytePerRowY = CVPixelBufferGetBytesPerRowOfPlane(*pbuf, 0);
size_t bytesPerRowUV = CVPixelBufferGetBytesPerRowOfPlane(*pbuf, 1);
void* base = CVPixelBufferGetBaseAddressOfPlane(*pbuf, 0);
memcpy(base, _pFrame->data[0], bytePerRowY*_pFrame->height);
base = CVPixelBufferGetBaseAddressOfPlane(*pbuf, 1);
memcpy(base, dstPlane, bytesPerRowUV*_pFrame->height/2);
CVPixelBufferUnlockBaseAddress(*pbuf, 0);
free(dstPlane);
if(ret != kCVReturnSuccess)
{
NSLog(@"CVPixelBufferCreate Failed");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment