YUV(三)-YUV420_to_RGB24 算法


 
算法二较方便
 

算法一:  查表法

const int Table_fv1[256]={ -180, -179, -177, -176, -174, -173, -172, -170, -169, -167, -166, -165, -163, -162, -160, -159, -158, -156, -155, -153, -152, -151, -149, -148, -146, -145, -144, -142, -141, -139, -138, -137, -135, -134, -132, -131, -130, -128, -127, -125, -124, -123, -121, -120, -118, -117, -115, -114, -113, -111, -110, -108, -107, -106, -104, -103, -101, -100, -99, -97, -96, -94, -93, -92, -90, -89, -87, -86, -85, -83, -82, -80, -79, -78, -76, -75, -73, -72, -71, -69, -68, -66, -65, -64, -62, -61, -59, -58, -57, -55, -54, -52, -51, -50, -48, -47, -45, -44, -43, -41, -40, -38, -37, -36, -34, -33, -31, -30, -29, -27, -26, -24, -23, -22, -20, -19, -17, -16, -15, -13, -12, -10, -9, -8, -6, -5, -3, -2, 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 15, 16, 18, 19, 21, 22, 23, 25, 26, 28, 29, 30, 32, 33, 35, 36, 37, 39, 40, 42, 43, 44, 46, 47, 49, 50, 51, 53, 54, 56, 57, 58, 60, 61, 63, 64, 65, 67, 68, 70, 71, 72, 74, 75, 77, 78, 79, 81, 82, 84, 85, 86, 88, 89, 91, 92, 93, 95, 96, 98, 99, 100, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 124, 126, 127, 129, 130, 131, 133, 134, 136, 137, 138, 140, 141, 143, 144, 145, 147, 148, 150, 151, 152, 154, 155, 157, 158, 159, 161, 162, 164, 165, 166, 168, 169, 171, 172, 173, 175, 176, 178 };
const int Table_fv2[256]={ -92, -91, -91, -90, -89, -88, -88, -87, -86, -86, -85, -84, -83, -83, -82, -81, -81, -80, -79, -78, -78, -77, -76, -76, -75, -74, -73, -73, -72, -71, -71, -70, -69, -68, -68, -67, -66, -66, -65, -64, -63, -63, -62, -61, -61, -60, -59, -58, -58, -57, -56, -56, -55, -54, -53, -53, -52, -51, -51, -50, -49, -48, -48, -47, -46, -46, -45, -44, -43, -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35, -34, -33, -33, -32, -31, -31, -30, -29, -28, -28, -27, -26, -26, -25, -24, -23, -23, -22, -21, -21, -20, -19, -18, -18, -17, -16, -16, -15, -14, -13, -13, -12, -11, -11, -10, -9, -8, -8, -7, -6, -6, -5, -4, -3, -3, -2, -1, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 40, 41, 42, 42, 43, 44, 45, 45, 46, 47, 47, 48, 49, 50, 50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 62, 63, 64, 65, 65, 66, 67, 67, 68, 69, 70, 70, 71, 72, 72, 73, 74, 75, 75, 76, 77, 77, 78, 79, 80, 80, 81, 82, 82, 83, 84, 85, 85, 86, 87, 87, 88, 89, 90, 90 };
 
 
const int Table_fu1[256]={ -44, -44, -44, -43, -43, -43, -42, -42, -42, -41, -41, -41, -40, -40, -40, -39, -39, -39, -38, -38, -38, -37, -37, -37, -36, -36, -36, -35, -35, -35, -34, -34, -33, -33, -33, -32, -32, -32, -31, -31, -31, -30, -30, -30, -29, -29, -29, -28, -28, -28, -27, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24, -24, -23, -23, -22, -22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18, -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -11, -11, -11, -10, -10, -10, -9, -9, -9, -8, -8, -8, -7, -7, -7, -6, -6, -6, -5, -5, -5, -4, -4, -4, -3, -3, -3, -2, -2, -2, -1, -1, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43 };
 
 
const int Table_fu2[256]={ -227, -226, -224, -222, -220, -219, -217, -215, -213, -212, -210, -208, -206, -204, -203, -201, -199, -197, -196, -194, -192, -190, -188, -187, -185, -183, -181, -180, -178, -176, -174, -173, -171, -169, -167, -165, -164, -162, -160, -158, -157, -155, -153, -151, -149, -148, -146, -144, -142, -141, -139, -137, -135, -134, -132, -130, -128, -126, -125, -123, -121, -119, -118, -116, -114, -112, -110, -109, -107, -105, -103, -102, -100, -98, -96, -94, -93, -91, -89, -87, -86, -84, -82, -80, -79, -77, -75, -73, -71, -70, -68, -66, -64, -63, -61, -59, -57, -55, -54, -52, -50, -48, -47, -45, -43, -41, -40, -38, -36, -34, -32, -31, -29, -27, -25, -24, -22, -20, -18, -16, -15, -13, -11, -9, -8, -6, -4, -2, 0, 1, 3, 5, 7, 8, 10, 12, 14, 15, 17, 19, 21, 23, 24, 26, 28, 30, 31, 33, 35, 37, 39, 40, 42, 44, 46, 47, 49, 51, 53, 54, 56, 58, 60, 62, 63, 65, 67, 69, 70, 72, 74, 76, 78, 79, 81, 83, 85, 86, 88, 90, 92, 93, 95, 97, 99, 101, 102, 104, 106, 108, 109, 111, 113, 115, 117, 118, 120, 122, 124, 125, 127, 129, 131, 133, 134, 136, 138, 140, 141, 143, 145, 147, 148, 150, 152, 154, 156, 157, 159, 161, 163, 164, 166, 168, 170, 172, 173, 175, 177, 179, 180, 182, 184, 186, 187, 189, 191, 193, 195, 196, 198, 200, 202, 203, 205, 207, 209, 211, 212, 214, 216, 218, 219, 221, 223, 225 };
  
