财产保险包括哪些:ARM平台YUV转RGB888 - Nova的专栏 - CSDN博客

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 19:13:52
 前段时间,公司有个嵌入式的项目,我做的其中有一项是yuv视频到rgb888图像的转换。我主要是参照一位牛人的博客做的:http://blog.csdn.net/housisong/archive/2007/10/31/1859084.aspx

      YUV422p To RGB888 C语言版本接口说明:

view plaincopy to clipboardprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. /****************************************YUV422P_To_RGB24.c**************************/  
  2. //模块功能:将YUV422_PLANAR图像数据转换成RGB24格式  
  3. typedef unsigned char BYTE; // [0..255]  
  4. /* 
  5.  * 接口说明: 
  6.  * 功能:构建查询表,转换模块运行前必须进行的初始化操作 
  7.  */  
  8. void YUV422P_To_RGB24_init();  
  9. /* 
  10.  *接口说明: 
  11.  *功能:将YUV422P图像数据转换成RGB24格式 
  12.  *参数: 
  13.  *            pY: YUV422P图像数据Y的起始指针 
  14.  *            pU: YUV422P图像数据U的起始指针 
  15.  *            pV: YUV422P图像数据V的起始指针 
  16.  *        DstPic: 转换成的RGB24图像数据的起始指针 
  17.  *         width: 图像宽度 
  18.  *        height: 图像高度 
  19.  *返回值:成功返回0,失败返回-1 
  20.  *注意:DstPic所指向的缓冲区必须事先分配好,其大小应该为 width*height*3 
  21.  */  
  22. int YUV422P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width, int height);  
 

      实现:

view plaincopy to clipboardprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. //使用整数运算(定点数运算)来代替浮点运算  
  2. const int csY_coeff_16 = 1.164383 * (1 << 16);  
  3. const int csU_blue_16 = 2.017232 * (1 << 16);  
  4. const int csU_green_16 = (-0.391762) * (1 << 16);  
  5. const int csV_green_16 = (-0.812968) * (1 << 16);  
  6. const int csV_red_16 = 1.596027 * (1 << 16);  
  7. //颜色查表  
  8. static BYTE _color_table[256 * 3];  
  9. static const BYTE* color_table = &_color_table[256];  
  10. //查表  
  11. static int Ym_tableEx[256];  
  12. static int Um_blue_tableEx[256];  
  13. static int Um_green_tableEx[256];  
  14. static int Vm_green_tableEx[256];  
  15. static int Vm_red_tableEx[256];  
  16. //颜色饱和函数  
  17. inline long border_color(long color) {  
  18.     if (color > 255)  
  19.         return 255;  
  20.     else if (color < 0)  
  21.         return 0;  
  22.     else  
  23.         return color;  
  24. }  
  25. //采用查找表进行计算时,必须运行的初始化函数  
  26. void YUV422P_To_RGB24_init() {  
  27.     int i;  
  28.     for (i = 0; i < 256 * 3; ++i)  
  29.         _color_table[i] = border_color(i - 256);  
  30.     for (i = 0; i < 256; ++i) {  
  31.         Ym_tableEx[i] = (csY_coeff_16 * (i - 16)) >> 16;  
  32.         Um_blue_tableEx[i] = (csU_blue_16 * (i - 128)) >> 16;  
  33.         Um_green_tableEx[i] = (csU_green_16 * (i - 128)) >> 16;  
  34.         Vm_green_tableEx[i] = (csV_green_16 * (i - 128)) >> 16;  
  35.         Vm_red_tableEx[i] = (csV_red_16 * (i - 128)) >> 16;  
  36.     }  
  37. }  
  38. inline void YUVToRGB24_Table(BYTE *p, const BYTE Y0, const BYTE Y1,  
  39.         const BYTE U, const BYTE V) {  
  40.     int Ye0 = Ym_tableEx[Y0];  
  41.     int Ye1 = Ym_tableEx[Y1];  
  42.     int Ue_blue = Um_blue_tableEx[U];  
  43.     int Ue_green = Um_green_tableEx[U];  
  44.     int Ve_green = Vm_green_tableEx[V];  
  45.     int Ve_red = Vm_red_tableEx[V];  
  46.     int UeVe_green = Ue_green + Ve_green;  
  47.     *p = color_table[(Ye0 + Ve_red)];  
  48.     *(p + 1) = color_table[(Ye0 + UeVe_green)];  
  49.     *(p + 2) = color_table[(Ye0 + Ue_blue)];  
  50.     *(p + 3) = color_table[(Ye1 + Ve_red)];  
  51.     *(p + 4) = color_table[(Ye1 + UeVe_green)];  
  52.     *(p + 5) = color_table[(Ye1 + Ue_blue)];  
  53. }  
  54. int YUV420P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width,  
  55.         int height) {  
  56.     int y, x, x_uv;  
  57.     BYTE* pDstLine = DstPic;  
  58.     if ((width % 2) != 0 || (height % 2) != 0)  
  59.         return (-1);  
  60.     for (y = 0; y < height; ++y) {  
  61.         //DECODE_PlanarYUV211_Common_line(pDstLine, pY, pU, pV,width);  
  62.         for (x = 0; x < width; x += 2) {  
  63.             x_uv = x >> 1;  
  64.             YUVToRGB24_Table(&pDstLine[x * 3], pY[x], pY[x + 1], pU[x_uv],  
  65.                     pV[x_uv]);  
  66.         }  
  67.         pDstLine += width * 3; //RGB888  
  68.         pY += width; //YUV422  
  69.         if (y % 2 == 1) {  
  70.             pU += width / 2;  
  71.             pV += width / 2;  
  72.         }  
  73.     }  
  74.     return 0;  
  75. }  
 

      经测试发现,在hi3512(arm 926ej-s,267MHz)平台上运行时,该yuv转rgb模块的速度不是很快,大概20帧/秒。为了提高效率,核心解码模块我采用了arm汇编,重写了YUVToRGB24_Table模块。

