点击视界音你而不同关注我们!
搞音视频,相信RGB与YUV之间的转换,大家都不陌生。不过呢,由于这个转换的公式是浮点运算,再加上大量像素的密集型运算,导致对资源的消耗比较大,进而效率需要进一步的提升。
首先我们来看看,RGB转YUV的公式:
Y = 0.299*R + 0.587*G + 0.114*B;
U = -0.169*R - 0.331*G + 0.5 *B ;
V = 0.5 *R - 0.419*G - 0.081*B;
观察一下,都是浮点型的运算,我们都知道浮点型的乘法运算,在计算机内部要经过阶码和尾数的运算,相对耗时。如果我们能将浮点运算去掉,就可以实现这个目标了。于是,我们可以通过数学上的一些变换,将浮点运算变换为整数运算。变换过程如下:
Y = 0.299*R + 0.587*G + 0.114*B
= 128 * (0.299*R + 0.587*G + 0.114*B) >> 7
= ( 38 * R + 75 * B + 15 * B) >> 7;
经过如此转换,浮点运算就变成了整数乘法和位移运算,而位移运算,效率很高,整数乘法的运算也会较浮点运算的效率高些,所以,此方法是可取的。
由于音视频数据的处理,是典型的密集型运算。即针对每一个像素,我们的算法和处理方式都是一样的,这也为我们做进一步优化提供了可能。
比较原始的方式,我们遍历每一个像素,针对每一个像素做转换处理,这样实现功能没有问题,但效率相对来说会比较低下。由于算法是相同的,所以我们可以一次处理多个像素,这样就会大大提升效率。
假设原来一次处理一个像素,现在我们一次处理16个像素,这样我们的效率理论上就会提到16倍,当然这只是理论值,实际上10倍是有把握的,也相当可观了。而要实现这样的操作,我们可以借助多媒体指令集,如MMX,SSE等,如此这般,便可实现效率的提升。不过呢,要注意一个对齐的问题,如果我们一次处理16个像素,那么图片的宽就必须是16的倍数,否则就需要做一些容错的处理,比如填充。
下面是部分代码,估计不可以直接使用哦,要根据机器自身CPU支持的指令集做相应的调整哦。
int YUV420_RGB32_mmx(uint32_t* rgb, int width, int height, uint8_t* y, uint8_t* u, uint8_t* v){__asm{pushadfinitxor eax, eaxmov ebx, heightmov ecx, widthmov edx, ymov edi, vmov esi, umov ebp, rgbhloop:push ebxmov ebx, ecxwloop :push ebxxor ebx, ebxmov al, [edi]mov bl, [esi]movq mm0, [CoefficientsRGBU + 8*eax]paddw mm0, [CoefficientsRGBV + 8*ebx]mov al, [edx]mov bl, [edx + 1]movq mm1, [CoefficientsRGBY + 8 * eax]movq mm2, [CoefficientsRGBY + 8 * ebx]mov al, [edx + ecx]mov bl, [edx + ecx + 1]movq mm3, [CoefficientsRGBY + 8 * eax]movq mm4, [CoefficientsRGBY + 8 * ebx]paddw mm1, mm0paddw mm2, mm0paddw mm3, mm0paddw mm4, mm0psraw mm1, 6psraw mm2, 6psraw mm3, 6psraw mm4, 6packuswb mm1, mm2packuswb mm3, mm4movq[ebp], mm1movq[ebp + 4 * ecx], mm3add ebp, 8add edx, 2add edi, 1add esi, 1pop ebxsub ebx, 2jnz wlooplea ebp, [ebp + 4*ecx]add edx, ecxpop ebxsub ebx, 2jnz hloopemmspopad}}
总结一下,RGB转YUV是音视频中常见的一个处理过程,针对其也有一定的优化空间。优化主要分为两个方向,一个是对转换公式本身做一些变换,从而避免浮点运算;另外一个就是借助指令集,实现从单一处理到批量处理。希望对你有帮助。也希望各位多多关注,多多转发,多多点在看(脸好像有点大了)。
本文分享自微信公众号 - 视界音你而不同(WorldOfVideoAndAudio)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/4579542/blog/4350448