分享

YUV420格式

 felwell 2012-10-08
YUV格式:
为了方便后面叙述,图片的大小定 义为:w * h,宽高分别为w和h
一、YUV420格式
先Y,后V,中间是U。其中的Y是w * h,U和V是w/2 * (h/2)
如果w = 4,h = 2,则:
yyyy
yyyy
uu
vv
内存则是:yyyyyyyyuuvv
需要占用的内存:w * h * 3 / 2
采样规律是:每个像素点都采样Y,奇数行采样1/2个U,不采样V,偶数行采样1/2个V,不采样U

二、YUV422格式
本格式使用较为广泛
每两个点为一组,共占用4个字节
YUYVYUYV…
对于每一组YUYV,前面一个Y和本组中的UV组成第一个点,第二个Y和本组中的UV组成第二个点
所以,在内存中,宽高分别为w * 2、h。
如果w = 4,h = 2,则:
YUYVYUYV
YUYVYUYV
需要占用的内存:w * h * 2

三、UYUY422格式

本格式和YUYV422一样,只是YUV的位置不一样罢了

每组中YUV的排列顺序为:UYUV

 需要占用的内存:w * h * 2

****************************************
YUV的采样格式及每种格式中单像素所占内 存大小

YUV主要的采样格式有YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和 YCbCr 4:4:4。
 采样格式          单像素所占内存大小        存放的码流

 YCbCr 4:4:4            3  byte              Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3(4像素为例)

 YCbCr 4:2:2            2  byte              Y0 U0 Y1 V1 Y2 U2 Y3 V3(4像素为例)

 YCbCr 4:2:0            1.5byte              Y0 U0 Y1 Y2 U2 Y3 Y5 V5 Y6 Y7 V7 Y8(8像素为例)
 
YCbCr 4:1:1            1.5byte              Y0 U0 Y1 Y2 V2 Y3(4像素为例)




YUV的采样格式及每种格式中单像素所占内 存大小

****************************************

 YUV422的resize较为彻底,它提供了一次性的将要resize的YUV数据resize的功能,

所以流程较为简单,具体过程为:


1、ResizeCreate

2、ResizeConfig

3、ResizeExecute

4、ResizeDelete


例:色彩空间:YUV422 ----> YUV420

      分辨率:704*576 ----> 704*576

      以上两种数据的UV分量全为半交错的

//========================================//


Resize_Handle  hResize;

Resize_Attrs rszAttrs;


/* resizehandle的创建 */

hResize = Resize_create(&rszAttrs);


//========================================//


Int32 bufSizeIn;

Int32 bufSizeOut;

Buffer_Handle resizeInBuf;

Buffer_Handle resizeOutBuf;


/* 创建config resize的输入Buffer */

bufSizeIn = BufferGfx_calcSize ( VideoStd_D1_PAL, ColorSpace_UYVY );

BufferGfx_calcDimensions ( VideoStd_D1_PAL, ColorSpace_UYVY,

                                                       &gfxAttrsin.dim );

gfxAttrsin.colorSpace = ColorSpace_UYVY;

resizeInBuf =Buffer_create (bufSizeIn, BufferGfx_getBufferAttrs (&gfxAttrsin));


/* 创建config resize的输出Buffer */

bufSizeOut = BufferGfx_calcSize ( VideoStd_D1_PAL,

ColorSpace_YUV420PSEMI );

BufferGfx_calcDimensions ( VideoStd_D1_PAL, ColorSpace_YUV420PSEMI,

                                                        &gfxAttrsout.dim );

gfxAttrsout.colorSpace = ColorSpace_YUV420PSEMI;

gfxAttrsout.dim.lineLength = Dmai_roundUp ( BufferGfx_calcLineLength

                                                        ( gfxAttrsout.dim.width, ColorSpace_YUV420PSEMI ),  32 );

resizeOutBuf= Buffer_create (bufsizeout,

       BufferGfx_getBufferAttrs (&gfxAttrsout));


 /* resize handle 的配置 */

 /* 通过 resizeInBuf 与resizeOutBuf 来配置resize,告诉resize数据的输入

   与输出的格式,大小等信息 */

 Resize_config (hResize, resizeInBuf , resizeOutBuf);


//========================================//


/* resize handle 的config 执行*/

/* resizeoInBuf 是输入buffer,里面是要resize的YUV422的数据 */

/* resizeOutBuf 是输出buffer,它用来装载resize后的YUV420数据*/

Resize_execute ( hResize, resizeoInBuf , resizeOutBuf );


//========================================//


/* resize handle 的删除 */

Resize_delete( hResize );


//========================================//


YUV420的resize较YUV422稍烦琐,它不支持对数据的一次性resize,而是要对

      Y分量跟UV分量分别进行resize操作。并且TI的dmai也没有提供对于YUV420下采样

      的接口,所以要自己去封装接口。YUV420的resize 对于一张YUV420的图片要进行

      六步操作:


1、ResizeCreate

2、ResizeConfig  ( 对于Y分量的配置 )

3、ResizeExecute ( 对于Y分量的resize )

4、ResizeConfig ( 对于UV分量的配置 )

5、ResizeExecute( 对于UV分量的resize )

6、ResizeDelete


例:色彩空间:YUV420 ----> YUV420

      分辨率:704*576 ----> 640*480

      以上两种数据的UV分量全为半交错的

      //========================================//


      /* resizehandle的创建 */

      hResize = Resize_create(&resizeAttrs);


      /* 配置resizehandle的输入输出buffer的创建 */

      /* 最后的参数1,可以实现buffer的字节对齐的功能,函数要自己封装实现 */

      hInResizeBuf = GfxBufCreate(VideoStd_D1_PAL,

           ColorSpace_YUV420PSEMI, 1 );

       hOutResizeBuf = GfxBufCreate( VideoStd_VGA,

          ColorSpace_YUV420PSEMI, 1 );


      //========================================//


      /* YComponent 为1表示当前进行的是Y分量操作 */

       YComponent = 1;


      /* 将resizehandle配置成Y分量操作 */

      Resize_Config( hResize, hInResizeBuf, hOutResizeBuf, YComponent );


      /* 进行Y分量的resize操作 */

      /* 完成后hSrcBuf里面存放的还是resize之前的数据,没有改变,

          hDstBuf里面存放的是resize后的Y分量数据,大小为640*480 */

      Resize_Execute( hResize, hSrcBuf, hDstBuf, YComponent );


     //========================================//


      /* YComponent 为1表示当前进行的是Y分量操作 */

       YComponent = 0;


      /* 将resizehandle由Y分量配置成UV分量操作 */

     Resize_Config( hResize, hInResizeBuf, hOutResizeBuf, YComponent );


      /* UV分量的resize函数里面要注意数据的偏移位置,hSrcBuf的

    数据指针要向后偏移704*576的数据量,后面的704*576/2的

    数据量才是UV数据量,而hDstBuf经过之前的resize,已经

    里面有640*480的数据,所以resize后的UV数据要从偏移

    640*480的数据后开始存储 */

     Resize_Execute( hResize, hSrcBuf, hDstBuf, YComponent );


     //========================================//


     /* resize handle 的删除 */

      Resize_delete( hResize );



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多