如何在ios中将y平面,u平面和uv平面与yuv bi平面分开?

时间:2012-11-17 09:50:45

标签: objective-c video-streaming avfoundation

在应用程序中,我使用了AVCaptureVideo。我收到了kCVPixelFormatType_420YpCbCr8BiPlanarFullRange格式的视频。

现在我从imagebuffer获得了y-planar和uv-planar。

  CVPlanarPixelBufferInfo_YCbCrBiPlanar *planar = CVPixelBufferGetBaseAddress(imageBuffer);

    size_t y-offset = NSSwapBigLongToHost(planar->componentInfoY.offset);
    size_t uv-offset = NSSwapBigLongToHost(planar->componentInfoCbCr.offset);

这里yuv是双平面格式(y + UV)。

什么是UV平面?这是uuuu,yyyy格式还是uvuvuvuv格式? 如何分离u平面和y平面?

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:4)

Y平面表示亮度分量,UV平面表示Cb和Cr色度分量。

对于kCVPixelFormatType_420YpCbCr8BiPlanarFullRange格式,您会发现亮度平面为8bpp,其尺寸与视频相同,您的色度平面将为16bpp,但仅为原始视频大小的四分之一。在这个平面上,每个像素将有一个Cb和一个Cr组件。

所以,如果你的输入视频是352x288,你的Y平面将是352x288 8bpp,你的CbCr是176x144 16bpp。这与12bpp 352x288图像的数据量相同,是RGB888所需的一半,仍然低于RGB565。

所以在缓冲区中,Y看起来像这样 [YYYYY . . . ] 和紫外线 [UVUVUVUVUV . . .]

vs RGB当然是 [RGBRGBRGB . . . ]

答案 1 :(得分:0)

下面的代码复制来自pixelBuffer的 yuv 数据,其格式为kCVPixelFormatType_420YpCbCr8BiPlanarFullRange。

CVPixelBufferLockBaseAddress(pixelBuffer, 0);

size_t pixelWidth = CVPixelBufferGetWidth(pixelBuffer);
size_t pixelHeight = CVPixelBufferGetHeight(pixelBuffer);
// y bite size
size_t y_size = pixelWidth * pixelHeight;
// uv bite size
size_t uv_size = y_size / 2;
uint8_t *yuv_frame = malloc(uv_size + y_size);
// get base address of y
uint8_t *y_frame = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
// copy y data
memcpy(yuv_frame, y_frame, y_size);
// get base address of uv
uint8_t *uv_frame = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
// copy uv data
memcpy(yuv_frame + y_size, uv_frame, uv_size);

CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);