How seperate y-planar, u-planar and uv-planar from

2019-02-15 06:21发布

问题:

In application i used AVCaptureVideo. i got video in kCVPixelFormatType_420YpCbCr8BiPlanarFullRange format.

now i am getting y-planar and uv-planar from imagebuffer.

  CVPlanarPixelBufferInfo_YCbCrBiPlanar *planar = CVPixelBufferGetBaseAddress(imageBuffer);

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

here yuv is biplanar format(y+UV).

what is UV-planar? is this uuuu,yyyy format or uvuvuvuv format? How to i get u-planar and y-planar seperatly?

can any one pls help me?

回答1:

The Y plane represents the luminance component, and the UV plane represents the Cb and Cr chroma components.

In the case of kCVPixelFormatType_420YpCbCr8BiPlanarFullRange format, you will find the luma plane is 8bpp with the same dimensions as your video, your chroma plane will be 16bpp, but only a quarter of the size of the original video. You will have one Cb and one Cr component per pixel on this plane.

so if your input video is 352x288, your Y plane will be 352x288 8bpp, and your CbCr 176x144 16bpp. This works out to be about the same amount of data as a 12bpp 352x288 image, half what would be required for RGB888 and still less than RGB565.

So in the buffer, Y will look like this [YYYYY . . . ] and UV [UVUVUVUVUV . . .]

vs RGB being, of course, [RGBRGBRGB . . . ]



回答2:

Below code copy yuv data from pixelBuffer whose format is 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);