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_YV12__
00036 #ifdef __HAVE_PF_RGB32__
00037
00038 #include "mmstools/mmstools.h"
00039
00040 void mmsfb_blit_yv12_to_rgb32(MMSFBExternalSurfaceBuffer *extbuf, int src_height, int sx, int sy, int sw, int sh,
00041 unsigned int *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 conversion YV12 to RGB32.\n");
00046 firsttime = false;
00047 }
00048
00049
00050 unsigned char *src = (unsigned char *)extbuf->ptr;
00051 int src_pitch = extbuf->pitch;
00052
00053
00054 int dst_pitch_pix = dst_pitch >> 2;
00055 int src_pitch_pix = src_pitch;
00056 int src_pitch_pix_half = src_pitch_pix >> 1;
00057
00058 dst+= dx + dy * dst_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
00069
00070
00071
00072
00073 int src_pixels = src_pitch_pix * sh;
00074
00075
00076 bool odd_left = (sx & 0x01);
00077 bool odd_top = (sy & 0x01);
00078 bool odd_right = ((sx + sw) & 0x01);
00079 bool odd_bottom = ((sy + sh) & 0x01);
00080
00081
00082 unsigned char *src_y = src + sx + sy * src_pitch_pix;
00083 unsigned char *src_u = src + src_pitch_pix * src_height + src_pitch_pix_half * (src_height >> 1) + (sx >> 1) + (sy >> 1) * src_pitch_pix_half;
00084 unsigned char *src_v = src + src_pitch_pix * src_height + (sx >> 1) + (sy >> 1) * src_pitch_pix_half;
00085
00086
00087 unsigned int src_y2_offs = 1;
00088 unsigned int src_y3_offs = src_pitch;
00089 unsigned int src_y4_offs = src_y3_offs + 1;
00090 unsigned int dst2_offs = 1;
00091 unsigned int dst3_offs = dst_pitch_pix;
00092 unsigned int dst4_offs = dst3_offs + 1;
00093
00094
00095
00096
00097
00098 #ifdef sfsgsgsgsg
00099
00100 if (odd_top && odd_left) {
00101
00102 register unsigned int SRC;
00103 register unsigned int A;
00104
00105
00106 d_u = (*dst_u) * 3;
00107 d_v = (*dst_v) * 3;
00108
00109
00110 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00111
00112
00113 *dst_u = d_u >> 2;
00114 *dst_v = d_v >> 2;
00115 }
00116
00117 if (odd_top && odd_right) {
00118
00119 MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00120
00121
00122 src += sw - 1;
00123 dst_y += sw - 1;
00124 if (odd_left) {
00125 dst_u += sw >> 1;
00126 dst_v += sw >> 1;
00127 }
00128 else {
00129 dst_u += (sw - 1) >> 1;
00130 dst_v += (sw - 1) >> 1;
00131 }
00132
00133 register unsigned int SRC;
00134 register unsigned int A;
00135
00136
00137 d_u = (*dst_u) * 3;
00138 d_v = (*dst_v) * 3;
00139
00140
00141 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00142
00143
00144 *dst_u = d_u >> 2;
00145 *dst_v = d_v >> 2;
00146
00147
00148 MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00149 }
00150
00151 if (odd_bottom && odd_left) {
00152
00153 MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00154
00155
00156 src += src_pitch_pix * (sh-1);
00157 dst_y += dst_pitch_pix * (sh-1);
00158 if (odd_top) {
00159 dst_u += dst_pitch_pix_half * (sh >> 1);
00160 dst_v += dst_pitch_pix_half * (sh >> 1);
00161 }
00162 else {
00163 dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00164 dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00165 }
00166
00167 register unsigned int SRC;
00168 register unsigned int A;
00169
00170
00171 d_u = (*dst_u) * 3;
00172 d_v = (*dst_v) * 3;
00173
00174
00175 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00176
00177
00178 *dst_u = d_u >> 2;
00179 *dst_v = d_v >> 2;
00180
00181
00182 MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00183 }
00184
00185 if (odd_bottom && odd_right) {
00186
00187 MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00188
00189
00190 src += src_pitch_pix * (sh-1);
00191 dst_y += dst_pitch_pix * (sh-1);
00192 if (odd_top) {
00193 dst_u += dst_pitch_pix_half * (sh >> 1);
00194 dst_v += dst_pitch_pix_half * (sh >> 1);
00195 }
00196 else {
00197 dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00198 dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00199 }
00200
00201
00202 src += sw - 1;
00203 dst_y += sw - 1;
00204 if (odd_left) {
00205 dst_u += sw >> 1;
00206 dst_v += sw >> 1;
00207 }
00208 else {
00209 dst_u += (sw - 1) >> 1;
00210 dst_v += (sw - 1) >> 1;
00211 }
00212
00213 register unsigned int SRC;
00214 register unsigned int A;
00215
00216
00217 d_u = (*dst_u) * 3;
00218 d_v = (*dst_v) * 3;
00219
00220
00221 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00222
00223
00224 *dst_u = d_u >> 2;
00225 *dst_v = d_v >> 2;
00226
00227
00228 MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00229 }
00230
00231 if (odd_top) {
00232
00233 MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00234
00235
00236 unsigned int *line_end = src + sw;
00237 if (odd_left) {
00238 src++;
00239 dst_y++;
00240 dst_u++;
00241 dst_v++;
00242 line_end--;
00243 }
00244 if (odd_right)
00245 line_end--;
00246
00247
00248 while (src < line_end) {
00249 register unsigned int SRC;
00250 register unsigned int A;
00251
00252
00253 d_u = (*dst_u) << 1;
00254 d_v = (*dst_v) << 1;
00255
00256
00257 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00258 MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00259
00260
00261 *dst_u = d_u >> 2;
00262 *dst_v = d_v >> 2;
00263
00264
00265 src+=2;
00266 dst_y+=2;
00267 dst_u++;
00268 dst_v++;
00269 }
00270
00271
00272 MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00273 }
00274
00275 if (odd_bottom) {
00276
00277 MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00278
00279
00280 src += src_pitch_pix * (sh-1);
00281 dst_y += dst_pitch_pix * (sh-1);
00282 if (odd_top) {
00283 dst_u += dst_pitch_pix_half * (sh >> 1);
00284 dst_v += dst_pitch_pix_half * (sh >> 1);
00285 }
00286 else {
00287 dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00288 dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00289 }
00290
00291 unsigned int *line_end = src + sw;
00292 if (odd_left) {
00293 src++;
00294 dst_y++;
00295 dst_u++;
00296 dst_v++;
00297 line_end--;
00298 }
00299 if (odd_right)
00300 line_end--;
00301
00302
00303 while (src < line_end) {
00304 register unsigned int SRC;
00305 register unsigned int A;
00306
00307
00308 d_u = (*dst_u) << 1;
00309 d_v = (*dst_v) << 1;
00310
00311
00312 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00313 MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00314
00315
00316 *dst_u = d_u >> 2;
00317 *dst_v = d_v >> 2;
00318
00319
00320 src+=2;
00321 dst_y+=2;
00322 dst_u++;
00323 dst_v++;
00324 }
00325
00326
00327 MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00328 }
00329
00330 if (odd_left) {
00331
00332 MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00333
00334
00335 unsigned int *src_end = src + src_pixels;
00336 int src_pitch_diff = src_pitch_pix << 1;
00337 int dst_pitch_diff = dst_pitch_pix << 1;
00338 int dst_pitch_uvdiff = dst_pitch_pix_half;
00339 if (odd_top) {
00340 src += src_pitch_pix;
00341 src_end -= src_pitch_pix;
00342 dst_y += dst_pitch_pix;
00343 dst_u += dst_pitch_pix_half;
00344 dst_v += dst_pitch_pix_half;
00345 }
00346 if (odd_bottom)
00347 src_end -= src_pitch_pix;
00348
00349
00350 while (src < src_end) {
00351
00352 register unsigned int SRC;
00353 register unsigned int A;
00354
00355
00356 d_u = (*dst_u) << 1;
00357 d_v = (*dst_v) << 1;
00358
00359
00360 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00361 MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00362
00363
00364 *dst_u = d_u >> 2;
00365 *dst_v = d_v >> 2;
00366
00367
00368 src += src_pitch_diff;
00369 dst_y += dst_pitch_diff;
00370 dst_u += dst_pitch_uvdiff;
00371 dst_v += dst_pitch_uvdiff;
00372 }
00373
00374
00375 MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00376 }
00377
00378 if (odd_right) {
00379
00380 MMSFB_CONV_ARGB_TO_YV12_PUSHPTR;
00381
00382
00383 unsigned int *src_end = src + src_pixels;
00384 int src_pitch_diff = src_pitch_pix << 1;
00385 int dst_pitch_diff = dst_pitch_pix << 1;
00386 int dst_pitch_uvdiff = dst_pitch_pix_half;
00387 src += sw - 1;
00388 dst_y += sw - 1;
00389 if (odd_left) {
00390 dst_u += sw >> 1;
00391 dst_v += sw >> 1;
00392 }
00393 else {
00394 dst_u += (sw - 1) >> 1;
00395 dst_v += (sw - 1) >> 1;
00396 }
00397 if (odd_top) {
00398 src += src_pitch_pix;
00399 src_end -= src_pitch_pix;
00400 dst_y += dst_pitch_pix;
00401 dst_u += dst_pitch_pix_half;
00402 dst_v += dst_pitch_pix_half;
00403 }
00404 if (odd_bottom)
00405 src_end -= src_pitch_pix;
00406
00407
00408 while (src < src_end) {
00409
00410 register unsigned int SRC;
00411 register unsigned int A;
00412
00413
00414 d_u = (*dst_u) << 1;
00415 d_v = (*dst_v) << 1;
00416
00417
00418 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00419 MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00420
00421
00422 *dst_u = d_u >> 2;
00423 *dst_v = d_v >> 2;
00424
00425
00426 src += src_pitch_diff;
00427 dst_y += dst_pitch_diff;
00428 dst_u += dst_pitch_uvdiff;
00429 dst_v += dst_pitch_uvdiff;
00430 }
00431
00432
00433 MMSFB_CONV_ARGB_TO_YV12_POPPTR;
00434 }
00435 #endif
00436
00437
00438
00439 if (odd_top) {
00440
00441 dy++;
00442 sh--;
00443
00444
00445
00446
00447
00448
00449
00450 dst+=dst_pitch_pix;
00451 src_pixels-=src_pitch_pix;
00452 src_y+=src_pitch;
00453 src_u+=src_pitch >> 1;
00454 src_v+=src_pitch >> 1;
00455
00456 }
00457
00458 if (odd_bottom) {
00459
00460 src_height--;
00461 src_pixels-=src_pitch_pix;
00462 }
00463
00464 if (odd_left) {
00465
00466 dx++;
00467 sw--;
00468 dst++;
00469 src_y++;
00470 src_u++;
00471 src_v++;
00472 }
00473
00474 if (odd_right) {
00475
00476 sw--;
00477 }
00478
00479
00480
00481
00482 unsigned int *src_end = src + src_pixels;
00483 int src_pitch_diff = (src_pitch_pix << 1) - sw;
00484 int dst_pitch_diff = (dst_pitch_pix << 1) - sw;
00485 int dst_pitch_uvdiff = (dst_pitch_pix - sw) >> 1;
00486
00487 // for all lines
00488 while (src < src_end) {
00489 // for all pixels in the line
00490 unsigned int *line_end = src + sw;
00491
00492 // go through two lines in parallel (square 2x2 pixel)
00493 while (src < line_end) {
00494 register unsigned int SRC;
00495 register unsigned int A;
00496
00497 // calculate the four pixels...
00498 MMSFB_CONV_ARGB_TO_YV12_PIXEL(*src, *dst_y, *dst_u, *dst_v, d_u=, d_v=);
00499 MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00500 MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00501 MMSFB_CONV_ARGB_TO_YV12_PIXEL(src[src4_offs], dst_y[dst_y4_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00502
00503 // calulate the arithmetic mean
00504 *dst_u = d_u >> 2;
00505 *dst_v = d_v >> 2;
00506
00507 // go to the next two pixels
00508 src +=2;
00509 dst_y+=2;
00510 dst_u++;
00511 dst_v++;
00512 }
00513
00514 // go to the next two lines
00515 src += src_pitch_diff;
00516 dst_y += dst_pitch_diff;
00517 dst_u += dst_pitch_uvdiff;
00518 dst_v += dst_pitch_uvdiff;
00519 }
00520 */
00521
00522
00523
00524 unsigned char *src_end = src_y + src_pixels;
00525 int dst_pitch_diff = (dst_pitch_pix << 1) - sw;
00526 int src_pitch_diff = (src_pitch_pix << 1) - sw;
00527 int src_pitch_uvdiff = (src_pitch_pix - sw) >> 1;
00528
00529
00530 while (src_y < src_end) {
00531
00532 unsigned char *line_end = src_y + sw;
00533
00534
00535 while (src_y < line_end) {
00536
00537
00538
00539
00540 MMSFB_CONV_YV12_TO_RGB32_PIXEL(*src_y, *src_u, *src_v, *dst);
00541 MMSFB_CONV_YV12_TO_RGB32_PIXEL(src_y[src_y2_offs], *src_u, *src_v, dst[dst2_offs]);
00542 MMSFB_CONV_YV12_TO_RGB32_PIXEL(src_y[src_y3_offs], *src_u, *src_v, dst[dst3_offs]);
00543 MMSFB_CONV_YV12_TO_RGB32_PIXEL(src_y[src_y4_offs], *src_u, *src_v, dst[dst4_offs]);
00544
00545
00546
00547
00548
00549
00550 dst +=2;
00551 src_y+=2;
00552 src_u++;
00553 src_v++;
00554 }
00555
00556
00557 dst += dst_pitch_diff;
00558 src_y += src_pitch_diff;
00559 src_u += src_pitch_uvdiff;
00560 src_v += src_pitch_uvdiff;
00561 }
00562 }
00563
00564 #endif
00565 #endif