请大家分析一下为什么这个YUV420转RGB32的程序效率如此低下

fzfzfz 2006-09-23 10:29:25

#define RGB4Y 1.164
#define B4U 2.018
#define Y2ADD 16

#define G4U 0.391
#define G4V 0.813
#define U2ADD 128

#define R4V 1.596
#define V2ADD 128

#define SCALEBITS 13

#define FIX(x) ((WORD) ((x) * (1L << SCALEBITS) + 0.5))



int g_RGB4Y_Tab[256];

int g_B4U_Tab[256];
int g_G4U_Tab[256];
int g_G4V_Tab[256];
int g_R4V_Tab[256];



void InitColorSpace()
{
for (UINT i = 0; i < 256; i++)
{
g_RGB4Y_Tab[i] = FIX(RGB4Y) * (i - Y2ADD);
g_B4U_Tab[i] = FIX(B4U ) * (i - U2ADD);
g_G4U_Tab[i] = FIX(G4U ) * (i - U2ADD);
g_G4V_Tab[i] = FIX(G4V ) * (i - V2ADD);
g_R4V_Tab[i] = FIX(R4V ) * (i - V2ADD);
}
}


inline BYTE ClipColorValue(int x)
{
return x < 0 ? 0 : (x > 255 ? 255 : x);
}


inline void YUV420_RGB32_4Pixel(LPBYTE pRGB, LPBYTE pY, LPBYTE pU, LPBYTE pV, UINT Width)
{
int nRGB4Y = 0;
int nB4U = g_B4U_Tab[pU[0]];
int nG4UV = g_G4U_Tab[pU[0]] + g_G4V_Tab[pV[0]];
int nR4V = g_R4V_Tab[pV[0]];


// (0, 0)

nRGB4Y = g_RGB4Y_Tab[pY[0]];

pRGB[0] = ClipColorValue((nRGB4Y + nB4U ) >> SCALEBITS);
pRGB[1] = ClipColorValue((nRGB4Y - nG4UV) >> SCALEBITS);
pRGB[2] = ClipColorValue((nRGB4Y + nR4V ) >> SCALEBITS);
pRGB[3] = 0;


// (0, 1)

nRGB4Y = g_RGB4Y_Tab[pY[1]];

pRGB[4] = ClipColorValue((nRGB4Y + nB4U ) >> SCALEBITS);
pRGB[5] = ClipColorValue((nRGB4Y - nG4UV) >> SCALEBITS);
pRGB[6] = ClipColorValue((nRGB4Y + nR4V ) >> SCALEBITS);
pRGB[7] = 0;


// (1, 0)

nRGB4Y = g_RGB4Y_Tab[pY[Width]];

pRGB[(Width<<2)+0] = ClipColorValue((nRGB4Y + nB4U ) >> SCALEBITS);
pRGB[(Width<<2)+1] = ClipColorValue((nRGB4Y - nG4UV) >> SCALEBITS);
pRGB[(Width<<2)+2] = ClipColorValue((nRGB4Y + nR4V ) >> SCALEBITS);
pRGB[(Width<<2)+3] = 0;


// (1, 1)

nRGB4Y = g_RGB4Y_Tab[pY[Width+1]];

pRGB[(Width<<2)+4] = ClipColorValue((nRGB4Y + nB4U ) >> SCALEBITS);
pRGB[(Width<<2)+5] = ClipColorValue((nRGB4Y - nG4UV) >> SCALEBITS);
pRGB[(Width<<2)+6] = ClipColorValue((nRGB4Y + nR4V ) >> SCALEBITS);
pRGB[(Width<<2)+7] = 0;
}


///////////////////////////////////////////////////////////////////////////////////
//

void YUV420_RGB32(LPBYTE pRGB, LPBYTE pYUV, DWORD Width, DWORD Height)
{
LPBYTE pY = pYUV, pU = pY + Width * Height, pV = pU + Width * Height/4;

UINT x, y;
for (y = 0; y < Height; y += 2)
{
for (x = 0; x < Width; x += 2)
{
YUV420_RGB32_4Pixel(pRGB, pY, pU, pV, Width);

pRGB += 8; pY += 2; pU += 1; pV += 1;
}

pRGB += Width<<2;
pY += Width;
}
}
...全文
639 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyhzpk 2006-09-27
  • 打赏
  • 举报
回复
可以用ipp库试试
fzfzfz 2006-09-27
  • 打赏
  • 举报
回复
好的谢谢,fz_fz@tom.com

cscc.lib应该没优化吧,MMX都要对齐的,它好象没要求对齐,况且我还额外做了RGB24转RGB32的赋值,CPU占用率还是特别小。

是不是查表访问内存次数多了?

不过我觉得即使是汇编优化,也不应该有这么大的优势,比方算SAD什么的,也就快个2倍,3倍的。
Bill1212 2006-09-27
  • 打赏
  • 举报
回复
你不是说不用汇编优化吗?你怎么知道cscc.lib中也没有用汇编优化?不可比的。我只是说用C也只能做到这个样子了。
我这里有一段sse的优化代码,你需要的话发给你好了。
fzfzfz 2006-09-27
  • 打赏
  • 举报
回复
顶顶!
fzfzfz 2006-09-25
  • 打赏
  • 举报
回复
Bill老兄,不瞒您说,该算法不是一般的慢,我处理CIF格式352x288,25FPS,2.4G CPU占到了35%,我用YUVViewer的cscc.lib中的转换函数转成RGB24,再赋值转成RGB32都不到1%(也就是说0%)。我好纳闷,怎么效率低了几百倍???
Bill1212 2006-09-25
  • 打赏
  • 举报
回复
这个算法还可以,若不考虑汇编也只能这样了, 即使要优化,提高也不会太大。

我觉得有个可以优化的地方,如下:
YUV420_RGB32_4Pixel的调用一次可以处理两行RGB或y。因为yuv420的一行u或v用于两行的y或RGB。如果一次只处理两个pixel,函数调用次数过多,额外消耗就过多。
fzfzfz 2006-09-25
  • 打赏
  • 举报
回复
没人气啊 :(
happydeer 2006-09-23
  • 打赏
  • 举报
回复
到一些开源的项目中去找找优化过的方法吧,比如ffmpeg, ffdshow。
fzfzfz 2006-09-23
  • 打赏
  • 举报
回复
光从算法的角度讲,不考虑汇编优化
fzfzfz 2006-09-23
  • 打赏
  • 举报
回复
这是xvid中的改写的,只是把它的宏改为inline函数

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