mmx_yv12_to_yuy2(转)

/*************************************
* Progressive YV12 -> YUY2 conversion
*
* (c) 2003, Klaus Post.
*
* Requires mod 8 rowsize.
* MMX version.
*************************************/

void mmx_yv12_to_yuy2(const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, int src_rowsize, int src_pitch, int src_pitch_uv,
BYTE* dst, int dst_pitch,
int height) {
static __int64 add_64=0x0002000200020002;
const BYTE** srcp= new const BYTE*[3];
int src_pitch_uv2 = src_pitch_uv*2;
int skipnext = 0;

int dst_pitch2=dst_pitch*2;
int src_pitch2 = src_pitch*2;



/**** Do first and last lines - NO interpolation: *****/
// MMX loop relies on C-code to adjust the lines for it.
const BYTE* _srcY=srcY;
const BYTE* _srcU=srcU;
const BYTE* _srcV=srcV;
BYTE* _dst=dst;

for (int i=0;i<4;i++) {
switch (i) {
case 1:
_srcY+=src_pitch; // Same chroma as in 0
_dst+=dst_pitch;
break;
case 2:
_srcY=srcY+(src_pitch*(height-2));
_srcU=srcU+(src_pitch_uv*((height>>1)-1));
_srcV=srcV+(src_pitch_uv*((height>>1)-1));
_dst = dst+(dst_pitch*(height-2));
break;
case 3: // Same chroma as in 4
_srcY += src_pitch;
_dst += dst_pitch;
break;
default: // Nothing, case 0
break;
}


__asm {
mov edi, [_dst]
mov eax, [_srcY]
mov ebx, [_srcU]
mov ecx, [_srcV]
mov edx,0
pxor mm7,mm7
jmp xloop_test_p
xloop_p:
movq mm0,[eax] //Y
movd mm1,[ebx] //U
movq mm3,mm0
movd mm2,[ecx] //V
punpcklbw mm0,mm7 // Y low
punpckhbw mm3,mm7 // Y high
punpcklbw mm1,mm7 // 00uu 00uu
punpcklbw mm2,mm7 // 00vv 00vv
movq mm4,mm1
movq mm5,mm2
punpcklbw mm1,mm7 // 0000 00uu low
punpcklbw mm2,mm7 // 0000 00vv low
punpckhbw mm4,mm7 // 0000 00uu high
punpckhbw mm5,mm7 // 0000 00vv high
pslld mm1,8
pslld mm4,8
pslld mm2,24
pslld mm5,24
por mm0, mm1
por mm3, mm4
por mm0, mm2
por mm3, mm5
movq [edi],mm0
movq [edi+8],mm3
add eax,8
add ebx,4
add ecx,4
add edx,8
add edi, 16
xloop_test_p:
cmp edx,[src_rowsize]
jl xloop_p
}
}

/****************************************
* Conversion main loop.
* The code properly interpolates UV from
* interlaced material.
* We process two lines in the same field
* in the same loop, to avoid reloading
* chroma each time.
*****************************************/

height-=4;

dst+=dst_pitch2;
srcY+=src_pitch2;
srcU+=src_pitch_uv;
srcV+=src_pitch_uv;

srcp[0] = srcY;
srcp[1] = srcU-src_pitch_uv;
srcp[2] = srcV-src_pitch_uv;

int y=0;
int x=0;

__asm {
mov esi, [srcp]
mov edi, [dst]

mov eax,[esi]
mov ebx,[esi+4]
mov ecx,[esi+8]
mov edx,0
jmp yloop_test
align 16
yloop:
mov edx,0 // x counter
jmp xloop_test
align 16
xloop:
mov edx, src_pitch_uv
movq mm0,[eax] // mm0 = Y current line
pxor mm7,mm7
movd mm2,[ebx+edx] // mm2 = U top field
movd mm3, [ecx+edx] // mm3 = V top field
movd mm4,[ebx] // U prev top field
movq mm1,mm0 // mm1 = Y current line
movd mm5,[ecx] // V prev top field

punpcklbw mm2,mm7 // U 00uu 00uu 00uu 00uu
punpcklbw mm3,mm7 // V 00vv 00vv 00vv 00vv
punpcklbw mm4,mm7 // U 00uu 00uu 00uu 00uu
punpcklbw mm5,mm7 // V 00vv 00vv 00vv 00vv
paddusw mm4,mm2
paddusw mm5,mm3
paddusw mm4,mm2
paddusw mm5,mm3
paddusw mm4,mm2
paddusw mm5,mm3
paddusw mm4, [add_64]
paddusw mm5, [add_64]
psrlw mm4,2
psrlw mm5,2


punpcklbw mm0,mm7 // Y low
punpckhbw mm1,mm7 // Y high*
pxor mm6,mm6
punpcklbw mm6,mm4 // U 0000 uu00 0000 uu00 (low)
punpckhbw mm7,mm4 // V 0000 uu00 0000 uu00 (high
por mm0,mm6
por mm1,mm7
movq mm6,mm5
punpcklbw mm5,mm5 // V 0000 vvvv 0000 vvvv (low)
punpckhbw mm6,mm6 // V 0000 vvvv 0000 vvvv (high)
pslld mm5,24
pslld mm6,24
por mm0,mm5
por mm1,mm6
mov edx, src_pitch_uv2
movq [edi],mm0
movq [edi+8],mm1

//Next line

movd mm4,[ebx+edx] // U next top field
movd mm5,[ecx+edx] // V prev top field
mov edx, [src_pitch]
pxor mm7,mm7
movq mm0,[eax+edx] // Next U-line
movq mm1,mm0 // mm1 = Y current line

punpcklbw mm4,mm7 // U 00uu 00uu 00uu 00uu
punpcklbw mm5,mm7 // V 00vv 00vv 00vv 00vv
paddusw mm4,mm2
paddusw mm5,mm3
paddusw mm4,mm2
paddusw mm5,mm3
paddusw mm4,mm2
paddusw mm5,mm3
paddusw mm4, [add_64]
paddusw mm5, [add_64]
psrlw mm4,2
psrlw mm5,2

punpcklbw mm0,mm7 // Y low
punpckhbw mm1,mm7 // Y high*
pxor mm6,mm6
punpcklbw mm6,mm4 // U 0000 uu00 0000 uu00 (low)
punpckhbw mm7,mm4 // V 0000 uu00 0000 uu00 (high
por mm0,mm6
por mm1,mm7
movq mm6,mm5
punpcklbw mm5,mm5 // V 0000 vvvv 0000 vvvv (low)
punpckhbw mm6,mm6 // V 0000 vvvv 0000 vvvv (high)
pslld mm5,24
mov edx,[dst_pitch]
pslld mm6,24
por mm0,mm5
por mm1,mm6
movq [edi+edx],mm0
movq [edi+edx+8],mm1
add edi,16
mov edx, [x]
add eax, 8
add ebx, 4
add edx, 8
add ecx, 4
xloop_test:
cmp edx,[src_rowsize]
mov x,edx
jl xloop
mov edi, dst
mov eax,[esi]
mov ebx,[esi+4]
mov ecx,[esi+8]

add edi,[dst_pitch2]
add eax,[src_pitch2]
add ebx,[src_pitch_uv]
add ecx,[src_pitch_uv]
mov edx, [y]
mov [esi],eax
mov [esi+4],ebx
mov [esi+8],ecx
mov [dst],edi
add edx, 2

yloop_test:
cmp edx,[height]
mov [y],edx
jl yloop
emms
}
delete[] srcp;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值