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