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