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_RGB24__
00036 #ifdef __HAVE_PF_YV12__
00037
00038 #include "mmstools/mmstools.h"
00039
00040 void mmsfb_blit_rgb24_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 conversion RGB24 to YV12.\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 src_pitch_pix = src_pitch / 3;
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) * 3;
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 int src_pixels = src_pitch_pix * sh;
00069
00070
00071 bool odd_left = (dx & 0x01);
00072 bool odd_top = (dy & 0x01);
00073 bool odd_right = ((dx + sw) & 0x01);
00074 bool odd_bottom = ((dy + sh) & 0x01);
00075
00076
00077 unsigned char *dst_y = dst + dx + dy * dst_pitch_pix;
00078 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;
00079 unsigned char *dst_v = dst + dst_pitch_pix * dst_height + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00080
00081
00082 unsigned int dst_y2_offs = 1;
00083 unsigned int dst_y3_offs = dst_pitch;
00084 unsigned int dst_y4_offs = dst_y3_offs + 1;
00085 unsigned int src2_offs = 3;
00086 unsigned int src3_offs = src_pitch;
00087 unsigned int src4_offs = src3_offs + 3;
00088
00089
00090 register unsigned int d_u;
00091 register unsigned int d_v;
00092
00093
00094 if (odd_top && odd_left) {
00095
00096
00097 d_u = (*dst_u) * 3;
00098 d_v = (*dst_v) * 3;
00099
00100
00101 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00102
00103
00104 *dst_u = d_u >> 2;
00105 *dst_v = d_v >> 2;
00106 }
00107
00108 if (odd_top && odd_right) {
00109
00110 MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00111
00112
00113 src += (sw - 1) * 3;
00114 dst_y += sw - 1;
00115 if (odd_left) {
00116 dst_u += sw >> 1;
00117 dst_v += sw >> 1;
00118 }
00119 else {
00120 dst_u += (sw - 1) >> 1;
00121 dst_v += (sw - 1) >> 1;
00122 }
00123
00124
00125 d_u = (*dst_u) * 3;
00126 d_v = (*dst_v) * 3;
00127
00128
00129 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00130
00131
00132 *dst_u = d_u >> 2;
00133 *dst_v = d_v >> 2;
00134
00135
00136 MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00137 }
00138
00139 if (odd_bottom && odd_left) {
00140
00141 MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00142
00143
00144 src += (src_pitch_pix * (sh-1)) * 3;
00145 dst_y += dst_pitch_pix * (sh-1);
00146 if (odd_top) {
00147 dst_u += dst_pitch_pix_half * (sh >> 1);
00148 dst_v += dst_pitch_pix_half * (sh >> 1);
00149 }
00150 else {
00151 dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00152 dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00153 }
00154
00155
00156 d_u = (*dst_u) * 3;
00157 d_v = (*dst_v) * 3;
00158
00159
00160 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00161
00162
00163 *dst_u = d_u >> 2;
00164 *dst_v = d_v >> 2;
00165
00166
00167 MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00168 }
00169
00170 if (odd_bottom && odd_right) {
00171
00172 MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00173
00174
00175 src += (src_pitch_pix * (sh-1)) * 3;
00176 dst_y += dst_pitch_pix * (sh-1);
00177 if (odd_top) {
00178 dst_u += dst_pitch_pix_half * (sh >> 1);
00179 dst_v += dst_pitch_pix_half * (sh >> 1);
00180 }
00181 else {
00182 dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00183 dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00184 }
00185
00186
00187 src += (sw - 1) * 3;
00188 dst_y += sw - 1;
00189 if (odd_left) {
00190 dst_u += sw >> 1;
00191 dst_v += sw >> 1;
00192 }
00193 else {
00194 dst_u += (sw - 1) >> 1;
00195 dst_v += (sw - 1) >> 1;
00196 }
00197
00198
00199 d_u = (*dst_u) * 3;
00200 d_v = (*dst_v) * 3;
00201
00202
00203 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00204
00205
00206 *dst_u = d_u >> 2;
00207 *dst_v = d_v >> 2;
00208
00209
00210 MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00211 }
00212
00213 if (odd_top) {
00214
00215 MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00216
00217
00218 unsigned char *line_end = src + sw * 3;
00219 if (odd_left) {
00220 src+=3;
00221 dst_y++;
00222 dst_u++;
00223 dst_v++;
00224 line_end-=3;
00225 }
00226 if (odd_right)
00227 line_end-=3;
00228
00229
00230 while (src < line_end) {
00231
00232 d_u = (*dst_u) << 1;
00233 d_v = (*dst_v) << 1;
00234
00235
00236 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00237 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src2_offs, dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00238
00239
00240 *dst_u = d_u >> 2;
00241 *dst_v = d_v >> 2;
00242
00243
00244 src+=2*3;
00245 dst_y+=2;
00246 dst_u++;
00247 dst_v++;
00248 }
00249
00250
00251 MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00252 }
00253
00254 if (odd_bottom) {
00255
00256 MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00257
00258
00259 src += (src_pitch_pix * (sh-1)) * 3;
00260 dst_y += dst_pitch_pix * (sh-1);
00261 if (odd_top) {
00262 dst_u += dst_pitch_pix_half * (sh >> 1);
00263 dst_v += dst_pitch_pix_half * (sh >> 1);
00264 }
00265 else {
00266 dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00267 dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00268 }
00269
00270 unsigned char *line_end = src + sw * 3;
00271 if (odd_left) {
00272 src+=3;
00273 dst_y++;
00274 dst_u++;
00275 dst_v++;
00276 line_end-=3;
00277 }
00278 if (odd_right)
00279 line_end-=3;
00280
00281
00282 while (src < line_end) {
00283
00284 d_u = (*dst_u) << 1;
00285 d_v = (*dst_v) << 1;
00286
00287
00288 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00289 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src2_offs, dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00290
00291
00292 *dst_u = d_u >> 2;
00293 *dst_v = d_v >> 2;
00294
00295
00296 src+=2*3;
00297 dst_y+=2;
00298 dst_u++;
00299 dst_v++;
00300 }
00301
00302
00303 MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00304 }
00305
00306 if (odd_left) {
00307
00308 MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00309
00310
00311 unsigned char *src_end = src + src_pixels * 3;
00312 int src_pitch_diff = (src_pitch_pix << 1) * 3;
00313 int dst_pitch_diff = dst_pitch_pix << 1;
00314 int dst_pitch_uvdiff = dst_pitch_pix_half;
00315 if (odd_top) {
00316 src += src_pitch_pix * 3;
00317 src_end -= src_pitch_pix * 3;
00318 dst_y += dst_pitch_pix;
00319 dst_u += dst_pitch_pix_half;
00320 dst_v += dst_pitch_pix_half;
00321 }
00322 if (odd_bottom)
00323 src_end -= src_pitch_pix * 3;
00324
00325
00326 while (src < src_end) {
00327
00328
00329 d_u = (*dst_u) << 1;
00330 d_v = (*dst_v) << 1;
00331
00332
00333 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00334 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src3_offs, dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00335
00336
00337 *dst_u = d_u >> 2;
00338 *dst_v = d_v >> 2;
00339
00340
00341 src += src_pitch_diff;
00342 dst_y += dst_pitch_diff;
00343 dst_u += dst_pitch_uvdiff;
00344 dst_v += dst_pitch_uvdiff;
00345 }
00346
00347
00348 MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00349 }
00350
00351 if (odd_right) {
00352
00353 MMSFB_CONV_RGB24_TO_YV12_PUSHPTR;
00354
00355
00356 unsigned char *src_end = src + src_pixels * 3;
00357 int src_pitch_diff = (src_pitch_pix << 1) * 3;
00358 int dst_pitch_diff = dst_pitch_pix << 1;
00359 int dst_pitch_uvdiff = dst_pitch_pix_half;
00360 src += (sw - 1) * 3;
00361 dst_y += sw - 1;
00362 if (odd_left) {
00363 dst_u += sw >> 1;
00364 dst_v += sw >> 1;
00365 }
00366 else {
00367 dst_u += (sw - 1) >> 1;
00368 dst_v += (sw - 1) >> 1;
00369 }
00370 if (odd_top) {
00371 src += src_pitch_pix * 3;
00372 src_end -= src_pitch_pix * 3;
00373 dst_y += dst_pitch_pix;
00374 dst_u += dst_pitch_pix_half;
00375 dst_v += dst_pitch_pix_half;
00376 }
00377 if (odd_bottom)
00378 src_end -= src_pitch_pix * 3;
00379
00380
00381 while (src < src_end) {
00382
00383
00384 d_u = (*dst_u) << 1;
00385 d_v = (*dst_v) << 1;
00386
00387
00388 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u+=, d_v+=);
00389 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src3_offs, dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00390
00391
00392 *dst_u = d_u >> 2;
00393 *dst_v = d_v >> 2;
00394
00395
00396 src += src_pitch_diff;
00397 dst_y += dst_pitch_diff;
00398 dst_u += dst_pitch_uvdiff;
00399 dst_v += dst_pitch_uvdiff;
00400 }
00401
00402
00403 MMSFB_CONV_RGB24_TO_YV12_POPPTR;
00404 }
00405
00406
00407 if (odd_top) {
00408
00409 dy++;
00410 sh--;
00411 src+=src_pitch_pix * 3;
00412 src_pixels-=src_pitch_pix;
00413 dst_y+=dst_pitch;
00414 dst_u+=dst_pitch >> 1;
00415 dst_v+=dst_pitch >> 1;
00416 }
00417
00418 if (odd_bottom) {
00419
00420 src_height--;
00421 src_pixels-=src_pitch_pix;
00422 }
00423
00424 if (odd_left) {
00425
00426 dx++;
00427 sw--;
00428 src+=3;
00429 dst_y++;
00430 dst_u++;
00431 dst_v++;
00432 }
00433
00434 if (odd_right) {
00435
00436 sw--;
00437 }
00438
00439
00440
00441 unsigned char *src_end = src + src_pixels * 3;
00442 int src_pitch_diff = ((src_pitch_pix << 1) - sw) * 3;
00443 int dst_pitch_diff = (dst_pitch_pix << 1) - sw;
00444 int dst_pitch_uvdiff = (dst_pitch_pix - sw) >> 1;
00445 int swb = sw * 3;
00446
00447
00448 while (src < src_end) {
00449
00450 unsigned char *line_end = src + swb;
00451
00452
00453 while (src < line_end) {
00454
00455 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src, *dst_y, *dst_u, *dst_v, d_u=, d_v=);
00456 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src2_offs, dst_y[dst_y2_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00457 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src3_offs, dst_y[dst_y3_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00458 MMSFB_CONV_RGB24_TO_YV12_PIXEL(src+src4_offs, dst_y[dst_y4_offs], *dst_u, *dst_v, d_u+=, d_v+=);
00459
00460
00461 *dst_u = d_u >> 2;
00462 *dst_v = d_v >> 2;
00463
00464
00465 src +=2*3;
00466 dst_y+=2;
00467 dst_u++;
00468 dst_v++;
00469 }
00470
00471
00472 src += src_pitch_diff;
00473 dst_y += dst_pitch_diff;
00474 dst_u += dst_pitch_uvdiff;
00475 dst_v += dst_pitch_uvdiff;
00476 }
00477 }
00478
00479 #endif
00480 #endif