#define WIDTH 176
#define HEIGHT 144
#define PIXELSIZE WIDTH*HEIGHT
static void YV12_to_RGB24(unsigned char * pYV0, unsigned char * pYV1,
         unsigned char * pYV2,unsigned char * pRGB24)
{
  if (!pYV0 || !pRGB24)
   return  
  const long nYLen = long (PIXELSIZE);
  const int nHfWidth = (WIDTH>>1);
   
  if (nYLen<1 || nHfWidth<1)
   return ;
  // Y data
  unsigned char * yData = pYV0;
  // v data
  unsigned char * vData = pYV1;
  // u data
  unsigned char * uData = pYV2;
  if (!uData || !vData)
   return   
  int rgb[3];
  int i, j, m, n, x, y, pu, pv, py, rdif, invgdif, bdif;
  m = -WIDTH;
  n = -nHfWidth;
  bool addhalf = true ;
  for (y=0; y
 {
    m += WIDTH;
   if ( addhalf ){
    n+=nHfWidth;
    addhalf = false ;
   } else {
    addhalf = true ;
   }
   for (x=0; x
    i = m + x;
    j = n + (x>>1);
     
    py = yData[i];
     
    // search tables to get rdif invgdif and bidif
    rdif = Table_fv1[vData[j]];    // fv1
    invgdif = Table_fu1[uData[j]] + Table_fv2[vData[j]]; // fu1+fv2
    bdif = Table_fu2[uData[j]]; // fu2
     
     rgb[0] = py+rdif;    // R
     rgb[1] = py-invgdif; // G
     rgb[2] = py+bdif;    // B 
  
    j = nYLen - WIDTH - m + x;
    i = (j<<1) + j;
     
    // copy this pixel to rgb data
    for (j=0; j<3; j++)
    {
     if (rgb[j]>=0 && rgb[j]<=255){
      pRGB24[i + j] = rgb[j];
     }
     else {
      pRGB24[i + j] = (rgb[j] < 0)? 0 : 255;
     }
    }
   }
  }
}

 

算法二: cscc.lib

void YV12_to_RGB24(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori,int width,int height);

在很多进行yuv与rgb图像格式转换的程序中都使用了cscc.lib这个库.

 

算法三: asm

typedef      UCHAR        uint8_t;
typedef      ULONGLONG      uint64_t;
  
#define MAXIMUM_Y_WIDTH 1280
static uint64_t mmw_mult_Y     = 0x2568256825682568;
static uint64_t mmw_mult_U_G   = 0xf36ef36ef36ef36e;
static uint64_t mmw_mult_U_B   = 0x40cf40cf40cf40cf;
static uint64_t mmw_mult_V_R   = 0x3343334333433343;
static uint64_t mmw_mult_V_G   = 0xe5e2e5e2e5e2e5e2;
static uint64_t mmb_0x10       = 0x1010101010101010;
static uint64_t mmw_0x0080     = 0x0080008000800080;
static uint64_t mmw_0x00ff     = 0x00ff00ff00ff00ff;
static uint64_t mmw_cut_red    = 0x7c007c007c007c00;
static uint64_t mmw_cut_green = 0x03e003e003e003e0;
static uint64_t mmw_cut_blue   = 0x001f001f001f001f;
  
static void YUV_TO_RGB24(uint8_t *puc_y, int stride_y, 
        uint8_t *puc_u, uint8_t *puc_v, int stride_uv, 
        uint8_t *puc_out, int width_y, int height_y, int stride_out) 
{
   int y, horiz_count;
   uint8_t *puc_out_remembered;
//int stride_out = width_y * 3;
      
   if (height_y < 0) {
       //we are flipping our output upside-down
       height_y   = -height_y;
       puc_y      += (height_y    - 1) * stride_y ;
       puc_u      += (height_y/2 - 1) * stride_uv;
       puc_v      += (height_y/2 - 1) * stride_uv;
       stride_y   = -stride_y;
       stride_uv = -stride_uv;
   }
   horiz_count = -(width_y >> 3);
   for (y=0; y
   if (y == height_y-1) {
     //this is the last output line - we need to be careful not to overrun the end of this line
     uint8_t temp_buff[3*MAXIMUM_Y_WIDTH+1];
     puc_out_remembered = puc_out;
     puc_out = temp_buff; //write the RGB to a temporary store
    }
    _asm {
     push eax
     push ebx
     push ecx
     push edx
     push edi
     mov eax, puc_out       
     mov ebx, puc_y       
     mov ecx, puc_u       
     mov edx, puc_v
     mov edi, horiz_count
     horiz_loop:
     movd mm2, [ecx]
     pxor mm7, mm7
     movd mm3, [edx]
     punpcklbw mm2, mm7       
     movq mm0, [ebx]          
     punpcklbw mm3, mm7       
     movq mm1, mmw_0x00ff     
     psubusb mm0, mmb_0x10    
     psubw mm2, mmw_0x0080    
     pand mm1, mm0            
     psubw mm3, mmw_0x0080    
     psllw mm1, 3             
     psrlw mm0, 8             
     psllw mm2, 3             
     pmulhw mm1, mmw_mult_Y   
     psllw mm0, 3             
     psllw mm3, 3             
     movq mm5, mm3            
     pmulhw mm5, mmw_mult_V_R 
     movq mm4, mm2            
     pmulhw mm0, mmw_mult_Y   
     movq mm7, mm1            
     pmulhw mm2, mmw_mult_U_G 
     paddsw mm7, mm5
     pmulhw mm3, mmw_mult_V_G
     packuswb mm7, mm7
     pmulhw mm4, mmw_mult_U_B
     paddsw mm5, mm0      
     packuswb mm5, mm5
     paddsw mm2, mm3          
     movq mm3, mm1            
     movq mm6, mm1            
     paddsw mm3, mm4
     paddsw mm6, mm2
     punpcklbw mm7, mm5
     paddsw mm2, mm0
     packuswb mm6, mm6
     packuswb mm2, mm2
     packuswb mm3, mm3
     paddsw mm4, mm0
     packuswb mm4, mm4
     punpcklbw mm6, mm2
     punpcklbw mm3, mm4
     // 32-bit shuffle.
     pxor mm0, mm0
     movq mm1, mm6
     punpcklbw mm1, mm0
     movq mm0, mm3
     punpcklbw mm0, mm7
     movq mm2, mm0
     punpcklbw mm0, mm1
     punpckhbw mm2, mm1
     // 24-bit shuffle and sav
     movd    [eax], mm0
     psrlq mm0, 32
     movd   3[eax], mm0
     movd   6[eax], mm2
      
     psrlq mm2, 32            
     movd   9[eax], mm2        
     // 32-bit shuffle.
     pxor mm0, mm0            
     movq mm1, mm6            
     punpckhbw mm1, mm0       
     movq mm0, mm3            
     punpckhbw mm0, mm7       
     movq mm2, mm0            
     punpcklbw mm0, mm1       
     punpckhbw mm2, mm1       
     // 24-bit shuffle and sav
     movd 12[eax], mm0        
     psrlq mm0, 32            
     movd 15[eax], mm0        
     add ebx, 8               
     movd 18[eax], mm2        
     psrlq mm2, 32            
     add ecx, 4               
     add edx, 4               
     movd 21[eax], mm2        
     add eax, 24              
     inc edi
     jne horiz_loop
     pop edi
     pop edx
     pop ecx
     pop ebx
     pop eax
     emms
    }
    if (y == height_y-1) {
     //last line of output - we have used the temp_buff and need to copy
     int x = 3 * width_y;                   //interation counter
     uint8_t *ps = puc_out;                 // source pointer (temporary line store)
     uint8_t *pd = puc_out_remembered;      // dest pointer
     while (x--) *(pd++) = *(ps++);           // copy the line
      puc_y    += stride_y;
    if (y%2) {
     puc_u    += stride_uv;
     puc_v    += stride_uv;
    }
    puc_out += stride_out; 
}
}

 

算法四: 数组.

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
long int crv_tab[256];
long int cbu_tab[256];
long int cgu_tab[256];
long int cgv_tab[256];
long int tab_76309[256];
unsigned char clp[1024];   
init_dither_tab()
{
     long int crv,cbu,cgu,cgv;
     int i,ind;
      
     crv = 104597; cbu = 132201; 
     cgu = 25675;  cgv = 53279;
      
     for (i = 0; i < 256; i++) {
         crv_tab[i] = (i-128) * crv;
         cbu_tab[i] = (i-128) * cbu;
         cgu_tab[i] = (i-128) * cgu;
         cgv_tab[i] = (i-128) * cgv;
         tab_76309[i] = 76309*(i-16);
     }
      
     for (i=0; i<384; i++)
         clp[i] =0;
     ind=384;
     for (i=0;i<256; i++)
         clp[ind++]=i;
     ind=640;
     for (i=0;i<384;i++)
     clp[ind++]=255;
}
  
YUV2RGB420(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori, int width, int height)
{
     int y1,y2,u,v; 
     unsigned char *py1,*py2;
     int i,j, c1, c2, c3, c4;
     unsigned char *d1, *d2;
      
     py1=src0;
     py2=py1+width;
     d1=dst_ori;
     d2=d1+3*width;
     for (j = 0; j < height; j += 2)
         for (i = 0; i < width; i += 2) {
              
             u = *src1++;
             v = *src2++;
              
             c1 = crv_tab[v];
             c2 = cgu_tab[u];
             c3 = cgv_tab[v];
             c4 = cbu_tab[u];
              
             //up-left
             y1 = tab_76309[*py1++];    
             *d1++ = clp[384+((y1 + c1)>>16)];  
             *d1++ = clp[384+((y1 - c2 - c3)>>16)];
             *d1++ = clp[384+((y1 + c4)>>16)];
              
             //down-left
             y2 = tab_76309[*py2++];
             *d2++ = clp[384+((y2 + c1)>>16)];  
             *d2++ = clp[384+((y2 - c2 - c3)>>16)];
             *d2++ = clp[384+((y2 + c4)>>16)];
              
             //up-right
             y1 = tab_76309[*py1++];
             *d1++ = clp[384+((y1 + c1)>>16)];  
             *d1++ = clp[384+((y1 - c2 - c3)>>16)];
             *d1++ = clp[384+((y1 + c4)>>16)];
              
             //down-right
             y2 = tab_76309[*py2++];
             *d2++ = clp[384+((y2 + c1)>>16)];  
             *d2++ = clp[384+((y2 - c2 - c3)>>16)];
             *d2++ = clp[384+((y2 + c4)>>16)];          
          }
         d1 += 3*width;
         d2 += 3*width;
         py1+=   width;
         py2+=   width;
         }
}

 

算法五: ffmpeg 中的swscale函数

 

这几个算法都实验了一下, 前4种算法在低分辨率的情况下都可以正常显示, 在解1280*720的视频时雪花点点, 只能采用第五种算法,

第五种的话可能比较麻烦一点, 涉及开源的ffmpeg.

cscc.lib源文件和头文件声明下载看这里:http://files.cnblogs.com/doorsky/cscc.lib.rar

ffmepg源码实例看这里:http://files.cnblogs.com/doorsky/ffmepg_H.264.rar

SDLDemo下载看这里:http://files.cnblogs.com/doorsky/SDLDemo.rar

更多ffmepg的相关资料参阅: http://www.bairuitech.com/html/ruanjianxiazai/index.html

中华视频网论坛: http://bbs.chinavideo.org/index.php

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值