uv422转换为yuv420_YUV420 Planar 转换为 YUV422 Packed

YUV格式通常有两大类:打包(packed)格式和平面(planar)格式。

Packed 格式将YUV分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素(macro-pixel),

比如相邻两个像素组成一个宏像素,UYVY

Planar 格式使用三个数组分开存放YUV三个分量。

在使用 FFMPEG avcodec_decode_video() 函数解码H.264码流后,得到 planar 格式存储的YUV分量

data[0], linesize[0], 描述Y分量的地址和跨度(stride)

data[1], data[2], linesize[1], 描述U,V分量的地址和跨度(stride)

在某些场合下,我们需要将YUV420 Planar格式转化成 YUV422 Packed格式,以方便显示或处理。下面这个函数使用MMX指令完成这个任务。

void YUV420toUYVY422(unsigned char *pszSrcY, int iSrcPitchY, unsigned char *pszSrcU,

unsigned char *pszSrcV, int iSrcPitchUV, unsigned char *pszDst,

int iSrcWidth, int iSrcHeight, int iDstPitch)

{

int iSrcStride = iSrcPitchY + iSrcPitchY - iSrcWidth;

int iSrcStrideU = (iSrcPitchY - iSrcWidth) >> 1;

int iDstStride =(iDstPitch - iSrcWidth) << 1;

__asm

{

push ebx

mov edi , [pszDst]

mov esi , [pszSrcY]

mov eax , [pszSrcU]

mov ebx , [pszSrcV]

mov ecx , [iSrcHeight]

mov edx , [iSrcWidth]

cyc:

movq mm0, qword ptr[esi] //y1(yyyyyyyy)

movq mm1, qword ptr[esi + 8] //y2      (yyyyyyyy)

movq mm2 , qword ptr [eax] //u ( u u u u u u u u)

movq mm3 , qword ptr [ebx] //v ( v v v v v v v v)

movq mm4 , mm2

//push eax

//xor eax, eax

//movd mm2, eax //u ( u u u u u u u u)

//movd mm3, eax //v ( v v v v v v v v)

//movq mm4, mm2

//pop eax

//-----------------------------------------------------

//punpcklbw mmDST, mmSRC

//交叉组合 mmDST 与 mmSRC 低位双字(4B)中的字节,

//结果(8B)放入 mmDST

//-----------------------------------------------------

//before:

//MM0 == 01 02 03 04 _ 05 06 07 08 hex

//MM1 == 09 0a 0b 0c _ 0d 0e 0f 00 hex

//punpcklbw MM0, MM1, after:

//MM0 = 0d 05 0e 06 0f 07 00 08 h  (64bit full)

//-----------------------------------------------------

//when write MM0 to memory: 08 00 07 0f 06 0e 05 0d h

//-----------------------------------------------------

punpcklbw mm2 , mm3 // uv1 ( LOW 8B         v u v u v u v u)

punpckhbw mm4 , mm3 // uv2 (v u v u v u v u         HI 8B  )

movq mm6 , mm2

movq mm7 , mm4

movq mm3 , mm2

movq mm5 , mm4

punpcklbw mm2 , mm0 // uyvy1 (                y v y u y v y u)

punpckhbw mm3 , mm0 // uyvy2 (y v y u y v y u                )

punpcklbw mm4 , mm1 // uyvy3 (                Y v Y u Y v Y u)

punpckhbw mm5 , mm1 // uyvy4 (Y v Y u Y v Y u                )

movq qword ptr [edi] , mm2

movq qword ptr [edi+8] , mm3

movq qword ptr [edi+16] , mm4

movq qword ptr [edi+24] , mm5

add esi , [iSrcPitchY]

add edi , [iDstPitch]

movq mm0 , qword ptr [esi]   //y1

movq mm1 , qword ptr [esi+8] //y2

movq mm2 , mm6

movq mm4 , mm7

movq mm3 , mm2

movq mm5 , mm4

punpcklbw mm2 , mm0 // uyvy 1  //low byte mix

punpckhbw mm3 , mm0 // uyvy 2  //high byte mix

punpcklbw mm4 , mm1 // uyvy 3

punpckhbw mm5 , mm1 // uyvy 4

movq qword ptr [edi] , mm2

movq qword ptr [edi+8] , mm3

movq qword ptr [edi+16] , mm4

movq qword ptr [edi+24] , mm5

sub esi , [iSrcPitchY]

sub edi , [iDstPitch]

add eax , 8    //U

add ebx , 8    //V

add esi , 16   //Y

add edi , 32   //DST

sub edx , 16   //WIDTH

ja cyc         //repeat until current row completes

mov edx,  [iSrcWidth]   //Reload width at new row

add esi , [iSrcStride]  //Reload stride at new row

add eax , [iSrcStrideU] //U stride

add ebx , [iSrcStrideU] //V stride

add edi , [iDstStride]  //Y stride

sub ecx,2       //HEIGHT 480

ja cyc          //repeat until all rows complete

emms

pop ebx

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值