MythTV  0.26-pre
util-osd.cpp
Go to the documentation of this file.
00001 #include "util-osd.h"
00002 #include "dithertable.h"
00003 
00004 #if HAVE_BIGENDIAN
00005 #define R_OI  1
00006 #define G_OI  2
00007 #define B_OI  3
00008 #define A_OI  0
00009 #else
00010 #define R_OI  2
00011 #define G_OI  1
00012 #define B_OI  0
00013 #define A_OI  3
00014 #endif
00015 
00016 void yuv888_to_yv12(VideoFrame *frame, MythImage *osd_image,
00017                     int left, int top, int right, int bottom)
00018 {
00019     bool c_aligned  = !(left % ALIGN_C || right % ALIGN_C);
00020     bool misaligned = (top % ALIGN_C || bottom % ALIGN_C) || !c_aligned;
00021     bool mmx_aligned = false;
00022 #ifdef MMX
00023     mmx_aligned = !(left % ALIGN_X_MMX || right % ALIGN_X_MMX);
00024 #endif
00025 
00026     if (misaligned)
00027     {
00028         LOG(VB_GENERAL, LOG_ERR,
00029             QString("OSD image size is odd. This shouldn't happen."));
00030     }
00031     else if (mmx_aligned)
00032     {
00033         mmx_yuv888_to_yv12(frame, osd_image, left, top, right, bottom);
00034     }
00035     else if (c_aligned)
00036     {
00037 #ifdef MMX
00038         LOG(VB_GENERAL, LOG_WARNING, "MMX available but image not MMX aligned. "
00039                                      "This shouldn't happen.");
00040 #endif
00041         c_yuv888_to_yv12(frame, osd_image, left, top, right, bottom);
00042     }
00043 }
00044 
00045 #define ASM(code) __asm__ __volatile__(code);
00046 void inline mmx_yuv888_to_yv12(VideoFrame *frame, MythImage *osd_image,
00047                                int left, int top, int right, int bottom)
00048 {
00049 #ifdef MMX
00050     unsigned char *src1, *src2, *y1, *y2, *u, *v;
00051     int y_wrap, src_wrap, u_wrap, v_wrap, width, height;
00052 
00053     width  = right - left;
00054     height = bottom - top;
00055     src1 = osd_image->scanLine(top) + (left << 2);
00056     src2 = src1 + osd_image->bytesPerLine();
00057     src_wrap = (osd_image->bytesPerLine() << 1)- (width << 2);
00058 
00059     y1 = frame->buf + frame->offsets[0] + (frame->pitches[0] * top) + left;
00060     y2 = y1 + frame->pitches[0];
00061     u  = frame->buf + frame->offsets[1] +
00062         (frame->pitches[1] * (top >> 1)) + (left >> 1);
00063     v  = frame->buf + frame->offsets[2] +
00064         (frame->pitches[2] * (top >> 1)) + (left >> 1);
00065     y_wrap = (frame->pitches[0] << 1) - width;
00066     u_wrap = frame->pitches[1] - (width >> 1);
00067     v_wrap = frame->pitches[2] - (width >> 1);
00068 
00069     static long long MMX_MAX = 0xFFFFFFFFFFFFFFFFLL;
00070     static long long MMX_MIN = 0x0000000000000000LL;
00071     static long long MMX_255 = 0x00FF00FF00FF00FFLL;
00072     static long long tmp_u, tmp_v, tmp_a;
00073 
00074     for (int row = 0; row < height; row += 2)
00075     {
00076         for (int col = 0; col < (width >> 3); col++)
00077         {
00078             // here be pain
00079             // unpack and luminance - row 1                                     01234567
00080             ASM("movq %0, %%mm1"::"m"(src1[0]))       // mm1: A2Y2U2V2 A1Y1U1V1 .t......
00081             ASM("movq %mm1, %mm2")                    // mm2: A2Y2U2V2 A1Y1U1V1 .tt.....
00082             ASM("punpckhbw %0, %%mm1"::"m"(src1[8]))  // mm1: A4A2Y4Y2 U4U2V4V2 .tt.....
00083             ASM("punpcklbw %0, %%mm2"::"m"(src1[8]))  // mm2: A3A1Y3Y1 U3U1V3V1 .tt.....
00084             ASM("movq %mm2, %mm0")                    // mm0: A3A1Y3Y1 U3U1V3V1 ttt.....
00085             ASM("punpckhbw %mm1, %mm2")               // mm2: A4A3A2A1 Y4Y3Y2Y1 .tA..... AY stage 1
00086             ASM("punpcklbw %mm1, %mm0")               // mm0: U4U3U2U1 V4V3V2V1 U.A..... UV stage 1
00087             ASM("movq %0, %%mm3"::"m"(src1[16]))      // mm3: A6Y6U6V6 A5Y5U5V5 U.At....
00088             ASM("movq %mm3, %mm4")                    // mm4: A6Y6U6V6 A5YU55V5 U.Att...
00089             ASM("punpckhbw %0, %%mm3"::"m"(src1[24])) // mm3: A8A6Y8Y6 U8U6V8V6 U.Att...
00090             ASM("punpcklbw %0, %%mm4"::"m"(src1[24])) // mm4: A7A5Y7Y5 U7U5V7V5 U.Att...
00091             ASM("movq %mm4, %mm1")                    // mm1: A7A5Y7Y5 U7U5V7V5 UtAtt...
00092             ASM("punpckhbw %mm3, %mm1")               // mm1: A8A7A6A5 Y8Y7Y6Y5 UtAtt... AY stage 2
00093             ASM("punpcklbw %mm3, %mm4")               // mm4: U8U7U6U5 V8V7V6V5 UtA.V... UV stage 2
00094             ASM("movq %mm2, %mm3")                    // mm3: A4A3A2A1 Y4Y3Y2Y1 UtAtV...
00095             ASM("punpckldq %mm1, %mm3")               // mm3: Y8Y7Y6Y5 Y4Y3Y2Y1 UtAYV... 8-1 Y
00096             ASM("punpckhdq %mm1, %mm2")               // mm2: A8A7A6A5 A4A3A2A1 UtAYV... 8-1 A
00097             ASM("movq %0, %%mm7"::"m"(MMX_MAX))       // mm7: FFFFFFFF FFFFFFFF U.AYV..t 255
00098             ASM("psubusb %mm2, %mm7")                 // mm7: A8A7A6A5 A4A3A2A1 U.AYV..t 8-1 (255-a)
00099             ASM("movq %mm7, %mm6")                    // mm6: A8A7A6A5 A4A3A2A1 U.AYV.tt 8-1 (255-a)
00100             ASM("movq %mm7, %mm2")                    // mm2: A8A7A6A5 A4A3A2A1 U.AYV.tt 8-1 (255-a)
00101             ASM("punpckhbw %0, %%mm7"::"m"(MMX_MIN))  // mm7: 00A800A7 00A600A4 U.AYV.tt 8-5 (255-a)
00102             ASM("punpcklbw %0, %%mm6"::"m"(MMX_MIN))  // mm6: 00A400A3 00A200A1 U.AYV.tt 4-1 (255-a)
00103             ASM("movq %0, %%mm5"::"m"(*y1))           // mm5: D8D7D6D5 D4D3D2D1 U.AYVttt 8-1 dest
00104             ASM("movq %mm5, %mm1")                    // mm1: D8D7D6D5 D4D3D2D1 UtAYVttt
00105             ASM("punpckhbw %0, %%mm5"::"m"(MMX_MIN))  // mm5: 00D800D7 00D600D5 UtAYVttt
00106             ASM("punpcklbw %0, %%mm1"::"m"(MMX_MIN))  // mm1: 00D400D3 00D200D1 UtAYVttt
00107             ASM("pmullw %mm7, %mm5")                  // mm5: D8D8D7D7 D6D6D5D5 UtAYVttt 8-5 dest*(255-a)
00108             ASM("pmullw %mm6, %mm1")                  // mm1: D4D4D3D3 D2D2D1D1 UtAYVtt. 4-1 dest*(255-a)
00109             ASM("psrlw $8, %mm5")                     // mm5: 00D800D7 00D600D5 UtAYVt.. 8-5 (dest*(255-a))/256
00110             ASM("psrlw $8, %mm1")                     // mm1: 00D400D3 00D200D1 UtAYVt.. 4-1 (dest*(255-a))/256
00111             ASM("packuswb %mm5, %mm1")                // mm1: D8D7D6D5 D4D3D2D1 UtAYV... 8-1 (dest*(255-a))/256
00112             ASM("paddusb %mm1, %mm3")                 // mm3: D8D7D6D5 D4D3D2D1 U.AYV... 8-1 (dest*(255-a))/256+y
00113             ASM("movq %%mm3, %0":"=m"(*y1):)          //                        U.A.V... row 1 y
00114             ASM("movq %mm0, %mm1")                    // mm1: U4U3U2U1 V4V3V2V1 uuA.v...
00115             ASM("punpckhdq %mm4, %mm0")               // mm0: U8U7U6U5 U4U3U2U1 UuA.v... 8-1 u
00116             ASM("punpckldq %mm4, %mm1")               // mm1: V8V7V6V5 V4V3V2V1 UVA..... 9-1 v
00117             // store u,v and for sub-sampling
00118             ASM("movq %%mm0, %0":"=m"(tmp_u):)
00119             ASM("movq %%mm1, %0":"=m"(tmp_v):)
00120             ASM("movq %%mm2, %0":"=m"(tmp_a):)
00121             // unpack and luminance - row 2
00122             ASM("movq %0, %%mm1"::"m"(src2[0]))       // mm1: A2Y2U2V2 A1Y1U1V1 .t......
00123             ASM("movq %mm1, %mm2")                    // mm2: A2Y2U2V2 A1Y1U1V1 .tt.....
00124             ASM("punpckhbw %0, %%mm1"::"m"(src2[8]))  // mm1: A4A2Y4Y2 U4U2V4V2 .tt.....
00125             ASM("punpcklbw %0, %%mm2"::"m"(src2[8]))  // mm2: A3A1Y3Y1 U3U1V3V1 .tt.....
00126             ASM("movq %mm2, %mm0")                    // mm0: A3A1Y3Y1 U3U1V3V1 ttt.....
00127             ASM("punpckhbw %mm1, %mm2")               // mm2: A4A3A2A1 Y4Y3Y2Y1 .tA..... AY stage 1
00128             ASM("punpcklbw %mm1, %mm0")               // mm0: U4U3U2U1 V4V3V2V1 U.A..... UV stage 1
00129             ASM("movq %0, %%mm3"::"m"(src2[16]))      // mm3: A6Y6U6V6 A5Y5U5V5 U.At....
00130             ASM("movq %mm3, %mm4")                    // mm4: A6Y6U6V6 A5YU55V5 U.Att...
00131             ASM("punpckhbw %0, %%mm3"::"m"(src2[24])) // mm3: A8A6Y8Y6 U8U6V8V6 U.Att...
00132             ASM("punpcklbw %0, %%mm4"::"m"(src2[24])) // mm4: A7A5Y7Y5 U7U5V7V5 U.Att...
00133             ASM("movq %mm4, %mm1")                    // mm1: A7A5Y7Y5 U7U5V7V5 UtAtt...
00134             ASM("punpckhbw %mm3, %mm1")               // mm1: A8A7A6A5 Y8Y7Y6Y5 UtAtt... AY stage 2
00135             ASM("punpcklbw %mm3, %mm4")               // mm4: U8U7U6U5 V8V7V6V5 UtA.V... UV stage 2
00136             ASM("movq %mm2, %mm3")                    // mm3: A4A3A2A1 Y4Y3Y2Y1 UtAtV...
00137             ASM("punpckldq %mm1, %mm3")               // mm3: Y8Y7Y6Y5 Y4Y3Y2Y1 UtAYV... 8-1 Y
00138             ASM("punpckhdq %mm1, %mm2")               // mm2: A8A7A6A5 A4A3A2A1 UtAYV... 8-1 A
00139             ASM("movq %0, %%mm7"::"m"(MMX_MAX))       // mm7: FFFFFFFF FFFFFFFF U.AYV..t 255
00140             ASM("psubusb %mm2, %mm7")                 // mm7: A8A7A6A5 A4A3A2A1 U.AYV..t 8-1 (255-a)
00141             ASM("movq %mm7, %mm6")                    // mm6: A8A7A6A5 A4A3A2A1 U.AYV.tt 8-1 (255-a)
00142             ASM("movq %mm7, %mm2")                    // mm2: A8A7A6A5 A4A3A2A1 U.AYV.tt 8-1 (255-a)
00143             ASM("punpckhbw %0, %%mm7"::"m"(MMX_MIN))  // mm7: 00A800A7 00A600A4 U.AYV.tt 8-5 (255-a)
00144             ASM("punpcklbw %0, %%mm6"::"m"(MMX_MIN))  // mm6: 00A400A3 00A200A1 U.AYV.tt 4-1 (255-a)
00145             ASM("movq %0, %%mm5"::"m"(*y2))           // mm5: D8D7D6D5 D4D3D2D1 U.AYVttt 8-1 dest
00146             ASM("movq %mm5, %mm1")                    // mm1: D8D7D6D5 D4D3D2D1 UtAYVttt
00147             ASM("punpckhbw %0, %%mm5"::"m"(MMX_MIN))  // mm5: 00D800D7 00D600D5 UtAYVttt
00148             ASM("punpcklbw %0, %%mm1"::"m"(MMX_MIN))  // mm1: 00D400D3 00D200D1 UtAYVttt
00149             ASM("pmullw %mm7, %mm5")                  // mm5: D8D8D7D7 D6D6D5D5 UtAYVttt 8-5 dest*(255-a)
00150             ASM("pmullw %mm6, %mm1")                  // mm1: D4D4D3D3 D2D2D1D1 UtAYVtt. 4-1 dest*(255-a)
00151             ASM("psrlw $8, %mm5")                     // mm5: 00D800D7 00D600D5 UtAYVt.. 8-5 (dest*(255-a))/256
00152             ASM("psrlw $8, %mm1")                     // mm1: 00D400D3 00D200D1 UtAYVt.. 4-1 (dest*(255-a))/256
00153             ASM("packuswb %mm5, %mm1")                // mm1: D8D7D6D5 D4D3D2D1 UtAYV... 8-1 (dest*(255-a))/256
00154             ASM("paddusb %mm1, %mm3")                 // mm3: D8D7D6D5 D4D3D2D1 U.AYV... 8-1 (dest*(255-a))/256+y
00155             ASM("movq %%mm3, %0":"=m"(*y2):)          //                        U.A.V... row 1 y
00156             ASM("movq %mm0, %mm1")                    // mm1: U4U3U2U1 V4V3V2V1 uuA.v...
00157             ASM("punpckhdq %mm4, %mm0")               // mm0: U8U7U6U5 U4U3U2U1 UuA.v... 8-1 u
00158             ASM("punpckldq %mm4, %mm1")               // mm1: V8V7V6V5 V4V3V2V1 UVA..... 9-1 v
00159             // subsample alpha
00160             ASM("movq %mm2, %mm3")                    // mm3: A8A7A6A5 A4A3A2A1 UVAA.... copy row 2 a
00161             ASM("movq %0, %%mm4"::"m"(tmp_a))         // mm4: A8A7A6A5 A4A3A2A1 UVAA.... row 1 a
00162             ASM("movq %mm4, %mm5")                    // mm5: A8A7A6A5 A4A3A2A1 UVAAAA.. copy row 1 a
00163             ASM("psrlw $8, %mm2")                     // mm2: 00A800A6 00A400A2 UVAAAA.. row 2
00164             ASM("pand %0, %%mm3"::"m"(MMX_255))       // mm3: 00A700A5 00A300A1 UVAAAA.. row 2
00165             ASM("psrlw $8, %mm4")                     // mm4: 00A800A6 00A400A2 UVAAAA.. row 1
00166             ASM("pand %0, %%mm5"::"m"(MMX_255))       // mm5: 00A700A5 00A300A1 UVAAAA.. row 1
00167             ASM("paddusw %mm5, %mm4")                 // add
00168             ASM("paddusw %mm4, %mm3")
00169             ASM("paddusw %mm3, %mm2")
00170             ASM("psrlw $2, %mm2")                     // mm2: xxA4xxA3 xxA2xxA1 UVA..... /4
00171             ASM("pand %0, %%mm2"::"m"(MMX_255))       // mm2: 00A400A3 00A200A1 UVA.....
00172             // subsample u
00173             ASM("movq %mm0, %mm3")                    // mm3: U8U7U6U5 U4U3U2U1 UVAU.... copy row 2 u
00174             ASM("movq %0, %%mm4"::"m"(tmp_u))         // mm4: U8U7U6U5 U4U3U2U1 UVAUU... row 1 u
00175             ASM("movq %mm4, %mm5")                    // mm5: U8U7U6U5 U4U3U2U1 UVAUUU.. copy row 1 u
00176             ASM("psrlw $8, %mm0")                     // mm0: 00U800U6 00U400U2 UVAUUU.. row 2
00177             ASM("pand %0, %%mm3"::"m"(MMX_255))       // mm3: 00U700U5 00U300U1 UVAUUU.. row 2
00178             ASM("psrlw $8, %mm4")                     // mm4: 00U800U6 00U400U2 UVAUUU.. row 1
00179             ASM("pand %0, %%mm5"::"m"(MMX_255))       // mm5: 00U700U5 00U300U1 UVAUUU.. row 1
00180             ASM("paddusw %mm5, %mm4")                 // add
00181             ASM("paddusw %mm4, %mm3")
00182             ASM("paddusw %mm3, %mm0")
00183             ASM("psrlw $2, %mm0")                     // mm0: xxU4xxU3 xxU2xxU1 UVA..... /4
00184             ASM("pand %0, %%mm0"::"m"(MMX_255))       // mm0: 00U400U3 00U200U1 UVA.....
00185             // blend u
00186             ASM("movd %0, %%mm3"::"m"(*u))            // mm3: 00000000 D4D3D2D1 UVAt.... 4-1 dest u
00187             ASM("punpcklbw %0, %%mm3"::"m"(MMX_MIN))  // mm3: 00D400D3 00D200D1 UVAt.... 4-1 dest u
00188             ASM("pmullw %mm2, %mm3")                  // mm3: 00D400D3 00D200D1 UVAt.... destu * (255-a)
00189             ASM("psrlw $8, %mm3")                     // mm3: 00D400D3 00D200D1 UVAt.... (destu*(255-a))/256
00190             ASM("paddusb %mm3, %mm0")                 // mm0: xxR4xxR3 xxR2xxR1 UVA..... (destu*(255-a))/256 + u
00191             ASM("packuswb %mm1, %mm0")                // mm0: xxxxxxxx U4U3U2U1 UVA..... (destu*(255-a))/256 + u
00192             ASM("movd %%mm0, %0":"=m"(*u):)           // output                 .VA.....
00193             // subsample v
00194             ASM("movq %mm1, %mm3")                    // mm3: U8U7U6U5 U4U3U2U1 .VAV.... copy row 2 v
00195             ASM("movq %0, %%mm4"::"m"(tmp_v))         // mm4: U8U7U6U5 U4U3U2U1 .VAVV... row 1 v
00196             ASM("movq %mm4, %mm5")                    // mm5: U8U7U6U5 U4U3U2U1 .VAVVV.. copy row 1 v
00197             ASM("psrlw $8, %mm1")                     // mm1: 00U800U6 00U400U2 .VAVVV.. row 2
00198             ASM("pand %0, %%mm3"::"m"(MMX_255))       // mm3: 00U700U5 00U300U1 .VAVVV.. row 2
00199             ASM("psrlw $8, %mm4")                     // mm4: 00U800U6 00U400U2 .VAVVV.. row 1
00200             ASM("pand %0, %%mm5"::"m"(MMX_255))       // mm5: 00U700U5 00U300U1 .VAVVV.. row 1
00201             ASM("paddusw %mm5, %mm4")                 // add
00202             ASM("paddusw %mm4, %mm3")
00203             ASM("paddusw %mm3, %mm1")
00204             ASM("psrlw $2, %mm1")                     // mm1: xxU4xxU3 xxU2xxU1 .VA..... /4
00205             ASM("pand %0, %%mm1"::"m"(MMX_255))       // mm1: 00U400U3 00U200U1 .VA.....
00206             // blend v
00207             ASM("movd %0, %%mm3"::"m"(*v))            // mm3: 00000000 D4D3D2D1 .VAt.... 4-1 dest v
00208             ASM("punpcklbw %0, %%mm3"::"m"(MMX_MIN))  // mm3: 00D400D3 00D200D1 .VAt.... 4-1 dest v
00209             ASM("pmullw %mm2, %mm3")                  // mm3: 00D400D3 00D200D1 .V.t.... destv * (255-a)
00210             ASM("psrlw $8, %mm3")                     // mm3: 00D400D3 00D200D1 .V.t.... (destv*(255-a))/256
00211             ASM("paddusb %mm3, %mm1")                 // mm1: xxR4xxR3 xxR2xxR1 .V...... (destv*(255-a))/256 + v
00212             ASM("packuswb %mm2, %mm1")                // mm1: xxxxxxxx V4V3V2V1 .V...... (destv*(255-a))/256 + v
00213             ASM("movd %%mm1, %0":"=m"(*v):)           // output                 ........
00214 
00215             src1 += 32; src2 += 32; y1 += 8; y2 += 8; u += 4; v += 4;
00216         }
00217         y1 += y_wrap; y2 += y_wrap; u+= u_wrap; v += v_wrap;
00218         src1 += src_wrap; src2 += src_wrap;
00219     }
00220     ASM("emms")
00221 #endif
00222 }
00223 
00224 void inline c_yuv888_to_yv12(VideoFrame *frame, MythImage *osd_image,
00225                              int left, int top, int right, int bottom)
00226 {
00227     unsigned char *udest, *vdest, *src1, *src2;
00228     int alpha1, alpha2, alpha3, alpha4, src_wrap, y_wrap, width, height;
00229     unsigned char *y1, *y2, *y3, *y4, *a1, *a2, *a3, *a4, *r1, *r2, *r3, *r4;
00230     unsigned char *g1, *g2, *g3, *g4, *b1, *b2, *b3, *b4;
00231 
00232     width  = right - left;
00233     height = bottom - top;
00234 
00235     udest   = frame->buf + frame->offsets[1];
00236     vdest   = frame->buf + frame->offsets[2];
00237     udest  += (frame->pitches[1] * (top >> 1)) + (left >> 1);
00238     vdest  += (frame->pitches[2] * (top >> 1)) + (left >> 1);
00239 
00240     y1 = frame->buf + frame->offsets[0] + (frame->pitches[0] * top) + left;
00241     y3 = frame->buf + frame->offsets[0] + (frame->pitches[0] * (top + 1)) + left;
00242     y2 = y1 + 1; y4 = y3 + 1;
00243 
00244     src1 = osd_image->scanLine(top) + (left << 2);
00245     src2 = osd_image->scanLine(top + 1) + (left << 2);
00246     b1 = src1 + B_OI; b2 = b1 + 4; b3 = src2 + B_OI; b4 = b3 + 4;
00247     g1 = src1 + G_OI; g2 = g1 + 4; g3 = src2 + G_OI; g4 = g3 + 4;
00248     r1 = src1 + R_OI; r2 = r1 + 4; r3 = src2 + R_OI; r4 = r3 + 4;
00249     a1 = src1 + A_OI; a2 = a1 + 4; a3 = src2 + A_OI; a4 = a3 + 4;
00250     src_wrap = (osd_image->bytesPerLine() << 1) - (width << 2);
00251     y_wrap = (frame->pitches[0] << 1) - width;
00252 
00253     for (int row = 0; row < height; row += 2)
00254     {
00255         for (int col = 0; col < (width >> 1); col++)
00256         {
00257             alpha1 = 255 - *a1; alpha2 = 255 - *a2;
00258             alpha3 = 255 - *a3; alpha4 = 255 - *a4;
00259 
00260             *y1 = ((*y1 * alpha1) >> 8) + *r1;
00261             *y2 = ((*y2 * alpha2) >> 8) + *r2;
00262             *y3 = ((*y3 * alpha3) >> 8) + *r3;
00263             *y4 = ((*y4 * alpha4) >> 8) + *r4;
00264 
00265             alpha1 = (alpha1 + alpha2 + alpha3 + alpha4) >> 2;
00266             udest[col] = ((udest[col] * alpha1) >> 8) +
00267                          ((*g1 + *g2 + *g3 + *g4) >> 2);
00268             vdest[col] = ((vdest[col] * alpha1) >> 8) +
00269                          ((*b1 + *b2 + *b3 + *b4) >> 2);
00270 
00271             y1 += 2; y2 += 2; y3 += 2; y4 += 2;
00272             r1 += 8; r2 += 8; r3 += 8; r4 += 8;
00273             g1 += 8; g2 += 8; g3 += 8; g4 += 8;
00274             b1 += 8; b2 += 8; b3 += 8; b4 += 8;
00275             a1 += 8; a2 += 8; a3 += 8; a4 += 8;
00276 
00277         }
00278         r1 += src_wrap; r2 += src_wrap; r3 += src_wrap; r4 += src_wrap;
00279         g1 += src_wrap; g2 += src_wrap; g3 += src_wrap; g4 += src_wrap;
00280         b1 += src_wrap; b2 += src_wrap; b3 += src_wrap; b4 += src_wrap;
00281         a1 += src_wrap; a2 += src_wrap; a3 += src_wrap; a4 += src_wrap;
00282         y1 += y_wrap;   y2 += y_wrap;   y3 += y_wrap;   y4 += y_wrap;
00283         udest  += frame->pitches[1];
00284         vdest  += frame->pitches[2];
00285     }
00286 }
00287 
00288 void yuv888_to_i44(unsigned char *dest, MythImage *osd_image, QSize dst_size,
00289                    int left, int top, int right, int bottom, bool ifirst)
00290 {
00291     int width, ashift, amask, ishift, imask, src_wrap, dst_wrap;
00292     unsigned char *src, *alpha, *dst;
00293     const unsigned char *dmp;
00294 
00295     width  = right - left;
00296     ashift = ifirst ? 0 : 4;
00297     amask  = ifirst ? 0x0f : 0xf0;
00298     ishift = ifirst ? 4 : 0;
00299     imask  = ifirst ? 0xf0 : 0x0f;
00300 
00301     src   = osd_image->scanLine(top) + (left << 2) + R_OI;
00302     alpha = osd_image->scanLine(top) + (left << 2) + A_OI;
00303     dst   = dest + dst_size.width() * top + left;
00304     dst_wrap = dst_size.width() - width;
00305     src_wrap = osd_image->bytesPerLine() - (width << 2);
00306 
00307     for (int row = top; row < bottom; row++)
00308     {
00309         dmp = DM[row & (DM_HEIGHT - 1)];
00310         for (int col = left; col < right; col++)
00311         {
00312             int grey;
00313 
00314             grey = *src + ((dmp[col & (DM_WIDTH - 1)] << 2) >> 4);
00315             grey = (grey - (grey >> 4)) >> 4;
00316 
00317             *dst = (((*alpha >> 4) << ashift) & amask) |
00318                     (((grey) << ishift) & imask);
00319 
00320             alpha += 4;
00321             src   += 4;
00322             dst++;
00323         }
00324         alpha += src_wrap;
00325         src   += src_wrap;
00326         dst   += dst_wrap;
00327     }
00328 }
00329 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends