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 #undef MOVNTQ
00030 #undef EMMS
00031 #undef SFENCE
00032
00033 #if HAVE_AMD3DNOW
00034
00035 #define EMMS "femms"
00036 #else
00037 #define EMMS "emms"
00038 #endif
00039
00040 #if HAVE_MMX2
00041 #define MOVNTQ "movntq"
00042 #define SFENCE "sfence"
00043 #else
00044 #define MOVNTQ "movq"
00045 #define SFENCE "/nop"
00046 #endif
00047
00048 #define YUV2RGB \
00049
00050
00051
00052
00053 \
00054 \
00055 "punpcklbw %%mm4, %%mm0;" \
00056 "punpcklbw %%mm4, %%mm1;" \
00057 \
00058 "psllw $3, %%mm0;" \
00059 "psllw $3, %%mm1;" \
00060 \
00061 "psubsw "U_OFFSET"(%4), %%mm0;" \
00062 "psubsw "V_OFFSET"(%4), %%mm1;" \
00063 \
00064 "movq %%mm0, %%mm2;" \
00065 "movq %%mm1, %%mm3;" \
00066 \
00067 "pmulhw "UG_COEFF"(%4), %%mm2;" \
00068 "pmulhw "VG_COEFF"(%4), %%mm3;" \
00069 \
00070 "pmulhw "UB_COEFF"(%4), %%mm0;" \
00071 "pmulhw "VR_COEFF"(%4), %%mm1;" \
00072 \
00073 "paddsw %%mm3, %%mm2;" \
00074 \
00075 \
00076 "movq %%mm6, %%mm7;" \
00077 "pand "MANGLE(mmx_00ffw)", %%mm6;" \
00078 \
00079 "psrlw $8, %%mm7;" \
00080 \
00081 "psllw $3, %%mm6;" \
00082 "psllw $3, %%mm7;" \
00083 \
00084 "psubw "Y_OFFSET"(%4), %%mm6;" \
00085 "psubw "Y_OFFSET"(%4), %%mm7;" \
00086 \
00087 "pmulhw "Y_COEFF"(%4), %%mm6;" \
00088 "pmulhw "Y_COEFF"(%4), %%mm7;" \
00089 \
00090
00091
00092
00093
00094 \
00095 "movq %%mm0, %%mm3;" \
00096 "movq %%mm1, %%mm4;" \
00097 "movq %%mm2, %%mm5;" \
00098 \
00099 "paddsw %%mm6, %%mm0;" \
00100 "paddsw %%mm7, %%mm3;" \
00101 \
00102 "paddsw %%mm6, %%mm1;" \
00103 "paddsw %%mm7, %%mm4;" \
00104 \
00105 "paddsw %%mm6, %%mm2;" \
00106 "paddsw %%mm7, %%mm5;" \
00107 \
00108 \
00109 "packuswb %%mm0, %%mm0;" \
00110 "packuswb %%mm1, %%mm1;" \
00111 "packuswb %%mm2, %%mm2;" \
00112 \
00113 \
00114 "packuswb %%mm3, %%mm3;" \
00115 "packuswb %%mm4, %%mm4;" \
00116 "packuswb %%mm5, %%mm5;" \
00117 \
00118 \
00119 "punpcklbw %%mm3, %%mm0;" \
00120 "punpcklbw %%mm4, %%mm1;" \
00121 "punpcklbw %%mm5, %%mm2;" \
00122
00123
00124 #define YUV422_UNSHIFT \
00125 if(c->srcFormat == PIX_FMT_YUV422P){ \
00126 srcStride[1] *= 2; \
00127 srcStride[2] *= 2; \
00128 } \
00129
00130 #define YUV2RGB_LOOP(depth) \
00131 h_size= (c->dstW+7)&~7; \
00132 if(h_size*depth > FFABS(dstStride[0])) h_size-=8; \
00133 \
00134 __asm__ volatile ("pxor %mm4, %mm4;" ); \
00135 for (y= 0; y<srcSliceH; y++ ) { \
00136 uint8_t *image = dst[0] + (y+srcSliceY)*dstStride[0]; \
00137 uint8_t *py = src[0] + y*srcStride[0]; \
00138 uint8_t *pu = src[1] + (y>>1)*srcStride[1]; \
00139 uint8_t *pv = src[2] + (y>>1)*srcStride[2]; \
00140 long index= -h_size/2; \
00141
00142 #define YUV2RGB_INIT \
00143
00144 \
00145 __asm__ volatile ( \
00146 \
00147 "movd (%2, %0), %%mm0;" \
00148 "movd (%3, %0), %%mm1;" \
00149 "movq (%5, %0, 2), %%mm6;" \
00150
00151
00152 \
00153 "1: \n\t" \
00154
00155
00156
00157
00158
00159 \
00160
00161 #define YUV2RGB_ENDLOOP(depth) \
00162 "add $"AV_STRINGIFY(depth*8)", %1 \n\t" \
00163 "add $4, %0 \n\t" \
00164 " js 1b \n\t" \
00165 \
00166 : "+r" (index), "+r" (image) \
00167 : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), "r" (py - 2*index) \
00168 ); \
00169 } \
00170 __asm__ volatile (EMMS); \
00171 return srcSliceH; \
00172
00173 static inline int RENAME(yuv420_rgb16)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
00174 int srcSliceH, uint8_t* dst[], int dstStride[]){
00175 int y, h_size;
00176
00177 YUV422_UNSHIFT
00178 YUV2RGB_LOOP(2)
00179
00180 c->blueDither= ff_dither8[y&1];
00181 c->greenDither= ff_dither4[y&1];
00182 c->redDither= ff_dither8[(y+1)&1];
00183
00184 YUV2RGB_INIT
00185 YUV2RGB
00186
00187 #ifdef DITHER1XBPP
00188 "paddusb "BLUE_DITHER"(%4), %%mm0;"
00189 "paddusb "GREEN_DITHER"(%4), %%mm2;"
00190 "paddusb "RED_DITHER"(%4), %%mm1;"
00191 #endif
00192
00193 "pand "MANGLE(mmx_redmask)", %%mm0;"
00194 "pand "MANGLE(mmx_grnmask)", %%mm2;"
00195 "pand "MANGLE(mmx_redmask)", %%mm1;"
00196
00197 "psrlw $3, %%mm0;"
00198 "pxor %%mm4, %%mm4;"
00199
00200 "movq %%mm0, %%mm5;"
00201 "movq %%mm2, %%mm7;"
00202
00203
00204 "punpcklbw %%mm4, %%mm2;"
00205 "punpcklbw %%mm1, %%mm0;"
00206
00207 "psllw $3, %%mm2;"
00208 "por %%mm2, %%mm0;"
00209
00210 "movq 8 (%5, %0, 2), %%mm6;"
00211 MOVNTQ " %%mm0, (%1);"
00212
00213
00214 "punpckhbw %%mm4, %%mm7;"
00215 "punpckhbw %%mm1, %%mm5;"
00216
00217 "psllw $3, %%mm7;"
00218 "movd 4 (%2, %0), %%mm0;"
00219
00220 "por %%mm7, %%mm5;"
00221 "movd 4 (%3, %0), %%mm1;"
00222
00223 MOVNTQ " %%mm5, 8 (%1);"
00224
00225 YUV2RGB_ENDLOOP(2)
00226 }
00227
00228 static inline int RENAME(yuv420_rgb15)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
00229 int srcSliceH, uint8_t* dst[], int dstStride[]){
00230 int y, h_size;
00231
00232 YUV422_UNSHIFT
00233 YUV2RGB_LOOP(2)
00234
00235 c->blueDither= ff_dither8[y&1];
00236 c->greenDither= ff_dither8[y&1];
00237 c->redDither= ff_dither8[(y+1)&1];
00238
00239 YUV2RGB_INIT
00240 YUV2RGB
00241
00242 #ifdef DITHER1XBPP
00243 "paddusb "BLUE_DITHER"(%4), %%mm0 \n\t"
00244 "paddusb "GREEN_DITHER"(%4), %%mm2 \n\t"
00245 "paddusb "RED_DITHER"(%4), %%mm1 \n\t"
00246 #endif
00247
00248
00249 "pand "MANGLE(mmx_redmask)", %%mm0;"
00250 "pand "MANGLE(mmx_redmask)", %%mm2;"
00251 "pand "MANGLE(mmx_redmask)", %%mm1;"
00252
00253 "psrlw $3, %%mm0;"
00254 "psrlw $1, %%mm1;"
00255 "pxor %%mm4, %%mm4;"
00256
00257 "movq %%mm0, %%mm5;"
00258 "movq %%mm2, %%mm7;"
00259
00260
00261 "punpcklbw %%mm4, %%mm2;"
00262 "punpcklbw %%mm1, %%mm0;"
00263
00264 "psllw $2, %%mm2;"
00265 "por %%mm2, %%mm0;"
00266
00267 "movq 8 (%5, %0, 2), %%mm6;"
00268 MOVNTQ " %%mm0, (%1);"
00269
00270
00271 "punpckhbw %%mm4, %%mm7;"
00272 "punpckhbw %%mm1, %%mm5;"
00273
00274 "psllw $2, %%mm7;"
00275 "movd 4 (%2, %0), %%mm0;"
00276
00277 "por %%mm7, %%mm5;"
00278 "movd 4 (%3, %0), %%mm1;"
00279
00280 MOVNTQ " %%mm5, 8 (%1);"
00281
00282 YUV2RGB_ENDLOOP(2)
00283 }
00284
00285 static inline int RENAME(yuv420_rgb24)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
00286 int srcSliceH, uint8_t* dst[], int dstStride[]){
00287 int y, h_size;
00288
00289 YUV422_UNSHIFT
00290 YUV2RGB_LOOP(3)
00291
00292 YUV2RGB_INIT
00293 YUV2RGB
00294
00295 #if HAVE_MMX2
00296 "movq "MANGLE(ff_M24A)", %%mm4 \n\t"
00297 "movq "MANGLE(ff_M24C)", %%mm7 \n\t"
00298 "pshufw $0x50, %%mm0, %%mm5 \n\t"
00299 "pshufw $0x50, %%mm2, %%mm3 \n\t"
00300 "pshufw $0x00, %%mm1, %%mm6 \n\t"
00301
00302 "pand %%mm4, %%mm5 \n\t"
00303 "pand %%mm4, %%mm3 \n\t"
00304 "pand %%mm7, %%mm6 \n\t"
00305
00306 "psllq $8, %%mm3 \n\t"
00307 "por %%mm5, %%mm6 \n\t"
00308 "por %%mm3, %%mm6 \n\t"
00309 MOVNTQ" %%mm6, (%1) \n\t"
00310
00311 "psrlq $8, %%mm2 \n\t"
00312 "pshufw $0xA5, %%mm0, %%mm5 \n\t"
00313 "pshufw $0x55, %%mm2, %%mm3 \n\t"
00314 "pshufw $0xA5, %%mm1, %%mm6 \n\t"
00315
00316 "pand "MANGLE(ff_M24B)", %%mm5 \n\t"
00317 "pand %%mm7, %%mm3 \n\t"
00318 "pand %%mm4, %%mm6 \n\t"
00319
00320 "por %%mm5, %%mm3 \n\t"
00321 "por %%mm3, %%mm6 \n\t"
00322 MOVNTQ" %%mm6, 8(%1) \n\t"
00323
00324 "pshufw $0xFF, %%mm0, %%mm5 \n\t"
00325 "pshufw $0xFA, %%mm2, %%mm3 \n\t"
00326 "pshufw $0xFA, %%mm1, %%mm6 \n\t"
00327 "movd 4 (%2, %0), %%mm0;"
00328
00329 "pand %%mm7, %%mm5 \n\t"
00330 "pand %%mm4, %%mm3 \n\t"
00331 "pand "MANGLE(ff_M24B)", %%mm6 \n\t"
00332 "movd 4 (%3, %0), %%mm1;"
00333 \
00334 "por %%mm5, %%mm3 \n\t"
00335 "por %%mm3, %%mm6 \n\t"
00336 MOVNTQ" %%mm6, 16(%1) \n\t"
00337 "movq 8 (%5, %0, 2), %%mm6;"
00338 "pxor %%mm4, %%mm4 \n\t"
00339
00340 #else
00341
00342 "pxor %%mm4, %%mm4 \n\t"
00343 "movq %%mm0, %%mm5 \n\t"
00344 "movq %%mm1, %%mm6 \n\t"
00345 "punpcklbw %%mm2, %%mm0 \n\t"
00346 "punpcklbw %%mm4, %%mm1 \n\t"
00347 "punpckhbw %%mm2, %%mm5 \n\t"
00348 "punpckhbw %%mm4, %%mm6 \n\t"
00349 "movq %%mm0, %%mm7 \n\t"
00350 "movq %%mm5, %%mm3 \n\t"
00351 "punpcklwd %%mm1, %%mm7 \n\t"
00352 "punpckhwd %%mm1, %%mm0 \n\t"
00353 "punpcklwd %%mm6, %%mm5 \n\t"
00354 "punpckhwd %%mm6, %%mm3 \n\t"
00355
00356 "movq %%mm7, %%mm2 \n\t"
00357 "movq %%mm0, %%mm6 \n\t"
00358 "movq %%mm5, %%mm1 \n\t"
00359 "movq %%mm3, %%mm4 \n\t"
00360
00361 "psllq $40, %%mm7 \n\t"
00362 "psllq $40, %%mm0 \n\t"
00363 "psllq $40, %%mm5 \n\t"
00364 "psllq $40, %%mm3 \n\t"
00365
00366 "punpckhdq %%mm2, %%mm7 \n\t"
00367 "punpckhdq %%mm6, %%mm0 \n\t"
00368 "punpckhdq %%mm1, %%mm5 \n\t"
00369 "punpckhdq %%mm4, %%mm3 \n\t"
00370
00371 "psrlq $8, %%mm7 \n\t"
00372 "movq %%mm0, %%mm6 \n\t"
00373 "psllq $40, %%mm0 \n\t"
00374 "por %%mm0, %%mm7 \n\t"
00375 MOVNTQ" %%mm7, (%1) \n\t"
00376
00377 "movd 4 (%2, %0), %%mm0;"
00378
00379 "psrlq $24, %%mm6 \n\t"
00380 "movq %%mm5, %%mm1 \n\t"
00381 "psllq $24, %%mm5 \n\t"
00382 "por %%mm5, %%mm6 \n\t"
00383 MOVNTQ" %%mm6, 8(%1) \n\t"
00384
00385 "movq 8 (%5, %0, 2), %%mm6;"
00386
00387 "psrlq $40, %%mm1 \n\t"
00388 "psllq $8, %%mm3 \n\t"
00389 "por %%mm3, %%mm1 \n\t"
00390 MOVNTQ" %%mm1, 16(%1) \n\t"
00391
00392 "movd 4 (%3, %0), %%mm1;"
00393 "pxor %%mm4, %%mm4 \n\t"
00394 #endif
00395
00396 YUV2RGB_ENDLOOP(3)
00397 }
00398
00399 #define RGB_PLANAR2PACKED32 \
00400
00401
00402
00403 \
00404 "movq %%mm0, %%mm6;" \
00405 "movq %%mm1, %%mm7;" \
00406 \
00407 "movq %%mm0, %%mm4;" \
00408 "movq %%mm1, %%mm5;" \
00409 \
00410 "punpcklbw %%mm2, %%mm6;" \
00411 "punpcklbw %%mm3, %%mm7;" \
00412 \
00413 "punpcklwd %%mm7, %%mm6;" \
00414 MOVNTQ " %%mm6, (%1);" \
00415 \
00416 "movq %%mm0, %%mm6;" \
00417 "punpcklbw %%mm2, %%mm6;" \
00418 \
00419 "punpckhwd %%mm7, %%mm6;" \
00420 MOVNTQ " %%mm6, 8 (%1);" \
00421 \
00422 "punpckhbw %%mm2, %%mm4;" \
00423 "punpckhbw %%mm3, %%mm5;" \
00424 \
00425 "punpcklwd %%mm5, %%mm4;" \
00426 MOVNTQ " %%mm4, 16 (%1);" \
00427 \
00428 "movq %%mm0, %%mm4;" \
00429 "punpckhbw %%mm2, %%mm4;" \
00430 \
00431 "punpckhwd %%mm5, %%mm4;" \
00432 MOVNTQ " %%mm4, 24 (%1);" \
00433 \
00434 "movd 4 (%2, %0), %%mm0;" \
00435 "movd 4 (%3, %0), %%mm1;" \
00436 \
00437 "pxor %%mm4, %%mm4;" \
00438 "movq 8 (%5, %0, 2), %%mm6;" \
00439
00440 static inline int RENAME(yuv420_rgb32)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
00441 int srcSliceH, uint8_t* dst[], int dstStride[]){
00442 int y, h_size;
00443
00444 YUV422_UNSHIFT
00445 YUV2RGB_LOOP(4)
00446
00447 YUV2RGB_INIT
00448 YUV2RGB
00449 "pcmpeqd %%mm3, %%mm3;"
00450 RGB_PLANAR2PACKED32
00451
00452 YUV2RGB_ENDLOOP(4)
00453 }