00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #include "mmsgui/fb/mmsfbconv.h"
00034 
00035 #ifdef __HAVE_PF_RGB24__
00036 #ifdef __HAVE_PF_YV12__
00037 
00038 #include "mmstools/mmstools.h"
00039 
00040 void mmsfb_blit_rgb24_to_yv12(MMSFBExternalSurfaceBuffer *extbuf, int src_height, int sx, int sy, int sw, int sh,
00041                               unsigned char *dst, int dst_pitch, int dst_height, int dx, int dy) {
00042     
00043     static bool firsttime = true;
00044     if (firsttime) {
00045         printf("DISKO: Using accelerated conversion RGB24 to YV12.\n");
00046         firsttime = false;
00047     }
00048 
00049     
00050     unsigned char *src = (unsigned char *)extbuf->ptr;
00051     int src_pitch = extbuf->pitch;
00052 
00053     
00054     int  src_pitch_pix      = src_pitch / 3;
00055     int dst_pitch_pix       = dst_pitch;
00056     int dst_pitch_pix_half  = dst_pitch_pix >> 1;
00057 
00058     src+= (sx + sy * src_pitch_pix) * 3;
00059 
00060     
00061     if (dst_pitch_pix - dx < sw - sx)
00062         sw = dst_pitch_pix - dx - sx;
00063     if (dst_height - dy < sh - sy)
00064         sh = dst_height - dy - sy;
00065     if ((sw <= 0)||(sh <= 0))
00066         return;
00067 
00068     int  src_pixels = src_pitch_pix * sh;
00069 
00070     
00071     bool odd_left   = (dx & 0x01);
00072     bool odd_top    = (dy & 0x01);
00073     bool odd_right  = ((dx + sw) & 0x01);
00074     bool odd_bottom = ((dy + sh) & 0x01);
00075 
00076     
00077     unsigned char *dst_y = dst + dx + dy * dst_pitch_pix;
00078     unsigned char *dst_u = dst + dst_pitch_pix * dst_height + dst_pitch_pix_half * (dst_height >> 1) + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00079     unsigned char *dst_v = dst + dst_pitch_pix * dst_height                                          + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00080 
00081     
00082     unsigned int dst_y2_offs = 1;
00083     unsigned int dst_y3_offs = dst_pitch;
00084     unsigned int dst_y4_offs = dst_y3_offs + 1;
00085     unsigned int src2_offs = 3;
00086     unsigned int src3_offs = src_pitch;
00087     unsigned int src4_offs = src3_offs + 3;
00088 
00089     
00090     register unsigned int d_u;
00091     register unsigned int d_v;
00092 
00093     
00094     if (odd_top && odd_left) {
00095         
00096         
00097         d_u = (*dst_u) * 3;
00098         d_v = (*dst_v) * 3;
00099 
00100         
00101         MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00102 
00103         
00104         *dst_u = d_u >> 2;
00105         *dst_v = d_v >> 2;
00106     }
00107 
00108     if (odd_top && odd_right) {
00109         
00110         MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00111 
00112         
00113         src   += (sw - 1) * 3;
00114         dst_y += sw - 1;
00115         if (odd_left) {
00116             dst_u += sw >> 1;
00117             dst_v += sw >> 1;
00118         }
00119         else {
00120             dst_u += (sw - 1) >> 1;
00121             dst_v += (sw - 1) >> 1;
00122         }
00123 
00124         
00125         d_u = (*dst_u) * 3;
00126         d_v = (*dst_v) * 3;
00127 
00128         
00129         MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00130 
00131         
00132         *dst_u = d_u >> 2;
00133         *dst_v = d_v >> 2;
00134 
00135         
00136         MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00137     }
00138 
00139     if (odd_bottom && odd_left) {
00140         
00141         MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00142 
00143         
00144         src   += (src_pitch_pix * (sh-1)) * 3;
00145         dst_y += dst_pitch_pix * (sh-1);
00146         if (odd_top) {
00147             dst_u += dst_pitch_pix_half * (sh >> 1);
00148             dst_v += dst_pitch_pix_half * (sh >> 1);
00149         }
00150         else {
00151             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00152             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00153         }
00154 
00155         
00156         d_u = (*dst_u) * 3;
00157         d_v = (*dst_v) * 3;
00158 
00159         
00160         MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00161 
00162         
00163         *dst_u = d_u >> 2;
00164         *dst_v = d_v >> 2;
00165 
00166         
00167         MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00168     }
00169 
00170     if (odd_bottom && odd_right) {
00171         
00172         MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00173 
00174         
00175         src   += (src_pitch_pix * (sh-1)) * 3;
00176         dst_y += dst_pitch_pix * (sh-1);
00177         if (odd_top) {
00178             dst_u += dst_pitch_pix_half * (sh >> 1);
00179             dst_v += dst_pitch_pix_half * (sh >> 1);
00180         }
00181         else {
00182             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00183             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00184         }
00185 
00186         
00187         src   += (sw - 1) * 3;
00188         dst_y += sw - 1;
00189         if (odd_left) {
00190             dst_u += sw >> 1;
00191             dst_v += sw >> 1;
00192         }
00193         else {
00194             dst_u += (sw - 1) >> 1;
00195             dst_v += (sw - 1) >> 1;
00196         }
00197 
00198         
00199         d_u = (*dst_u) * 3;
00200         d_v = (*dst_v) * 3;
00201 
00202         
00203         MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00204 
00205         
00206         *dst_u = d_u >> 2;
00207         *dst_v = d_v >> 2;
00208 
00209         
00210         MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00211     }
00212 
00213     if (odd_top) {
00214         
00215         MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00216 
00217         
00218         unsigned char *line_end = src + sw * 3;
00219         if (odd_left) {
00220             src+=3;
00221             dst_y++;
00222             dst_u++;
00223             dst_v++;
00224             line_end-=3;
00225         }
00226         if (odd_right)
00227             line_end-=3;
00228 
00229         
00230         while (src < line_end) {
00231             
00232             d_u = (*dst_u) << 1;
00233             d_v = (*dst_v) << 1;
00234 
00235             
00236             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00237             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src2_offs, dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00238 
00239             
00240             *dst_u = d_u >> 2;
00241             *dst_v = d_v >> 2;
00242 
00243             
00244             src+=2*3;
00245             dst_y+=2;
00246             dst_u++;
00247             dst_v++;
00248         }
00249 
00250         
00251         MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00252     }
00253 
00254     if (odd_bottom) {
00255         
00256         MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00257 
00258         
00259         src   += (src_pitch_pix * (sh-1)) * 3;
00260         dst_y += dst_pitch_pix * (sh-1);
00261         if (odd_top) {
00262             dst_u += dst_pitch_pix_half * (sh >> 1);
00263             dst_v += dst_pitch_pix_half * (sh >> 1);
00264         }
00265         else {
00266             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00267             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00268         }
00269 
00270         unsigned char *line_end = src + sw * 3;
00271         if (odd_left) {
00272             src+=3;
00273             dst_y++;
00274             dst_u++;
00275             dst_v++;
00276             line_end-=3;
00277         }
00278         if (odd_right)
00279             line_end-=3;
00280 
00281         
00282         while (src < line_end) {
00283             
00284             d_u = (*dst_u) << 1;
00285             d_v = (*dst_v) << 1;
00286 
00287             
00288             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00289             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src2_offs, dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00290 
00291             
00292             *dst_u = d_u >> 2;
00293             *dst_v = d_v >> 2;
00294 
00295             
00296             src+=2*3;
00297             dst_y+=2;
00298             dst_u++;
00299             dst_v++;
00300         }
00301 
00302         
00303         MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00304     }
00305 
00306     if (odd_left) {
00307         
00308         MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00309 
00310         
00311         unsigned char *src_end = src + src_pixels * 3;
00312         int src_pitch_diff    = (src_pitch_pix << 1) * 3;
00313         int dst_pitch_diff    = dst_pitch_pix << 1;
00314         int dst_pitch_uvdiff  = dst_pitch_pix_half;
00315         if (odd_top) {
00316             src     += src_pitch_pix * 3;
00317             src_end -= src_pitch_pix * 3;
00318             dst_y   += dst_pitch_pix;
00319             dst_u   += dst_pitch_pix_half;
00320             dst_v   += dst_pitch_pix_half;
00321         }
00322         if (odd_bottom)
00323             src_end -= src_pitch_pix * 3;
00324 
00325         
00326         while (src < src_end) {
00327             
00328             
00329             d_u = (*dst_u) << 1;
00330             d_v = (*dst_v) << 1;
00331 
00332             
00333             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00334             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src3_offs, dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00335 
00336             
00337             *dst_u = d_u >> 2;
00338             *dst_v = d_v >> 2;
00339 
00340             
00341             src   += src_pitch_diff;
00342             dst_y += dst_pitch_diff;
00343             dst_u += dst_pitch_uvdiff;
00344             dst_v += dst_pitch_uvdiff;
00345         }
00346 
00347         
00348         MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00349     }
00350 
00351     if (odd_right) {
00352         
00353         MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00354 
00355         
00356         unsigned char *src_end = src + src_pixels * 3;
00357         int src_pitch_diff    = (src_pitch_pix << 1) * 3;
00358         int dst_pitch_diff    = dst_pitch_pix << 1;
00359         int dst_pitch_uvdiff  = dst_pitch_pix_half;
00360         src   += (sw - 1) * 3;
00361         dst_y += sw - 1;
00362         if (odd_left) {
00363             dst_u += sw >> 1;
00364             dst_v += sw >> 1;
00365         }
00366         else {
00367             dst_u += (sw - 1) >> 1;
00368             dst_v += (sw - 1) >> 1;
00369         }
00370         if (odd_top) {
00371             src     += src_pitch_pix * 3;
00372             src_end -= src_pitch_pix * 3;
00373             dst_y   += dst_pitch_pix;
00374             dst_u   += dst_pitch_pix_half;
00375             dst_v   += dst_pitch_pix_half;
00376         }
00377         if (odd_bottom)
00378             src_end -= src_pitch_pix * 3;
00379 
00380         
00381         while (src < src_end) {
00382             
00383             
00384             d_u = (*dst_u) << 1;
00385             d_v = (*dst_v) << 1;
00386 
00387             
00388             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00389             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src3_offs, dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00390 
00391             
00392             *dst_u = d_u >> 2;
00393             *dst_v = d_v >> 2;
00394 
00395             
00396             src   += src_pitch_diff;
00397             dst_y += dst_pitch_diff;
00398             dst_u += dst_pitch_uvdiff;
00399             dst_v += dst_pitch_uvdiff;
00400         }
00401 
00402         
00403         MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00404     }
00405 
00406     
00407     if (odd_top) {
00408         
00409         dy++;
00410         sh--;
00411         src+=src_pitch_pix * 3;
00412         src_pixels-=src_pitch_pix;
00413         dst_y+=dst_pitch;
00414         dst_u+=dst_pitch >> 1;
00415         dst_v+=dst_pitch >> 1;
00416     }
00417 
00418     if (odd_bottom) {
00419         
00420         src_height--;
00421         src_pixels-=src_pitch_pix;
00422     }
00423 
00424     if (odd_left) {
00425         
00426         dx++;
00427         sw--;
00428         src+=3;
00429         dst_y++;
00430         dst_u++;
00431         dst_v++;
00432     }
00433 
00434     if (odd_right) {
00435         
00436         sw--;
00437     }
00438 
00439     
00440 
00441     unsigned char *src_end = src + src_pixels * 3;
00442     int src_pitch_diff = ((src_pitch_pix << 1) - sw) * 3;
00443     int dst_pitch_diff = (dst_pitch_pix << 1) - sw;
00444     int dst_pitch_uvdiff = (dst_pitch_pix - sw) >> 1;
00445     int swb = sw * 3;
00446 
00447     
00448     while (src < src_end) {
00449         
00450         unsigned char *line_end = src + swb;
00451 
00452         
00453         while (src < line_end) {
00454             
00455             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u=, d_v=);
00456             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src2_offs, dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00457             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src3_offs, dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00458             MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src4_offs, dst_y[dst_y4_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00459 
00460             
00461             *dst_u = d_u >> 2;
00462             *dst_v = d_v >> 2;
00463 
00464             
00465             src  +=2*3;
00466             dst_y+=2;
00467             dst_u++;
00468             dst_v++;
00469         }
00470 
00471         
00472         src   += src_pitch_diff;
00473         dst_y += dst_pitch_diff;
00474         dst_u += dst_pitch_uvdiff;
00475         dst_v += dst_pitch_uvdiff;
00476     }
00477 }
00478 
00479 #endif
00480 #endif