3

在应用程序中,我使用了 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-planar 和 y-planar?

任何人都可以帮助我吗?

4

2 回答 2

5

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

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

因此,如果您的输入视频为 352x288,您的 Y 平面将为 352x288 8bpp,而您的 CbCr 为 176x144 16bpp。这与 12bpp 352x288 图像的数据量大致相同,是 RGB888 所需数据量的一半,但仍低于 RGB565。

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

与 RGB 相比,当然, [RGBRGBRGB . . . ]

于 2012-11-19T23:32:48.630 回答
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);
于 2017-11-29T02:22:28.797 回答