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 "mmsgui/fb/mmsfbsurface.h"
00039 #include "mmstools/mmstools.h"
00040 
00041 #ifdef __HAVE_SWSCALE__
00042 extern "C" {
00043 #include <libswscale/swscale.h>
00044 }
00045 #endif
00046 
00047 void mmsfb_stretchblit_yuy2_to_yv12(MMSFBSurfacePlanes *src_planes, int src_height, int sx, int sy, int sw, int sh,
00048                                     MMSFBSurfacePlanes *dst_planes, int dst_height, int dx, int dy, int dw, int dh,
00049                                     bool antialiasing) {
00050     
00051     static bool firsttime = true;
00052     if (firsttime) {
00053         printf("DISKO: Using accelerated stretch YUY2 to YV12.\n");
00054         firsttime = false;
00055     }
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066     static MMSFBSurface *interim = NULL;
00067 #ifdef __HAVE_SWSCALE__
00068     static MMSFBSurface *interim2= NULL;
00069 #endif
00070 
00071 
00072 #ifdef __HAVE_SWSCALE__
00073     static int fff = 0;
00074 #endif
00075     static int testswitchtime = 0;
00076     static int testswitch = 0;
00077     if (!testswitchtime) {
00078         testswitchtime=time(NULL)+30;
00079 #ifdef __HAVE_SWSCALE__
00080         printf(">>> using disko stretchblit YUY2\n");
00081 #endif
00082     }
00083     else
00084     if (testswitchtime < time(NULL)) {
00085         testswitchtime=time(NULL)+30;
00086         testswitch++;
00087         if (testswitch > 11)
00088             testswitch = 0;
00089 #ifdef __HAVE_SWSCALE__
00090         switch (testswitch) {
00091         case 0:
00092             printf(">>> using disko stretchblit YUY2\n");
00093             break;
00094         case 1:
00095             fff = SWS_POINT;
00096             printf(">>> using SWSCALE stretchblit flag=SWS_POINT\n");
00097             break;
00098         case 2:
00099             fff = SWS_AREA;
00100             printf(">>> using SWSCALE stretchblit flag=SWS_AREA\n");
00101             break;
00102         case 3:
00103             fff = SWS_BILINEAR;
00104             printf(">>> using SWSCALE stretchblit flag=SWS_BILINEAR\n");
00105             break;
00106         case 4:
00107             fff = SWS_FAST_BILINEAR;
00108             printf(">>> using SWSCALE stretchblit flag=SWS_FAST_BILINEAR\n");
00109             break;
00110         case 5:
00111             fff = SWS_BICUBIC;
00112             printf(">>> using SWSCALE stretchblit flag=SWS_BICUBIC\n");
00113             break;
00114         case 6:
00115             fff = SWS_X;
00116             printf(">>> using SWSCALE stretchblit flag=SWS_X\n");
00117             break;
00118         case 7:
00119             fff = SWS_GAUSS;
00120             printf(">>> using SWSCALE stretchblit flag=SWS_GAUSS\n");
00121             break;
00122         case 8:
00123             fff = SWS_LANCZOS;
00124             printf(">>> using SWSCALE stretchblit flag=SWS_LANCZOS\n");
00125             break;
00126         case 9:
00127             fff = SWS_SINC;
00128             printf(">>> using SWSCALE stretchblit flag=SWS_SINC\n");
00129             break;
00130         case 10:
00131             fff = SWS_SPLINE;
00132             printf(">>> using SWSCALE stretchblit flag=SWS_SPLINE\n");
00133             break;
00134         case 11:
00135             fff = SWS_BICUBLIN;
00136             printf(">>> using SWSCALE stretchblit flag=SWS_BICUBLIN\n");
00137             break;
00138         }
00139 
00140         
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 #endif
00158     }
00159     if (testswitch > 0) {
00160 
00161 #ifdef __HAVE_SWSCALE__
00162     
00163     MMSFBRectangle srect = MMSFBRectangle(sx,sy,sw,sh);
00164     MMSFBSurfacePlanes splanes = *src_planes;
00165     int sheight = src_height;
00166     MMSFBRectangle drect = MMSFBRectangle(dx,dy,dw,dh);
00167     MMSFBSurfacePlanes dplanes = *dst_planes;
00168     int dheight = dst_height;
00169 
00170 
00171 
00172     {
00173 
00174         if ((sx != 0) || ((src_planes->pitch >> 1) != sw)) {
00175             
00176             
00177             if (mmsfb_create_cached_surface(&interim, sw, sh, MMSFB_PF_YUY2)) {
00178                 
00179                 interim->blitBuffer(&splanes, MMSFB_PF_YUY2, splanes.pitch >> 1, sheight,
00180                                     &srect, 0, 0);
00181                 interim->lock(MMSFB_LOCK_READ, &splanes);
00182                 interim->unlock();
00183                 srect.x = 0;
00184                 srect.y = 0;
00185                 sheight = sh;
00186             }
00187         }
00188         else {
00189             
00190             if (interim) {
00191                 delete interim;
00192                 interim = NULL;
00193             }
00194         }
00195 
00196         if ((dx != 0) || (dst_planes->pitch != dw)) {
00197             
00198             
00199             if (mmsfb_create_cached_surface(&interim2, dw, dh, MMSFB_PF_YV12)) {
00200                 interim2->lock(MMSFB_LOCK_READ, &dplanes);
00201                 interim2->unlock();
00202                 drect.x = 0;
00203                 drect.y = 0;
00204                 dheight = dh;
00205             }
00206         }
00207         else {
00208             
00209             if (interim2) {
00210                 delete interim2;
00211                 interim2 = NULL;
00212             }
00213         }
00214 
00215 
00216 
00217         
00218         int pix_src_width = splanes.pitch >> 1;
00219         int pix_src_height = srect.h;
00220         int pix_dst_width = dplanes.pitch;
00221         int pix_dst_height = drect.h;
00222         int src_yoffs = srect.y * splanes.pitch;
00223         int dst_yoffs = drect.y * dplanes.pitch;
00224         int flags = fff;
00225 
00226         
00227         
00228         
00229         static SwsContext *sws_context = NULL;
00230         if (!sws_context) {
00231             const char *license = swscale_license();
00232             printf("DISKO: Using libswscale with license %s\n", license);
00233         }
00234         sws_context = sws_getCachedContext( sws_context,
00235                                             pix_src_width, pix_src_height, PIX_FMT_YUYV422,
00236                                             pix_dst_width, pix_dst_height, PIX_FMT_YUV420P,
00237                                             flags, NULL, NULL, NULL);
00238         if (!sws_context) {
00239             
00240             printf("DISKO: Failed to get SwsContext, using YUY2->YV12 stretch blit fall back\n");
00241         }
00242         else {
00243             
00244             int sws_src_stride[3];
00245             sws_src_stride[0] = splanes.pitch;
00246             sws_src_stride[1] = sws_src_stride[2] = 0;
00247 
00248             
00249             int sws_dst_stride[3];
00250             sws_dst_stride[0] = dplanes.pitch;
00251             sws_dst_stride[1] = sws_dst_stride[2] = dplanes.pitch/2;
00252 
00253             
00254             uint8_t* sws_src[3];
00255             sws_src[0] = (uint8_t*)splanes.ptr;
00256             sws_src[1] = NULL;
00257             sws_src[2] = NULL;
00258 
00259             
00260             sws_src[0] = sws_src[0] + src_yoffs;
00261 
00262             
00263             uint8_t* sws_dst[3];
00264             sws_dst[0] = (uint8_t*)dplanes.ptr;
00265             if (!dplanes.ptr2) {
00266                 
00267                 sws_dst[2] = sws_dst[0] + dplanes.pitch * dheight;
00268                 sws_dst[1] = sws_dst[2] + dplanes.pitch * dheight / 4;
00269             }
00270             else {
00271                 
00272                 sws_dst[2] = (uint8_t*)dplanes.ptr2;
00273                 sws_dst[1] = (uint8_t*)dplanes.ptr3;
00274             }
00275 
00276             
00277             sws_dst[0] = sws_dst[0] + dst_yoffs;
00278             sws_dst[1] = sws_dst[1] + (dst_yoffs >> 2);
00279             sws_dst[2] = sws_dst[2] + (dst_yoffs >> 2);
00280 
00281             
00282             sws_scale(  sws_context,
00283                         sws_src, sws_src_stride, 0, pix_src_height,
00284                         sws_dst, sws_dst_stride);
00285 
00286             if (interim2) {
00287                 
00288                 mmsfb_blit_yv12_to_yv12(&dplanes, dheight, drect.x, drect.y, drect.w, drect.h,
00289                                         dst_planes, dst_height, dx, dy);
00290             }
00291 
00292             
00293             return;
00294         }
00295     }
00296 #endif
00297 
00298     }
00299 
00300     
00301     if (mmsfb_create_cached_surface(&interim, src_planes->pitch >> 1, src_height, MMSFB_PF_YV12)) {
00302         
00303         interim->blitBuffer(src_planes, MMSFB_PF_YUY2, src_planes->pitch >> 1, src_height,
00304                             NULL, 0, 0);
00305 
00306         
00307         MMSFBSurfacePlanes sp;
00308         interim->lock(MMSFB_LOCK_READ, &sp);
00309         mmsfb_stretchblit_yv12_to_yv12(&sp, src_height, sx, sy, sw, sh,
00310                                        dst_planes, dst_height, dx, dy, dw, dh,
00311                                        antialiasing);
00312         interim->unlock();
00313     }
00314 }
00315 
00316 #endif
00317 #endif