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_YUY2__
00036 #ifdef __HAVE_PF_YV12__
00037 
00038 #include "mmstools/mmstools.h"
00039 
00040 void mmsfb_blit_yuy2_to_yv12(MMSFBSurfacePlanes *src_planes, int src_height, int sx, int sy, int sw, int sh,
00041                              MMSFBSurfacePlanes *dst_planes, int dst_height, int dx, int dy) {
00042     
00043     static bool firsttime = true;
00044     if (firsttime) {
00045         printf("DISKO: Using accelerated conversion YUY2 to YV12.\n");
00046         firsttime = false;
00047     }
00048 
00049     
00050     unsigned short int *src = (unsigned short int *)src_planes->ptr;
00051     int src_pitch = src_planes->pitch;
00052 
00053     
00054     unsigned char *dst = (unsigned char *)dst_planes->ptr;
00055     int dst_pitch = dst_planes->pitch;
00056 
00057     
00058     
00059     if (sx & 0x01) {
00060         sx++;
00061         sw--;
00062         dx++;
00063     }
00064     if (sw & 0x01) {
00065         sw--;
00066         if (dx & 0x01) {
00067             dx++;
00068         }
00069     }
00070     else
00071     if (dx & 0x01) {
00072         dx++;
00073         sw-=2;
00074     }
00075 
00076     
00077     int src_pitch_pix       = src_pitch >> 1;
00078     int dst_pitch_pix       = dst_pitch;
00079     int dst_pitch_pix_half  = dst_pitch_pix >> 1;
00080 
00081     src+= sx + sy * src_pitch_pix;
00082 
00083     
00084     if (dst_pitch_pix - dx < sw - sx)
00085         sw = dst_pitch_pix - dx - sx;
00086     if (dst_height - dy < sh - sy)
00087         sh = dst_height - dy - sy;
00088     if ((sw <= 0)||(sh <= 0))
00089         return;
00090 
00091     int  src_pixels = src_pitch_pix * sh;
00092 
00093     
00094     bool odd_top    = (dy & 0x01);
00095     bool odd_bottom = ((dy + sh) & 0x01);
00096 
00097     
00098     unsigned char *dst_y = dst + dx + dy * dst_pitch_pix;
00099     unsigned char *dst_u;
00100     unsigned char *dst_v;
00101     if ((dst_planes->ptr2)&&(dst_planes->ptr3)) {
00102         dst_u = (unsigned char *)dst_planes->ptr2 + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00103         dst_v = (unsigned char *)dst_planes->ptr3 + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00104     }
00105     else {
00106         dst_u = dst + dst_pitch_pix * dst_height + dst_pitch_pix_half * (dst_height >> 1) + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00107         dst_v = dst + dst_pitch_pix * dst_height                                          + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00108     }
00109 
00110     
00111     unsigned int dst_y2_offs = 1;
00112     unsigned int dst_y3_offs = dst_pitch;
00113     unsigned int dst_y4_offs = dst_y3_offs + 1;
00114     unsigned int src2_offs = 1;
00115     unsigned int src3_offs = src_pitch_pix;
00116     unsigned int src4_offs = src3_offs + 1;
00117 
00118     
00119     register unsigned int d_u;
00120     register unsigned int d_v;
00121 
00122     if (odd_top) {
00123         
00124         MMSFB_CONV_YUY2_TO_YV12_PUSHPTR;
00125 
00126         
00127         unsigned short int *line_end = src + sw;
00128 
00129         
00130         while (src < line_end) {
00131             register unsigned short int SRC;
00132 
00133             
00134             d_u = (*dst_u) << 1;
00135             d_v = (*dst_v) << 1;
00136 
00137             
00138             MMSFB_CONV_YUY2_TO_YV12_PIXEL_2(*src, *dst_y, d_u+=);
00139             MMSFB_CONV_YUY2_TO_YV12_PIXEL_2(src[src2_offs], dst_y[dst_y2_offs], d_v+=);
00140 
00141             
00142             *dst_u = d_u >> 2;
00143             *dst_v = d_v >> 2;
00144 
00145             
00146             src+=2;
00147             dst_y+=2;
00148             dst_u++;
00149             dst_v++;
00150         }
00151 
00152         
00153         MMSFB_CONV_YUY2_TO_YV12_POPPTR;
00154     }
00155 
00156     if (odd_bottom) {
00157         
00158         MMSFB_CONV_YUY2_TO_YV12_PUSHPTR;
00159 
00160         
00161         src   += src_pitch_pix * (sh-1);
00162         dst_y += dst_pitch_pix * (sh-1);
00163         if (odd_top) {
00164             dst_u += dst_pitch_pix_half * (sh >> 1);
00165             dst_v += dst_pitch_pix_half * (sh >> 1);
00166         }
00167         else {
00168             dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00169             dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00170         }
00171 
00172         unsigned short int *line_end = src + sw;
00173 
00174         
00175         while (src < line_end) {
00176             register unsigned short int SRC;
00177 
00178             
00179             d_u = (*dst_u) << 1;
00180             d_v = (*dst_v) << 1;
00181 
00182             
00183             MMSFB_CONV_YUY2_TO_YV12_PIXEL_2(*src, *dst_y, d_u+=);
00184             MMSFB_CONV_YUY2_TO_YV12_PIXEL_2(src[src2_offs], dst_y[dst_y2_offs], d_v+=);
00185 
00186             
00187             *dst_u = d_u >> 2;
00188             *dst_v = d_v >> 2;
00189 
00190             
00191             src+=2;
00192             dst_y+=2;
00193             dst_u++;
00194             dst_v++;
00195         }
00196 
00197         
00198         MMSFB_CONV_YUY2_TO_YV12_POPPTR;
00199     }
00200 
00201     
00202     if (odd_top) {
00203         
00204         dy++;
00205         sh--;
00206         src+=src_pitch_pix;
00207         src_pixels-=src_pitch_pix;
00208         dst_y+=dst_pitch;
00209         dst_u+=dst_pitch >> 1;
00210         dst_v+=dst_pitch >> 1;
00211     }
00212 
00213     if (odd_bottom) {
00214         
00215         src_height--;
00216         src_pixels-=src_pitch_pix;
00217     }
00218 
00219     
00220 
00221     unsigned short int *src_end = src + src_pixels;
00222     int src_pitch_diff = (src_pitch_pix << 1) - sw;
00223     int dst_pitch_diff = (dst_pitch_pix << 1) - sw;
00224     int dst_pitch_uvdiff = (dst_pitch_pix - sw) >> 1;
00225 
00226     
00227     while (src < src_end) {
00228         
00229         unsigned short int *line_end = src + sw;
00230 
00231         
00232         while (src < line_end) {
00233             register unsigned short int SRC;
00234 
00235             
00236             MMSFB_CONV_YUY2_TO_YV12_PIXEL(*src, *dst_y, d_u=);
00237             MMSFB_CONV_YUY2_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], d_v=);
00238             MMSFB_CONV_YUY2_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], d_u+=);
00239             MMSFB_CONV_YUY2_TO_YV12_PIXEL(src[src4_offs], dst_y[dst_y4_offs], d_v+=);
00240 
00241             
00242             *dst_u = d_u >> 1;
00243             *dst_v = d_v >> 1;
00244 
00245             
00246             src  +=2;
00247             dst_y+=2;
00248             dst_u++;
00249             dst_v++;
00250         }
00251 
00252         
00253         src   += src_pitch_diff;
00254         dst_y += dst_pitch_diff;
00255         dst_u += dst_pitch_uvdiff;
00256         dst_v += dst_pitch_uvdiff;
00257     }
00258 }
00259 
00260 #endif
00261 #endif