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 "mmstools/mmstools.h"
00039
00040 void mmsfb_blit_yuy2_to_yv12(MMSFBSurfacePlanes *src_planes, int src_height, int sx, int sy, int sw, int sh,
00041 MMSFBSurfacePlanes *dst_planes, int dst_height, int dx, int dy) {
00042
00043 static bool firsttime = true;
00044 if (firsttime) {
00045 printf("DISKO: Using accelerated conversion YUY2 to YV12.\n");
00046 firsttime = false;
00047 }
00048
00049
00050 unsigned short int *src = (unsigned short int *)src_planes->ptr;
00051 int src_pitch = src_planes->pitch;
00052
00053
00054 unsigned char *dst = (unsigned char *)dst_planes->ptr;
00055 int dst_pitch = dst_planes->pitch;
00056
00057
00058
00059 if (sx & 0x01) {
00060 sx++;
00061 sw--;
00062 dx++;
00063 }
00064 if (sw & 0x01) {
00065 sw--;
00066 if (dx & 0x01) {
00067 dx++;
00068 }
00069 }
00070 else
00071 if (dx & 0x01) {
00072 dx++;
00073 sw-=2;
00074 }
00075
00076
00077 int src_pitch_pix = src_pitch >> 1;
00078 int dst_pitch_pix = dst_pitch;
00079 int dst_pitch_pix_half = dst_pitch_pix >> 1;
00080
00081 src+= sx + sy * src_pitch_pix;
00082
00083
00084 if (dst_pitch_pix - dx < sw - sx)
00085 sw = dst_pitch_pix - dx - sx;
00086 if (dst_height - dy < sh - sy)
00087 sh = dst_height - dy - sy;
00088 if ((sw <= 0)||(sh <= 0))
00089 return;
00090
00091 int src_pixels = src_pitch_pix * sh;
00092
00093
00094 bool odd_top = (dy & 0x01);
00095 bool odd_bottom = ((dy + sh) & 0x01);
00096
00097
00098 unsigned char *dst_y = dst + dx + dy * dst_pitch_pix;
00099 unsigned char *dst_u;
00100 unsigned char *dst_v;
00101 if ((dst_planes->ptr2)&&(dst_planes->ptr3)) {
00102 dst_u = (unsigned char *)dst_planes->ptr2 + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00103 dst_v = (unsigned char *)dst_planes->ptr3 + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00104 }
00105 else {
00106 dst_u = dst + dst_pitch_pix * dst_height + dst_pitch_pix_half * (dst_height >> 1) + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00107 dst_v = dst + dst_pitch_pix * dst_height + (dx >> 1) + (dy >> 1) * dst_pitch_pix_half;
00108 }
00109
00110
00111 unsigned int dst_y2_offs = 1;
00112 unsigned int dst_y3_offs = dst_pitch;
00113 unsigned int dst_y4_offs = dst_y3_offs + 1;
00114 unsigned int src2_offs = 1;
00115 unsigned int src3_offs = src_pitch_pix;
00116 unsigned int src4_offs = src3_offs + 1;
00117
00118
00119 register unsigned int d_u;
00120 register unsigned int d_v;
00121
00122 if (odd_top) {
00123
00124 MMSFB_CONV_YUY2_TO_YV12_PUSHPTR;
00125
00126
00127 unsigned short int *line_end = src + sw;
00128
00129
00130 while (src < line_end) {
00131 register unsigned short int SRC;
00132
00133
00134 d_u = (*dst_u) << 1;
00135 d_v = (*dst_v) << 1;
00136
00137
00138 MMSFB_CONV_YUY2_TO_YV12_PIXEL_2(*src, *dst_y, d_u+=);
00139 MMSFB_CONV_YUY2_TO_YV12_PIXEL_2(src[src2_offs], dst_y[dst_y2_offs], d_v+=);
00140
00141
00142 *dst_u = d_u >> 2;
00143 *dst_v = d_v >> 2;
00144
00145
00146 src+=2;
00147 dst_y+=2;
00148 dst_u++;
00149 dst_v++;
00150 }
00151
00152
00153 MMSFB_CONV_YUY2_TO_YV12_POPPTR;
00154 }
00155
00156 if (odd_bottom) {
00157
00158 MMSFB_CONV_YUY2_TO_YV12_PUSHPTR;
00159
00160
00161 src += src_pitch_pix * (sh-1);
00162 dst_y += dst_pitch_pix * (sh-1);
00163 if (odd_top) {
00164 dst_u += dst_pitch_pix_half * (sh >> 1);
00165 dst_v += dst_pitch_pix_half * (sh >> 1);
00166 }
00167 else {
00168 dst_u += dst_pitch_pix_half * ((sh-1) >> 1);
00169 dst_v += dst_pitch_pix_half * ((sh-1) >> 1);
00170 }
00171
00172 unsigned short int *line_end = src + sw;
00173
00174
00175 while (src < line_end) {
00176 register unsigned short int SRC;
00177
00178
00179 d_u = (*dst_u) << 1;
00180 d_v = (*dst_v) << 1;
00181
00182
00183 MMSFB_CONV_YUY2_TO_YV12_PIXEL_2(*src, *dst_y, d_u+=);
00184 MMSFB_CONV_YUY2_TO_YV12_PIXEL_2(src[src2_offs], dst_y[dst_y2_offs], d_v+=);
00185
00186
00187 *dst_u = d_u >> 2;
00188 *dst_v = d_v >> 2;
00189
00190
00191 src+=2;
00192 dst_y+=2;
00193 dst_u++;
00194 dst_v++;
00195 }
00196
00197
00198 MMSFB_CONV_YUY2_TO_YV12_POPPTR;
00199 }
00200
00201
00202 if (odd_top) {
00203
00204 dy++;
00205 sh--;
00206 src+=src_pitch_pix;
00207 src_pixels-=src_pitch_pix;
00208 dst_y+=dst_pitch;
00209 dst_u+=dst_pitch >> 1;
00210 dst_v+=dst_pitch >> 1;
00211 }
00212
00213 if (odd_bottom) {
00214
00215 src_height--;
00216 src_pixels-=src_pitch_pix;
00217 }
00218
00219
00220
00221 unsigned short int *src_end = src + src_pixels;
00222 int src_pitch_diff = (src_pitch_pix << 1) - sw;
00223 int dst_pitch_diff = (dst_pitch_pix << 1) - sw;
00224 int dst_pitch_uvdiff = (dst_pitch_pix - sw) >> 1;
00225
00226
00227 while (src < src_end) {
00228
00229 unsigned short int *line_end = src + sw;
00230
00231
00232 while (src < line_end) {
00233 register unsigned short int SRC;
00234
00235
00236 MMSFB_CONV_YUY2_TO_YV12_PIXEL(*src, *dst_y, d_u=);
00237 MMSFB_CONV_YUY2_TO_YV12_PIXEL(src[src2_offs], dst_y[dst_y2_offs], d_v=);
00238 MMSFB_CONV_YUY2_TO_YV12_PIXEL(src[src3_offs], dst_y[dst_y3_offs], d_u+=);
00239 MMSFB_CONV_YUY2_TO_YV12_PIXEL(src[src4_offs], dst_y[dst_y4_offs], d_v+=);
00240
00241
00242 *dst_u = d_u >> 1;
00243 *dst_v = d_v >> 1;
00244
00245
00246 src +=2;
00247 dst_y+=2;
00248 dst_u++;
00249 dst_v++;
00250 }
00251
00252
00253 src += src_pitch_diff;
00254 dst_y += dst_pitch_diff;
00255 dst_u += dst_pitch_uvdiff;
00256 dst_v += dst_pitch_uvdiff;
00257 }
00258 }
00259
00260 #endif
00261 #endif