¿Convertir CMSampleBufferRef a UIImage con espacio de color YUV?

Estoy trabajando con AVCaptureVideoDataOutput y quiero convertir CMSampleBufferRef a UIImage . Muchas respuestas son las mismas, como este UIImage creado a partir de CMSampleBufferRef no se muestra en UIImageView? y AVCaptureSession con vistas previas múltiples

Funciona bien si configuro el espacio de color VideoDataOutput en BGRA (se atribuye a este error de respuesta CGBitmapContextCreateImage )

 NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; [dataOutput setVideoSettings:videoSettings]; 

Sin los ajustes de video anteriores, recibiré los siguientes errores

 CGBitmapContextCreate: invalid data bytes/row: should be at least 2560 for 8 integer bits/component, 3 components, kCGImageAlphaPremultipliedFirst. <Error>: CGBitmapContextCreateImage: invalid context 0x0 

Trabajar con BGRA no es una buena opción, ya que hay una sobrecarga de conversión desde YUV (espacio de color AVCaptureSession pnetworkingeterminado) a BGRA, como lo indican Brad y Codo en Cómo get el componente Y de CMSampleBuffer como resultado de AVCaptureSession?

Entonces, ¿hay alguna forma de convertir CMSampleBufferRef a UIImage y trabajar con el espacio de color YUV?

Después de hacer muchas investigaciones y leer documentaciones de apple y wikipedis. Me di count de la respuesta y funciona perfectamente para mí. Entonces, para los futuros lectores, estoy compartiendo el código para convertir CMSampleBufferRef a UIImage cuando el tipo de píxel de video se establece como kCVPixelFormatType_420YpCbCr8BiPlanarFullRange

 // Create a UIImage from sample buffer data // Works only if pixel format is kCVPixelFormatType_420YpCbCr8BiPlanarFullRange -(UIImage *) imageFromSamplePlanerPixelBuffer:(CMSampleBufferRef) sampleBuffer{ @autoreleasepool { // Get a CMSampleBuffer's Core Video image buffer for the media data CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); // Lock the base address of the pixel buffer CVPixelBufferLockBaseAddress(imageBuffer, 0); // Get the number of bytes per row for the plane pixel buffer void *baseAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0); // Get the number of bytes per row for the plane pixel buffer size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer,0); // Get the pixel buffer width and height size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); // Create a device-dependent gray color space CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); // Create a bitmap graphics context with the sample buffer data CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGImageAlphaNone); // Create a Quartz image from the pixel data in the bitmap graphics context CGImageRef quartzImage = CGBitmapContextCreateImage(context); // Unlock the pixel buffer CVPixelBufferUnlockBaseAddress(imageBuffer,0); // Free up the context and color space CGContextRelease(context); CGColorSpaceRelease(colorSpace); // Create an image object from the Quartz image UIImage *image = [UIImage imageWithCGImage:quartzImage]; // Release the Quartz image CGImageRelease(quartzImage); return (image); } }