YUV420P_To_RGB24_asm.c代码:

view plaincopy to clipboardprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. extern int YUVToRGB24_Assemble(unsigned char *pDstLine, unsigned char **yuv, int width);  
  2. //使用整数运算(定点数运算)来代替浮点运算  
  3. const int csY_coeff_16 = 1.164383 * (1 << 16);  
  4. const int csU_blue_16 = 2.017232 * (1 << 16);  
  5. const int csU_green_16 = (-0.391762) * (1 << 16);  
  6. const int csV_green_16 = (-0.812968) * (1 << 16);  
  7. const int csV_red_16 = 1.596027 * (1 << 16);  
  8. //查表  
  9. int  Ym_tableEx[256];  
  10. int  Um_blue_tableEx[256];  
  11. int  Um_green_tableEx[256];  
  12. int  Vm_green_tableEx[256];  
  13. int  Vm_red_tableEx[256];  
  14. //采用查找表进行计算时,必须运行的初始化函数  
  15. void YUV422P_To_RGB24_init()  
  16. {  
  17.     int i;  
  18.     for (i = 0; i < 256; ++i)  
  19.     {  
  20.         Ym_tableEx[i]=(csY_coeff_16 * (i - 16) )>>16;  
  21.             Um_blue_tableEx[i]=(csU_blue_16 * (i - 128) )>>16;  
  22.         Um_green_tableEx[i]=(csU_green_16 * (i - 128) )>>16;                    
  23.         Vm_green_tableEx[i]=(csV_green_16 * (i - 128) )>>16;  
  24.             Vm_red_tableEx[i]=(csV_red_16 * (i - 128) )>>16;  
  25.     }  
  26. }  
  27. int YUV420P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width, int height)  
  28. {  
  29.     int y;  
  30.     BYTE* pDstLine = DstPic;  
  31.     BYTE* yuv[3];  
  32.       
  33.     if ((width % 8)!=0)  
  34.         return(-1);  
  35.     yuv[0] = pY;  
  36.     yuv[1] = pU;  
  37.     yuv[2] = pV;  
  38.     for (y = height; y > 0; --y)  
  39.     {  
  40.         YUVToRGB24_Assemble(pDstLine, yuv, width); //decoder a line with asm function in YUVToRGB24_Assemble.s  
  41.         pDstLine += width * 3;      //RGB888  
  42.         yuv[0] += width;        //YUV422  
  43.         if(y % 2 == 1) {  
  44.             yuv[1] += width >> 1;  
  45.             yuv[2] += width >> 1;  
  46.         }  
  47.     }  
  48.     return 0;  
  49. }  
 

