在视频格式转换中使用MMX和SSE指令集提高性能

转载 2006年06月25日 20:26:00

大家都知道使用Overlay平面显示视频可能充分利用显示的硬件加速功能,自由缩放,同时显著降低CPU的消耗。但现在市场上流行的MP4,H.264板卡解压时往往输出的格式是YV12,这种格式在多数显卡上无法正常显示,一般需要转换为YUYV格式进行显示。

一.直接C++代码进行转换

void CDispOverlay::BufferFrame(

UINT nID, // 通道编号

PBYTE pBuf, // 源数据

UINT nLen, // 缓冲区长度

DWORD nFmt, // 原始格式, 可以是YUYV,RGB24或YV12

UINT nWidth, // 宽度(缺省:352)

UINT nHeight // 高(缺省:288)

)

{

 

/*

其它格式的转换

*/

if(MAKEFOURCC('Y','U','Y','2')==m_pDisp->GetFmt()->biCompression

&& MAKEFOURCC('Y','V','1','2')==nFmt)

{

// pBuf指向YV12格式的数据

UINT x=0, y=0;

   BYTE* pDest = (BYTE*)m_pDispData[nID].GetData();

    BYTE* y_src = (BYTE*)pBuf;

   BYTE* v_src = (BYTE*)(pBuf+(nWidth*nHeight));

BYTE* u_src = (BYTE*)(pBuf+(nWidth*nHeight*5/4));

UINT width=nWidth>>1;

  for (y = 0; y

{

  for (x = 0; x

{

  pDest[0] = y_src[x<<1];

  pDest[1] = u_src[x];

   pDest[2] = y_src[(x<<1)+1];

   pDest[3]= v_src[x];

   pDest += 4;

  }

  y_src += nWidth;

   if (y & 1)

{

  u_src += width;

  v_src += width;

   }

}

}

}

二.使用MMX指令集

int height=nHeight>>1;

for(int y=0;y

{ //about 10% faster than plain C++

__asm{

 mov edi,[pDest]

 mov ebx,[nWidth]

 shr ebx,3

 mov esi,[y_src]

 mov ecx,[u_src]

 mov edx,[v_src]

 xor eax,eax ; x=0

 align 8

xxloop1:

 movd mm1,[edx+4*eax]

 movd mm0,[ecx+4*eax]

 punpcklbw mm0, mm1 ; [vuvu|vuvu]

 movq mm2,[esi+8*eax]

 movq mm3, mm2

 punpcklbw mm2, mm0 ; [vyuy|vyuy]

 movntq [edi], mm2

 punpckhbw mm3, mm0 ; [vyuy|vyuy]

 movntq [edi+8], mm3

 add edi,16

 inc eax

 cmp eax,ebx

 jb xxloop1

 add esi,[width]

 xor eax,eax

xxloop2:

 movd mm1,[edx+4*eax]

 movd mm0,[ecx+4*eax]

 punpcklbw mm0, mm1 ; [vuvu|vuvu]

 movq mm2,[esi+8*eax]

 movq mm3, mm2

 punpcklbw mm2, mm0 ; [vyuy|vyuy]

 movntq [edi], mm2

 punpckhbw mm3, mm0 ; [vyuy|vyuy]

 movntq [edi+8], mm3

 add edi,16

 inc eax

 cmp eax, ebx

 jb xxloop2

 add esi,[width]

 mov [pDest],edi

 mov [y_src],esi

 shl ebx,2

 add ecx,ebx

 add edx,ebx

 mov [u_src],ecx

 mov [v_src],edx

 }

}

__asm EMMS;

三.使用SSE指令集

int height=nHeight>>1;

for(int y=0;y

{//about 20% faster than plain C++

__asm{

mov edi,[pDest]

 mov ebx,[nWidth]

 shr ebx,4

 mov esi,[y_src]

 mov ecx,[u_src]

 mov edx,[v_src]

 xor eax,eax ; x=0

 align 16

xloop1:

 movq xmm1,mmword ptr [edx+8*eax]

 movq xmm0,mmword ptr [ecx+8*eax]

 movdqa  xmm2,xmmword ptr [esi]

 inc eax

 movq xmm5,mmword ptr [edx+8*eax]

 punpcklbw  xmm0, xmm1 ; [vuvu|vuvu]

 movq xmm4,mmword ptr [ecx+8*eax]

 movdqa  xmm3, xmm2

 movdqa  xmm7,xmmword ptr [esi+16]

 punpcklbw xmm4,xmm5

 movdqa  xmm6,xmm7

 punpcklbw  xmm2, xmm0 ; [vyuy|vyuy]

 movntdq  [edi], xmm2

 punpckhbw  xmm3, xmm0  ; [vyuy|vyuy]

 punpcklbw xmm6,xmm4

 movntdq  xmmword ptr [edi+16], xmm3

 punpckhbw xmm7,xmm4

 movntdq  [edi+32],xmm6

 add  esi,32

 movntdq  [edi+48],xmm7

 add  edi,64

 inc  eax

 cmp  eax,ebx

 jb  xloop1

 xor  eax,eax

xloop2:

 movq xmm1,mmword ptr [edx+8*eax]

 movq xmm0,mmword ptr [ecx+8*eax]

 movdqa  xmm2,xmmword ptr [esi]

 inc eax

 movq xmm5,mmword ptr [edx+8*eax]

 punpcklbw  xmm0, xmm1 ; [vuvu|vuvu]

 movq xmm4,mmword ptr [ecx+8*eax]

 movdqa  xmm3, xmm2

 movdqa  xmm7,xmmword ptr [esi+16]

 punpcklbw xmm4,xmm5

 movdqa  xmm6,xmm7

 punpcklbw  xmm2, xmm0 ; [vyuy|vyuy]

 movntdq [edi], xmm2

 punpckhbw  xmm3, xmm0 ; [vyuy|vyuy]

 punpcklbw xmm6,xmm4

 movntdq  xmmword ptr [edi+16], xmm3

 punpckhbw xmm7,xmm4

 movntdq  [edi+32],xmm6

 add  esi,32

 movntdq  [edi+48],xmm7

 add  edi,64

 inc  eax

 cmp  eax, ebx

 jb  xloop2

 mov  [pDest],edi

 mov  [y_src],esi

 shl  ebx,3

 add  ecx,ebx

 add  edx,ebx

 mov  [u_src],ecx

 mov  [v_src],edx

 }

}

__asm EMMS;

四.如何判断CPU是否支持MMX和SSE指令集

#include

static bool _IsFeature(DWORD dwRequestFeature)

{

 _p_info cpuinfo;

 _cpuid(&cpuinfo);

 return (cpuinfo.feature & dwRequestFeature)!=0;

}

bool IsMMX()

{

 static bool bMMX = _IsFeature(_CPU_FEATURE_MMX);

 return(bMMX);

}

 

bool IsSSE2()

{

 /**/

 static bool bSSE2 = _IsFeature(_CPU_FEATURE_SSE2);

 return(bSSE2);

 /**/

}

bool IsSSE()

{

 /**/

 static bool bSSE = _IsFeature(_CPU_FEATURE_SSE);

 return(bSSE);

 /**/

}

bool Is3DNow()

{

 /**/

 static bool b3DNow = _IsFeature(_CPU_FEATURE_3DNOW);

 return(b3DNow);

 /**/

}

在视频格式转换中使用MMX和SSE指令集提高性能

大家都知道使用Overlay平面显示视频可能充分利用显示的硬件加速功能,自由缩放,同时显著降低CPU的消耗。但现在市场上流行的MP4,H.264板卡解压时往往输出的格式是YV12,这种格式在多数显卡上...

使用MMX/SSE汇编指令集优化视频开发

1、汇编指令集 目前大部分的PC机采用的都是Intel或者AMD的CPU,其支持的多媒体汇编指令有: MMX:多媒体扩展指令(MultiMedia eXtention),该指令由Intel在1996年...

[C] 跨平台使用Intrinsic函数范例3——使用MMX、SSE2指令集 处理 32位整数数组求和

作者:zyl910。   本文面对对SSE等SIMD指令集有一定基础的读者,以32位整数数组求和为例演示了如何跨平台使用MMX、SSE2指令集。支持vc、gcc编译器,在Windows、Linux、...
  • zyl910
  • zyl910
  • 2012年10月26日 21:23
  • 5210

【JAVA】JAVA使用ffmpeg进行视频格式转换以及截图

JAVA 处理视频文件,需要用到 ffmpeg  这个工具。不需要依赖jar包。无论是在windows服务器还是linux服务器,想要使用 ffmpeg 都需要先安装。 附上Linux下  ...

[VC6] 检查MMX和SSE系列指令集的支持级别(最高SSE4.2)

参考文献—— 《Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2 (2A, 2B & 2C): Instr...
  • zyl910
  • zyl910
  • 2012年03月01日 22:45
  • 1651

php视频格式转换---------ffmpeg-php扩展与ffmpeg.exe安装与使用

HP转换视频格式这个问题,找了一下午的ffmpeg-php扩展的安装与使用方法,都是千篇一律转载的。 下面是我整理的步骤,希望能帮助大家这个问题。 1.下载ffmpeg-php扩展包和ffmp...
  • c2a2o2
  • c2a2o2
  • 2017年03月17日 15:38
  • 803

(浏览器兼容问题)使用ffmpeg进行视频格式转换的用法

在HTML5中,新增的元素无疑为我们处理视频提供了极大便利,不过有一个问题我们也必须去解决的,就是不同浏览器对视频格式的支持不同,那么有时候我们必须去进行一些视频格式的转换,我们可以通过处理视频源文件...

使用ffmpeg视频格式转换、视频截图、视频采集、屏幕录制

ffmpeg非常强大,轻松几条命令就可以完成你的工作。 把darkdoor.[001-100].jpg序列帧和001.mp3音频文件利用mpeg4编码方式合成视频文件darkdoor.avi: ...
  • dlhansy
  • dlhansy
  • 2015年08月07日 17:57
  • 247

MMX指令集在C++中的使用

转自 http://www.vckbase.com/document/viewdoc/?id=418 下载本文示例源代码 上次在《关于内联汇编的几个技巧...
  • arau_sh
  • arau_sh
  • 2012年06月04日 13:36
  • 521

《mmx指令集在c++中的使用》

  • 2004年07月28日 00:00
  • 15KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在视频格式转换中使用MMX和SSE指令集提高性能
举报原因:
原因补充:

(最多只允许输入30个字)