2012-11-17 41 views
3

在應用程序中我使用了AVCaptureVideo。我以kCVPixelFormatType_420YpCbCr8BiPlanarFullRange格式獲得了視頻。從yuv bi平面在ios中如何分離y平面,u平面和uv平面?

現在我正在從圖像緩衝區獲得y平面和uv平面。

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平面分離?

任何人都可以幫助我嗎?

+1

本Q和A缺乏故意模糊性,令人耳目一新。 – 2014-04-03 23:37:59

回答

2

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 . . .]

當然VS RGB之中, [RGBRGBRGB . . . ]

+0

爲什麼UV平面是Y平面中像素數量的四分之一? – mrplants

+0

y的每4個像素有1 u和1 v像素。因此,u和v平面的大小是y的四分之一 –

0

下面的代碼複製YUV從pixelBuffer其格式數據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);