arm汇编核心解码模块:

view plaincopy to clipboardprint?
  1. .text  
  2. .macro  loadu a  
  3.     adr r1, UM_BLUE  
  4.     ldr r1, [r1]  
  5.     ldr r9, [r1, \a, lsl #2]  
  6.     adr r1, UM_GREEN  
  7.     ldr r1, [r1]  
  8.     ldr r10, [r1, \a, lsl #2]  
  9. .endm  
  10.       
  11. .macro  loadv a  
  12.     adr r1, VM_RED  
  13.     ldr r1, [r1]  
  14.     ldr r11, [r1, \a, lsl #2]  
  15.     adr r1, VM_GREEN  
  16.     ldr r1, [r1]  
  17.     ldr r12, [r1, \a, lsl #2]     
  18. .endm  
  19. .macro  bound_r0  
  20.     cmp r0, #0x00  
  21.     movlt r0, #0x00  
  22.     cmp r0, #255  
  23.     movgt r0, #255  
  24. .endm  
  25. .globl YUVToRGB24_Assemble  
  26. @ r0 = pDstLine; r1 = yuv; r2 = width  
  27. YUVToRGB24_Assemble:  
  28.     stmdb sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}  
  29.       
  30.     ldmia r1, {r1, r3, r4}      @r1 = y; r3 = u; r4 = v;  
  31.       
  32.     mov r5, #0          @r5 = row counter  
  33. hloop:  
  34.     ldr r6, [r1], #0x04     @load y; 4 bytes  
  35.     ldrh r7, [r3], #0x02        @load u; 2 bytes  
  36.     ldrh r8, [r4], #0x02        @load v; 2 bytes  
  37.       
  38.     stmdb sp!, {r0, r1, r2, r3, r4, r5}  
  39.       
  40.     @   temp register: r0,r1   rgbdata: r2,r3,r4    
  41.     @   ye:r5  ue_blue:r9  ue_green:r10  ve_red:r11   ve_green:r12  
  42.       
  43.     mov r2, #0  
  44.     mov r3, #0  
  45.     mov r4, #0  
  46.       
  47.     @ load ue_bule0, ue_green0  
  48.     mov r0, r7  
  49.     and r0, r0, #0xFF  
  50.     loadu r0  
  51.       
  52.     @load ve_red0, ve_green0  
  53.     mov r0, r8  
  54.     and r0, r0, #0xFF  
  55.     loadv r0  
  56.       
  57.     @load ye0  
  58.     mov r0, r6  
  59.     and r0, r0, #0xFF  
  60.     adr r1, YM  
  61.     ldr r1, [r1]  
  62.     ldr r5, [r1, r0, lsl #2]  
  63.       
  64.     @r0 = ye0+ve_red0  
  65.     add r0, r5, r11  
  66.     bound_r0  
  67.       
  68.     orr r2, r2, r0  
  69.       
  70.     @g0 = ye0+ue_green0+ve_green0  
  71.     adds r0, r10, r12  
  72.     adc r0, r0, r5  
  73.     bound_r0  
  74.       
  75.     orr r2, r2, r0, lsl #8  
  76.       
  77.     @b0 = ye0+ue_blue0  
  78.     add r0, r5, r9  
  79.     bound_r0  
  80.       
  81.     orr r2, r2, r0, lsl #16  
  82.       
  83.     @load ye1  
  84.     mov r0, r6, lsr #8  
  85.     and r0, r0, #0xFF  
  86.     ldr r5, [r1, r0, lsl #2]  
  87.       
  88.     @r1 = ye1+ve_red0  
  89.     add r0, r5, r11  
  90.     bound_r0  
  91.       
  92.     orr r2, r2, r0, lsl #24  
  93.       
  94.     @g1 = ye1+ue_green0+ve_green0  
  95.     adds r0, r10, r12  
  96.     adc r0, r0, r5  
  97.     bound_r0  
  98.       
  99.     orr r3, r3, r0  
  100.       
  101.     @b1 = ye1+ue_blue0  
  102.     add r0, r5, r9  
  103.     bound_r0  
  104.       
  105.     orr r3, r3, r0, lsl #8  
  106.       
  107.     @ load ue_bule1, ue_green1  
  108.     mov r0, r7, lsr #8  
  109.     and r0, r0, #0xFF  
  110.     loadu r0  
  111.       
  112.     @load ve_red1, ve_green1  
  113.     mov r0, r8, lsr #8  
  114.     and r0, r0, #0xFF  
  115.     loadv r0  
  116.       
  117.     @load ye2  
  118.     mov r0, r6, lsr #16  
  119.     and r0, r0, #0xFF  
  120.     adr r1, YM  
  121.     ldr r1, [r1]  
  122.     ldr r5, [r1, r0, lsl #2]  
  123.       
  124.     @r2 = ye2+ve_red1  
  125.     add r0, r5, r11  
  126.     bound_r0  
  127.       
  128.     orr r3, r3, r0, lsl #16  
  129.       
  130.     @g2 = ye2+ue_green1+ve_green1  
  131.     adds r0, r10, r12  
  132.     adc r0, r0, r5  
  133.     bound_r0  
  134.       
  135.     add r3, r3, r0, lsl #24  
  136.       
  137.     @b2 = ye2+ue_blue1  
  138.     add r0, r5, r9  
  139.     bound_r0  
  140.       
  141.     orr r4, r4, r0  
  142.       
  143.     @load ye3  
  144.     mov r0, r6, lsr #24  
  145.     and r0, r0, #0xFF  
  146.     ldr r5, [r1, r0, lsl #2]  
  147.       
  148.     @r3 = ye3+ve_red1  
  149.     add r0, r5, r11  
  150.     bound_r0  
  151.       
  152.     orr r4, r4, r0, lsl #8  
  153.       
  154.     @g3 = ye3+ue_green1+ve_green1  
  155.     adds r0, r10, r12  
  156.     adc r0, r0, r5  
  157.     bound_r0  
  158.       
  159.     orr r4, r4, r0, lsl #16  
  160.       
  161.     @b3 = ye3+ue_blue1  
  162.     add r0, r5, r9  
  163.     bound_r0  
  164.       
  165.     orr r4, r4, r0, lsl #24  
  166.       
  167.     mov r10, r2  
  168.     mov r11, r3  
  169.     mov r12, r4   
  170.       
  171.     ldmia sp!, {r0, r1, r2, r3, r4, r5}  
  172.       
  173.     stmia r0!, {r10, r11, r12}  
  174.           
  175.     add r5, r5, #4  
  176.     cmp r5, r2  
  177.     blo hloop  
  178.     ldmia sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}      @exit  
  179.       
  180. @tables  
  181. YM  : .long Ym_tableEx  
  182. UM_BLUE : .long Um_blue_tableEx  
  183. UM_GREEN: .long Um_green_tableEx  
  184. VM_GREEN: .long Vm_green_tableEx  
  185. VM_RED  : .long Vm_red_tableEx  
 

将核心模块改成汇编后,解码达到了50帧/秒,效率提高了60%,汇编果然强大,哈哈。