Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsfb_stretchblit_yuy2_to_yv12.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
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     // first time?
00051     static bool firsttime = true;
00052     if (firsttime) {
00053         printf("DISKO: Using accelerated stretch YUY2 to YV12.\n");
00054         firsttime = false;
00055     }
00056 
00057 //dy = 200;
00058 //dh-= 400;
00059 
00060 //sx+=100;
00061 //sw-=200;
00062 
00063 //dx+=100;
00064 //dw-=200;
00065 
00066     static MMSFBSurface *interim = NULL;
00067 #ifdef __HAVE_SWSCALE__
00068     static MMSFBSurface *interim2= NULL;
00069 #endif
00070 
00071 //////TESTONLY//////
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         02585     i= flags & ( SWS_POINT
00142         02586                 |SWS_AREA
00143         02587                 |SWS_BILINEAR
00144         02588                 |SWS_FAST_BILINEAR
00145         02589                 |SWS_BICUBIC
00146         02590                 |SWS_X
00147         02591                 |SWS_GAUSS
00148         02592                 |SWS_LANCZOS
00149         02593                 |SWS_SINC
00150         02594                 |SWS_SPLINE
00151         02595                 |SWS_BICUBLIN);
00152 */
00153 
00154 
00155 
00156 
00157 #endif
00158     }
00159     if (testswitch > 0) {
00160 /////TESTONLY///////
00161 #ifdef __HAVE_SWSCALE__
00162     // this code is for libswscale support...
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 //  if ((dx == 0) && (dst_planes->pitch == dw)) {
00172     {
00173 // the width of the destination rectangle MUST fit the width of the destination surface!
00174         if ((sx != 0) || ((src_planes->pitch >> 1) != sw)) {
00175             // the width of the source rectangle is NOT equal to the width of the source surface!
00176             // have to use a interim surface
00177             if (mmsfb_create_cached_surface(&interim, sw, sh, MMSFB_PF_YUY2)) {
00178                 // blit YUY2->YUY2
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             // no interim surface needed
00190             if (interim) {
00191                 delete interim;
00192                 interim = NULL;
00193             }
00194         }
00195 
00196         if ((dx != 0) || (dst_planes->pitch != dw)) {
00197             // the width of the destination rectangle is NOT equal to the width of the destination surface!
00198             // have to use a interim surface
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             // no interim surface needed
00209             if (interim2) {
00210                 delete interim2;
00211                 interim2 = NULL;
00212             }
00213         }
00214 
00215 
00216 
00217         // pixel width & height of source and destination
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         // get an sws context with pixelformat PIX_FMT_YUYV422 -> PIX_FMT_YUV420P
00227         // note: if the parameters are changed, a new context will be created
00228         //       else the previous context will be used
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             // error, using disko YUY2->YV12 stretch blit fall back
00240             printf("DISKO: Failed to get SwsContext, using YUY2->YV12 stretch blit fall back\n");
00241         }
00242         else {
00243             // set source pitches
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             // set destination pitches
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             // set source planes
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             // add source offset
00260             sws_src[0] = sws_src[0] + src_yoffs;
00261 
00262             // set destination planes (reverse order, because destination is YV12)
00263             uint8_t* sws_dst[3];
00264             sws_dst[0] = (uint8_t*)dplanes.ptr;
00265             if (!dplanes.ptr2) {
00266                 // no plane pointers given, calculate it
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                 // set plane pointers
00272                 sws_dst[2] = (uint8_t*)dplanes.ptr2;
00273                 sws_dst[1] = (uint8_t*)dplanes.ptr3;
00274             }
00275 
00276             // add destination offset
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             // scale the buffer
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                 // final blit from iterim to destination
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             // finished :)
00293             return;
00294         }
00295     }
00296 #endif
00297 
00298     }
00299 
00300     // here starts the disko YUY2->YV12 stretch blit...
00301     if (mmsfb_create_cached_surface(&interim, src_planes->pitch >> 1, src_height, MMSFB_PF_YV12)) {
00302         // blit YUY2->YV12
00303         interim->blitBuffer(src_planes, MMSFB_PF_YUY2, src_planes->pitch >> 1, src_height,
00304                             NULL, 0, 0);
00305 
00306         // stretch YV12->YV12
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

Generated by doxygen