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_YV12__
00036 #ifdef __HAVE_PF_RGB32__
00037 
00038 #include "mmstools/mmstools.h"
00039 
00040 void mmsfb_blit_yv12_to_rgb32(MMSFBExternalSurfaceBuffer *extbuf, int src_height, int sx, int sy, int sw, int sh,
00041                               unsigned int *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 YV12 to RGB32.\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 dst_pitch_pix       = dst_pitch >> 2;
00055     int src_pitch_pix       = src_pitch;
00056     int src_pitch_pix_half  = src_pitch_pix >> 1;
00057 
00058     dst+= dx + dy * dst_pitch_pix;
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 
00069 
00070 
00071 
00072 
00073     int  src_pixels = src_pitch_pix * sh;
00074 
00075     
00076     bool odd_left   = (sx & 0x01);
00077     bool odd_top    = (sy & 0x01);
00078     bool odd_right  = ((sx + sw) & 0x01);
00079     bool odd_bottom = ((sy + sh) & 0x01);
00080 
00081     
00082     unsigned char *src_y = src + sx + sy * src_pitch_pix;
00083     unsigned char *src_u = src + src_pitch_pix * src_height + src_pitch_pix_half * (src_height >> 1) + (sx >> 1) + (sy >> 1) * src_pitch_pix_half;
00084     unsigned char *src_v = src + src_pitch_pix * src_height                                          + (sx >> 1) + (sy >> 1) * src_pitch_pix_half;
00085 
00086     
00087     unsigned int src_y2_offs = 1;
00088     unsigned int src_y3_offs = src_pitch;
00089     unsigned int src_y4_offs = src_y3_offs + 1;
00090     unsigned int dst2_offs = 1;
00091     unsigned int dst3_offs = dst_pitch_pix;
00092     unsigned int dst4_offs = dst3_offs + 1;
00093 
00094     
00095 
00096 
00097 
00098 #ifdef sfsgsgsgsg
00099     
00100     if (odd_top && odd_left) {
00101         
00102         register unsigned int SRC;
00103         register unsigned int A;
00104 
00105         
00106         d_u = (*dst_u) * 3;
00107         d_v = (*dst_v) * 3;
00108 
00109         
00110         MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00111 
00112         
00113         *dst_u = d_u >> 2;
00114         *dst_v = d_v >> 2;
00115     }
00116 
00117     if (odd_top && odd_right) {
00118         
00119         MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00120 
00121         
00122         src   += sw - 1;
00123         dst_y += sw - 1;
00124         if (odd_left) {
00125             dst_u += sw >> 1;
00126             dst_v += sw >> 1;
00127         }
00128         else {
00129             dst_u += (sw - 1) >> 1;
00130             dst_v += (sw - 1) >> 1;
00131         }
00132 
00133         register unsigned int SRC;
00134         register unsigned int A;
00135 
00136         
00137         d_u = (*dst_u) * 3;
00138         d_v = (*dst_v) * 3;
00139 
00140         
00141         MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00142 
00143         
00144         *dst_u = d_u >> 2;
00145         *dst_v = d_v >> 2;
00146 
00147         
00148         MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00149     }
00150 
00151     if (odd_bottom && odd_left) {
00152         
00153         MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00154 
00155         
00156         src   += src_pitch_pix * (sh-1);
00157         dst_y += dst_pitch_pix * (sh-1);
00158         if (odd_top) {
00159             dst_u += dst_pitch_pix_half * (sh >> 1);
00160             dst_v += dst_pitch_pix_half * (sh >> 1);
00161         }
00162         else {
00163             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00164             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00165         }
00166 
00167         register unsigned int SRC;
00168         register unsigned int A;
00169 
00170         
00171         d_u = (*dst_u) * 3;
00172         d_v = (*dst_v) * 3;
00173 
00174         
00175         MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00176 
00177         
00178         *dst_u = d_u >> 2;
00179         *dst_v = d_v >> 2;
00180 
00181         
00182         MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00183     }
00184 
00185     if (odd_bottom && odd_right) {
00186         
00187         MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00188 
00189         
00190         src   += src_pitch_pix * (sh-1);
00191         dst_y += dst_pitch_pix * (sh-1);
00192         if (odd_top) {
00193             dst_u += dst_pitch_pix_half * (sh >> 1);
00194             dst_v += dst_pitch_pix_half * (sh >> 1);
00195         }
00196         else {
00197             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00198             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00199         }
00200 
00201         
00202         src   += sw - 1;
00203         dst_y += sw - 1;
00204         if (odd_left) {
00205             dst_u += sw >> 1;
00206             dst_v += sw >> 1;
00207         }
00208         else {
00209             dst_u += (sw - 1) >> 1;
00210             dst_v += (sw - 1) >> 1;
00211         }
00212 
00213         register unsigned int SRC;
00214         register unsigned int A;
00215 
00216         
00217         d_u = (*dst_u) * 3;
00218         d_v = (*dst_v) * 3;
00219 
00220         
00221         MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00222 
00223         
00224         *dst_u = d_u >> 2;
00225         *dst_v = d_v >> 2;
00226 
00227         
00228         MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00229     }
00230 
00231     if (odd_top) {
00232         
00233         MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00234 
00235         
00236         unsigned int *line_end = src + sw;
00237         if (odd_left) {
00238             src++;
00239             dst_y++;
00240             dst_u++;
00241             dst_v++;
00242             line_end--;
00243         }
00244         if (odd_right)
00245             line_end--;
00246 
00247         
00248         while (src < line_end) {
00249             register unsigned int SRC;
00250             register unsigned int A;
00251 
00252             
00253             d_u = (*dst_u) << 1;
00254             d_v = (*dst_v) << 1;
00255 
00256             
00257             MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00258             MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00259 
00260             
00261             *dst_u = d_u >> 2;
00262             *dst_v = d_v >> 2;
00263 
00264             
00265             src+=2;
00266             dst_y+=2;
00267             dst_u++;
00268             dst_v++;
00269         }
00270 
00271         
00272         MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00273     }
00274 
00275     if (odd_bottom) {
00276         
00277         MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00278 
00279         
00280         src   += src_pitch_pix * (sh-1);
00281         dst_y += dst_pitch_pix * (sh-1);
00282         if (odd_top) {
00283             dst_u += dst_pitch_pix_half * (sh >> 1);
00284             dst_v += dst_pitch_pix_half * (sh >> 1);
00285         }
00286         else {
00287             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00288             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00289         }
00290 
00291         unsigned int *line_end = src + sw;
00292         if (odd_left) {
00293             src++;
00294             dst_y++;
00295             dst_u++;
00296             dst_v++;
00297             line_end--;
00298         }
00299         if (odd_right)
00300             line_end--;
00301 
00302         
00303         while (src < line_end) {
00304             register unsigned int SRC;
00305             register unsigned int A;
00306 
00307             
00308             d_u = (*dst_u) << 1;
00309             d_v = (*dst_v) << 1;
00310 
00311             
00312             MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00313             MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00314 
00315             
00316             *dst_u = d_u >> 2;
00317             *dst_v = d_v >> 2;
00318 
00319             
00320             src+=2;
00321             dst_y+=2;
00322             dst_u++;
00323             dst_v++;
00324         }
00325 
00326         
00327         MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00328     }
00329 
00330     if (odd_left) {
00331         
00332         MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00333 
00334         
00335         unsigned int *src_end = src + src_pixels;
00336         int src_pitch_diff    = src_pitch_pix << 1;
00337         int dst_pitch_diff    = dst_pitch_pix << 1;
00338         int dst_pitch_uvdiff  = dst_pitch_pix_half;
00339         if (odd_top) {
00340             src     += src_pitch_pix;
00341             src_end -= src_pitch_pix;
00342             dst_y   += dst_pitch_pix;
00343             dst_u   += dst_pitch_pix_half;
00344             dst_v   += dst_pitch_pix_half;
00345         }
00346         if (odd_bottom)
00347             src_end -= src_pitch_pix;
00348 
00349         
00350         while (src < src_end) {
00351             
00352             register unsigned int SRC;
00353             register unsigned int A;
00354 
00355             
00356             d_u = (*dst_u) << 1;
00357             d_v = (*dst_v) << 1;
00358 
00359             
00360             MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00361             MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00362 
00363             
00364             *dst_u = d_u >> 2;
00365             *dst_v = d_v >> 2;
00366 
00367             
00368             src   += src_pitch_diff;
00369             dst_y += dst_pitch_diff;
00370             dst_u += dst_pitch_uvdiff;
00371             dst_v += dst_pitch_uvdiff;
00372         }
00373 
00374         
00375         MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00376     }
00377 
00378     if (odd_right) {
00379         
00380         MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00381 
00382         
00383         unsigned int *src_end = src + src_pixels;
00384         int src_pitch_diff    = src_pitch_pix << 1;
00385         int dst_pitch_diff    = dst_pitch_pix << 1;
00386         int dst_pitch_uvdiff  = dst_pitch_pix_half;
00387         src   += sw - 1;
00388         dst_y += sw - 1;
00389         if (odd_left) {
00390             dst_u += sw >> 1;
00391             dst_v += sw >> 1;
00392         }
00393         else {
00394             dst_u += (sw - 1) >> 1;
00395             dst_v += (sw - 1) >> 1;
00396         }
00397         if (odd_top) {
00398             src     += src_pitch_pix;
00399             src_end -= src_pitch_pix;
00400             dst_y   += dst_pitch_pix;
00401             dst_u   += dst_pitch_pix_half;
00402             dst_v   += dst_pitch_pix_half;
00403         }
00404         if (odd_bottom)
00405             src_end -= src_pitch_pix;
00406 
00407         
00408         while (src < src_end) {
00409             
00410             register unsigned int SRC;
00411             register unsigned int A;
00412 
00413             
00414             d_u = (*dst_u) << 1;
00415             d_v = (*dst_v) << 1;
00416 
00417             
00418             MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00419             MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00420 
00421             
00422             *dst_u = d_u >> 2;
00423             *dst_v = d_v >> 2;
00424 
00425             
00426             src   += src_pitch_diff;
00427             dst_y += dst_pitch_diff;
00428             dst_u += dst_pitch_uvdiff;
00429             dst_v += dst_pitch_uvdiff;
00430         }
00431 
00432         
00433         MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00434     }
00435 #endif
00436 
00437 
00438     
00439     if (odd_top) {
00440         
00441         dy++;
00442         sh--;
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450         dst+=dst_pitch_pix;
00451         src_pixels-=src_pitch_pix;
00452         src_y+=src_pitch;
00453         src_u+=src_pitch >> 1;
00454         src_v+=src_pitch >> 1;
00455 
00456     }
00457 
00458     if (odd_bottom) {
00459         
00460         src_height--;
00461         src_pixels-=src_pitch_pix;
00462     }
00463 
00464     if (odd_left) {
00465         
00466         dx++;
00467         sw--;
00468         dst++;
00469         src_y++;
00470         src_u++;
00471         src_v++;
00472     }
00473 
00474     if (odd_right) {
00475         
00476         sw--;
00477     }
00478 
00479 
00480 
00481 
00482     unsigned int *src_end = src + src_pixels;
00483     int src_pitch_diff = (src_pitch_pix << 1) - sw;
00484     int dst_pitch_diff = (dst_pitch_pix << 1) - sw;
00485     int dst_pitch_uvdiff = (dst_pitch_pix - sw) >> 1;
00486 
00487     // for all lines
00488     while (src < src_end) {
00489         // for all pixels in the line
00490         unsigned int *line_end = src + sw;
00491 
00492         // go through two lines in parallel (square 2x2 pixel)
00493         while (src < line_end) {
00494             register unsigned int SRC;
00495             register unsigned int A;
00496 
00497             // calculate the four pixels...
00498             MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u=, d_v=);
00499             MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00500             MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00501             MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src4_offs], dst_y[dst_y4_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00502 
00503             // calulate the arithmetic mean
00504             *dst_u = d_u >> 2;
00505             *dst_v = d_v >> 2;
00506 
00507             // go to the next two pixels
00508             src  +=2;
00509             dst_y+=2;
00510             dst_u++;
00511             dst_v++;
00512         }
00513 
00514         // go to the next two lines
00515         src   += src_pitch_diff;
00516         dst_y += dst_pitch_diff;
00517         dst_u += dst_pitch_uvdiff;
00518         dst_v += dst_pitch_uvdiff;
00519     }
00520 */
00521 
00522     
00523 
00524     unsigned char *src_end = src_y + src_pixels;
00525     int dst_pitch_diff = (dst_pitch_pix << 1) - sw;
00526     int src_pitch_diff = (src_pitch_pix << 1) - sw;
00527     int src_pitch_uvdiff = (src_pitch_pix - sw) >> 1;
00528 
00529     
00530     while (src_y < src_end) {
00531         
00532         unsigned char *line_end = src_y + sw;
00533 
00534         
00535         while (src_y < line_end) {
00536 
00537 
00538 
00539             
00540             MMSFB_CONV_YV12_TO_RGB32_PIXEL(*src_y, *src_u, *src_v, *dst);
00541             MMSFB_CONV_YV12_TO_RGB32_PIXEL(src_y[src_y2_offs], *src_u, *src_v, dst[dst2_offs]);
00542             MMSFB_CONV_YV12_TO_RGB32_PIXEL(src_y[src_y3_offs], *src_u, *src_v, dst[dst3_offs]);
00543             MMSFB_CONV_YV12_TO_RGB32_PIXEL(src_y[src_y4_offs], *src_u, *src_v, dst[dst4_offs]);
00544 
00545             
00546 
00547 
00548 
00549             
00550             dst  +=2;
00551             src_y+=2;
00552             src_u++;
00553             src_v++;
00554         }
00555 
00556         
00557         dst   += dst_pitch_diff;
00558         src_y += src_pitch_diff;
00559         src_u += src_pitch_uvdiff;
00560         src_v += src_pitch_uvdiff;
00561     }
00562 }
00563 
00564 #endif
00565 #endif