YUV轉RGB

http://www.cnblogs.com/doorsky/archive/2011/01/02/1924253.html

算法一:  查表法

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<HEIGHT;y++) {
  m += WIDTH;
  if( addhalf ){
   n+=nHfWidth;
   addhalf = false;
  } else {
   addhalf = true;
  }
  for(x=0; x<WIDTH;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<height_y; 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;
}
}

 

算法四: 數組.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章