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