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
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #define _SVID_SOURCE //needed for MAP_ANONYMOUS
00058 #include <inttypes.h>
00059 #include <string.h>
00060 #include <math.h>
00061 #include <stdio.h>
00062 #include <unistd.h>
00063 #include "config.h"
00064 #include <assert.h>
00065 #if HAVE_SYS_MMAN_H
00066 #include <sys/mman.h>
00067 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
00068 #define MAP_ANONYMOUS MAP_ANON
00069 #endif
00070 #endif
00071 #include "swscale.h"
00072 #include "swscale_internal.h"
00073 #include "rgb2rgb.h"
00074 #include "libavutil/x86_cpu.h"
00075 #include "libavutil/bswap.h"
00076
00077 unsigned swscale_version(void)
00078 {
00079 return LIBSWSCALE_VERSION_INT;
00080 }
00081
00082 #undef MOVNTQ
00083 #undef PAVGB
00084
00085
00086
00087
00088
00089
00090 #define DITHER1XBPP
00091
00092 #define FAST_BGR2YV12 // use 7 bit coefficients instead of 15 bit
00093
00094 #define RET 0xC3 //near return opcode for x86
00095
00096 #ifdef M_PI
00097 #define PI M_PI
00098 #else
00099 #define PI 3.14159265358979323846
00100 #endif
00101
00102 #define isSupportedIn(x) ( \
00103 (x)==PIX_FMT_YUV420P \
00104 || (x)==PIX_FMT_YUVA420P \
00105 || (x)==PIX_FMT_YUYV422 \
00106 || (x)==PIX_FMT_UYVY422 \
00107 || (x)==PIX_FMT_RGB32 \
00108 || (x)==PIX_FMT_RGB32_1 \
00109 || (x)==PIX_FMT_BGR24 \
00110 || (x)==PIX_FMT_BGR565 \
00111 || (x)==PIX_FMT_BGR555 \
00112 || (x)==PIX_FMT_BGR32 \
00113 || (x)==PIX_FMT_BGR32_1 \
00114 || (x)==PIX_FMT_RGB24 \
00115 || (x)==PIX_FMT_RGB565 \
00116 || (x)==PIX_FMT_RGB555 \
00117 || (x)==PIX_FMT_GRAY8 \
00118 || (x)==PIX_FMT_YUV410P \
00119 || (x)==PIX_FMT_YUV440P \
00120 || (x)==PIX_FMT_GRAY16BE \
00121 || (x)==PIX_FMT_GRAY16LE \
00122 || (x)==PIX_FMT_YUV444P \
00123 || (x)==PIX_FMT_YUV422P \
00124 || (x)==PIX_FMT_YUV411P \
00125 || (x)==PIX_FMT_PAL8 \
00126 || (x)==PIX_FMT_BGR8 \
00127 || (x)==PIX_FMT_RGB8 \
00128 || (x)==PIX_FMT_BGR4_BYTE \
00129 || (x)==PIX_FMT_RGB4_BYTE \
00130 || (x)==PIX_FMT_YUV440P \
00131 || (x)==PIX_FMT_MONOWHITE \
00132 || (x)==PIX_FMT_MONOBLACK \
00133 )
00134 #define isSupportedOut(x) ( \
00135 (x)==PIX_FMT_YUV420P \
00136 || (x)==PIX_FMT_YUYV422 \
00137 || (x)==PIX_FMT_UYVY422 \
00138 || (x)==PIX_FMT_YUV444P \
00139 || (x)==PIX_FMT_YUV422P \
00140 || (x)==PIX_FMT_YUV411P \
00141 || isRGB(x) \
00142 || isBGR(x) \
00143 || (x)==PIX_FMT_NV12 \
00144 || (x)==PIX_FMT_NV21 \
00145 || (x)==PIX_FMT_GRAY16BE \
00146 || (x)==PIX_FMT_GRAY16LE \
00147 || (x)==PIX_FMT_GRAY8 \
00148 || (x)==PIX_FMT_YUV410P \
00149 || (x)==PIX_FMT_YUV440P \
00150 )
00151 #define isPacked(x) ( \
00152 (x)==PIX_FMT_PAL8 \
00153 || (x)==PIX_FMT_YUYV422 \
00154 || (x)==PIX_FMT_UYVY422 \
00155 || isRGB(x) \
00156 || isBGR(x) \
00157 )
00158 #define usePal(x) ( \
00159 (x)==PIX_FMT_PAL8 \
00160 || (x)==PIX_FMT_BGR4_BYTE \
00161 || (x)==PIX_FMT_RGB4_BYTE \
00162 || (x)==PIX_FMT_BGR8 \
00163 || (x)==PIX_FMT_RGB8 \
00164 )
00165
00166 #define RGB2YUV_SHIFT 15
00167 #define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
00168 #define BV (-(int)(0.081*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00169 #define BU ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00170 #define GY ( (int)(0.587*219/255*(1<<RGB2YUV_SHIFT)+0.5))
00171 #define GV (-(int)(0.419*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00172 #define GU (-(int)(0.331*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00173 #define RY ( (int)(0.299*219/255*(1<<RGB2YUV_SHIFT)+0.5))
00174 #define RV ( (int)(0.500*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00175 #define RU (-(int)(0.169*224/255*(1<<RGB2YUV_SHIFT)+0.5))
00176
00177 extern const int32_t ff_yuv2rgb_coeffs[8][4];
00178
00179 static const double rgb2yuv_table[8][9]={
00180 {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5},
00181 {0.7152, 0.0722, 0.2126, -0.386, 0.5, -0.115, -0.454, -0.046, 0.5},
00182 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5},
00183 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5},
00184 {0.59 , 0.11 , 0.30 , -0.331, 0.5, -0.169, -0.421, -0.079, 0.5},
00185 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5},
00186 {0.587 , 0.114 , 0.299 , -0.331, 0.5, -0.169, -0.419, -0.081, 0.5},
00187 {0.701 , 0.087 , 0.212 , -0.384, 0.5 -0.116, -0.445, -0.055, 0.5},
00188 };
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 #if ARCH_X86 && CONFIG_GPL
00206 DECLARE_ASM_CONST(8, uint64_t, bF8)= 0xF8F8F8F8F8F8F8F8LL;
00207 DECLARE_ASM_CONST(8, uint64_t, bFC)= 0xFCFCFCFCFCFCFCFCLL;
00208 DECLARE_ASM_CONST(8, uint64_t, w10)= 0x0010001000100010LL;
00209 DECLARE_ASM_CONST(8, uint64_t, w02)= 0x0002000200020002LL;
00210 DECLARE_ASM_CONST(8, uint64_t, bm00001111)=0x00000000FFFFFFFFLL;
00211 DECLARE_ASM_CONST(8, uint64_t, bm00000111)=0x0000000000FFFFFFLL;
00212 DECLARE_ASM_CONST(8, uint64_t, bm11111000)=0xFFFFFFFFFF000000LL;
00213 DECLARE_ASM_CONST(8, uint64_t, bm01010101)=0x00FF00FF00FF00FFLL;
00214
00215 const DECLARE_ALIGNED(8, uint64_t, ff_dither4[2]) = {
00216 0x0103010301030103LL,
00217 0x0200020002000200LL,};
00218
00219 const DECLARE_ALIGNED(8, uint64_t, ff_dither8[2]) = {
00220 0x0602060206020602LL,
00221 0x0004000400040004LL,};
00222
00223 DECLARE_ASM_CONST(8, uint64_t, b16Mask)= 0x001F001F001F001FLL;
00224 DECLARE_ASM_CONST(8, uint64_t, g16Mask)= 0x07E007E007E007E0LL;
00225 DECLARE_ASM_CONST(8, uint64_t, r16Mask)= 0xF800F800F800F800LL;
00226 DECLARE_ASM_CONST(8, uint64_t, b15Mask)= 0x001F001F001F001FLL;
00227 DECLARE_ASM_CONST(8, uint64_t, g15Mask)= 0x03E003E003E003E0LL;
00228 DECLARE_ASM_CONST(8, uint64_t, r15Mask)= 0x7C007C007C007C00LL;
00229
00230 DECLARE_ALIGNED(8, const uint64_t, ff_M24A) = 0x00FF0000FF0000FFLL;
00231 DECLARE_ALIGNED(8, const uint64_t, ff_M24B) = 0xFF0000FF0000FF00LL;
00232 DECLARE_ALIGNED(8, const uint64_t, ff_M24C) = 0x0000FF0000FF0000LL;
00233
00234 #ifdef FAST_BGR2YV12
00235 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YCoeff) = 0x000000210041000DULL;
00236 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UCoeff) = 0x0000FFEEFFDC0038ULL;
00237 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2VCoeff) = 0x00000038FFD2FFF8ULL;
00238 #else
00239 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YCoeff) = 0x000020E540830C8BULL;
00240 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UCoeff) = 0x0000ED0FDAC23831ULL;
00241 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2VCoeff) = 0x00003831D0E6F6EAULL;
00242 #endif
00243 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2YOffset) = 0x1010101010101010ULL;
00244 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UVOffset) = 0x8080808080808080ULL;
00245 DECLARE_ALIGNED(8, const uint64_t, ff_w1111) = 0x0001000100010001ULL;
00246
00247 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY1Coeff) = 0x0C88000040870C88ULL;
00248 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toY2Coeff) = 0x20DE4087000020DEULL;
00249 DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY1Coeff) = 0x20DE0000408720DEULL;
00250 DECLARE_ASM_CONST(8, uint64_t, ff_rgb24toY2Coeff) = 0x0C88408700000C88ULL;
00251 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toYOffset) = 0x0008400000084000ULL;
00252
00253 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUV[2][4]) = {
00254 {0x38380000DAC83838ULL, 0xECFFDAC80000ECFFULL, 0xF6E40000D0E3F6E4ULL, 0x3838D0E300003838ULL},
00255 {0xECFF0000DAC8ECFFULL, 0x3838DAC800003838ULL, 0x38380000D0E33838ULL, 0xF6E4D0E30000F6E4ULL},
00256 };
00257
00258 DECLARE_ASM_CONST(8, uint64_t, ff_bgr24toUVOffset)= 0x0040400000404000ULL;
00259
00260 #endif
00261
00262
00263 static unsigned char clip_table[768];
00264
00265 static SwsVector *sws_getConvVec(SwsVector *a, SwsVector *b);
00266
00267 static const uint8_t __attribute__((aligned(8))) dither_2x2_4[2][8]={
00268 { 1, 3, 1, 3, 1, 3, 1, 3, },
00269 { 2, 0, 2, 0, 2, 0, 2, 0, },
00270 };
00271
00272 static const uint8_t __attribute__((aligned(8))) dither_2x2_8[2][8]={
00273 { 6, 2, 6, 2, 6, 2, 6, 2, },
00274 { 0, 4, 0, 4, 0, 4, 0, 4, },
00275 };
00276
00277 const uint8_t __attribute__((aligned(8))) dither_8x8_32[8][8]={
00278 { 17, 9, 23, 15, 16, 8, 22, 14, },
00279 { 5, 29, 3, 27, 4, 28, 2, 26, },
00280 { 21, 13, 19, 11, 20, 12, 18, 10, },
00281 { 0, 24, 6, 30, 1, 25, 7, 31, },
00282 { 16, 8, 22, 14, 17, 9, 23, 15, },
00283 { 4, 28, 2, 26, 5, 29, 3, 27, },
00284 { 20, 12, 18, 10, 21, 13, 19, 11, },
00285 { 1, 25, 7, 31, 0, 24, 6, 30, },
00286 };
00287
00288 #if 0
00289 const uint8_t __attribute__((aligned(8))) dither_8x8_64[8][8]={
00290 { 0, 48, 12, 60, 3, 51, 15, 63, },
00291 { 32, 16, 44, 28, 35, 19, 47, 31, },
00292 { 8, 56, 4, 52, 11, 59, 7, 55, },
00293 { 40, 24, 36, 20, 43, 27, 39, 23, },
00294 { 2, 50, 14, 62, 1, 49, 13, 61, },
00295 { 34, 18, 46, 30, 33, 17, 45, 29, },
00296 { 10, 58, 6, 54, 9, 57, 5, 53, },
00297 { 42, 26, 38, 22, 41, 25, 37, 21, },
00298 };
00299 #endif
00300
00301 const uint8_t __attribute__((aligned(8))) dither_8x8_73[8][8]={
00302 { 0, 55, 14, 68, 3, 58, 17, 72, },
00303 { 37, 18, 50, 32, 40, 22, 54, 35, },
00304 { 9, 64, 5, 59, 13, 67, 8, 63, },
00305 { 46, 27, 41, 23, 49, 31, 44, 26, },
00306 { 2, 57, 16, 71, 1, 56, 15, 70, },
00307 { 39, 21, 52, 34, 38, 19, 51, 33, },
00308 { 11, 66, 7, 62, 10, 65, 6, 60, },
00309 { 48, 30, 43, 25, 47, 29, 42, 24, },
00310 };
00311
00312 #if 0
00313 const uint8_t __attribute__((aligned(8))) dither_8x8_128[8][8]={
00314 { 68, 36, 92, 60, 66, 34, 90, 58, },
00315 { 20, 116, 12, 108, 18, 114, 10, 106, },
00316 { 84, 52, 76, 44, 82, 50, 74, 42, },
00317 { 0, 96, 24, 120, 6, 102, 30, 126, },
00318 { 64, 32, 88, 56, 70, 38, 94, 62, },
00319 { 16, 112, 8, 104, 22, 118, 14, 110, },
00320 { 80, 48, 72, 40, 86, 54, 78, 46, },
00321 { 4, 100, 28, 124, 2, 98, 26, 122, },
00322 };
00323 #endif
00324
00325 #if 1
00326 const uint8_t __attribute__((aligned(8))) dither_8x8_220[8][8]={
00327 {117, 62, 158, 103, 113, 58, 155, 100, },
00328 { 34, 199, 21, 186, 31, 196, 17, 182, },
00329 {144, 89, 131, 76, 141, 86, 127, 72, },
00330 { 0, 165, 41, 206, 10, 175, 52, 217, },
00331 {110, 55, 151, 96, 120, 65, 162, 107, },
00332 { 28, 193, 14, 179, 38, 203, 24, 189, },
00333 {138, 83, 124, 69, 148, 93, 134, 79, },
00334 { 7, 172, 48, 213, 3, 168, 45, 210, },
00335 };
00336 #elif 1
00337
00338 const uint8_t __attribute__((aligned(8))) dither_8x8_220[8][8]={
00339 { 0, 143, 18, 200, 2, 156, 25, 215, },
00340 { 78, 28, 125, 64, 89, 36, 138, 74, },
00341 { 10, 180, 3, 161, 16, 195, 8, 175, },
00342 {109, 51, 93, 38, 121, 60, 105, 47, },
00343 { 1, 152, 23, 210, 0, 147, 20, 205, },
00344 { 85, 33, 134, 71, 81, 30, 130, 67, },
00345 { 14, 190, 6, 171, 12, 185, 5, 166, },
00346 {117, 57, 101, 44, 113, 54, 97, 41, },
00347 };
00348 #elif 1
00349
00350 const uint8_t __attribute__((aligned(8))) dither_8x8_220[8][8]={
00351 { 0, 124, 8, 193, 0, 140, 12, 213, },
00352 { 55, 14, 104, 42, 66, 19, 119, 52, },
00353 { 3, 168, 1, 145, 6, 187, 3, 162, },
00354 { 86, 31, 70, 21, 99, 39, 82, 28, },
00355 { 0, 134, 11, 206, 0, 129, 9, 200, },
00356 { 62, 17, 114, 48, 58, 16, 109, 45, },
00357 { 5, 181, 2, 157, 4, 175, 1, 151, },
00358 { 95, 36, 78, 26, 90, 34, 74, 24, },
00359 };
00360 #else
00361
00362 const uint8_t __attribute__((aligned(8))) dither_8x8_220[8][8]={
00363 { 0, 107, 3, 187, 0, 125, 6, 212, },
00364 { 39, 7, 86, 28, 49, 11, 102, 36, },
00365 { 1, 158, 0, 131, 3, 180, 1, 151, },
00366 { 68, 19, 52, 12, 81, 25, 64, 17, },
00367 { 0, 119, 5, 203, 0, 113, 4, 195, },
00368 { 45, 9, 96, 33, 42, 8, 91, 30, },
00369 { 2, 172, 1, 144, 2, 165, 0, 137, },
00370 { 77, 23, 60, 15, 72, 21, 56, 14, },
00371 };
00372 #endif
00373
00374 const char *sws_format_name(enum PixelFormat format)
00375 {
00376 switch (format) {
00377 case PIX_FMT_YUV420P:
00378 return "yuv420p";
00379 case PIX_FMT_YUVA420P:
00380 return "yuva420p";
00381 case PIX_FMT_YUYV422:
00382 return "yuyv422";
00383 case PIX_FMT_RGB24:
00384 return "rgb24";
00385 case PIX_FMT_BGR24:
00386 return "bgr24";
00387 case PIX_FMT_YUV422P:
00388 return "yuv422p";
00389 case PIX_FMT_YUV444P:
00390 return "yuv444p";
00391 case PIX_FMT_RGB32:
00392 return "rgb32";
00393 case PIX_FMT_YUV410P:
00394 return "yuv410p";
00395 case PIX_FMT_YUV411P:
00396 return "yuv411p";
00397 case PIX_FMT_RGB565:
00398 return "rgb565";
00399 case PIX_FMT_RGB555:
00400 return "rgb555";
00401 case PIX_FMT_GRAY16BE:
00402 return "gray16be";
00403 case PIX_FMT_GRAY16LE:
00404 return "gray16le";
00405 case PIX_FMT_GRAY8:
00406 return "gray8";
00407 case PIX_FMT_MONOWHITE:
00408 return "mono white";
00409 case PIX_FMT_MONOBLACK:
00410 return "mono black";
00411 case PIX_FMT_PAL8:
00412 return "Palette";
00413 case PIX_FMT_YUVJ420P:
00414 return "yuvj420p";
00415 case PIX_FMT_YUVJ422P:
00416 return "yuvj422p";
00417 case PIX_FMT_YUVJ444P:
00418 return "yuvj444p";
00419 case PIX_FMT_XVMC_MPEG2_MC:
00420 return "xvmc_mpeg2_mc";
00421 case PIX_FMT_XVMC_MPEG2_IDCT:
00422 return "xvmc_mpeg2_idct";
00423 case PIX_FMT_UYVY422:
00424 return "uyvy422";
00425 case PIX_FMT_UYYVYY411:
00426 return "uyyvyy411";
00427 case PIX_FMT_RGB32_1:
00428 return "rgb32x";
00429 case PIX_FMT_BGR32_1:
00430 return "bgr32x";
00431 case PIX_FMT_BGR32:
00432 return "bgr32";
00433 case PIX_FMT_BGR565:
00434 return "bgr565";
00435 case PIX_FMT_BGR555:
00436 return "bgr555";
00437 case PIX_FMT_BGR8:
00438 return "bgr8";
00439 case PIX_FMT_BGR4:
00440 return "bgr4";
00441 case PIX_FMT_BGR4_BYTE:
00442 return "bgr4 byte";
00443 case PIX_FMT_RGB8:
00444 return "rgb8";
00445 case PIX_FMT_RGB4:
00446 return "rgb4";
00447 case PIX_FMT_RGB4_BYTE:
00448 return "rgb4 byte";
00449 case PIX_FMT_NV12:
00450 return "nv12";
00451 case PIX_FMT_NV21:
00452 return "nv21";
00453 case PIX_FMT_YUV440P:
00454 return "yuv440p";
00455 case PIX_FMT_VDPAU_H264:
00456 return "vdpau_h264";
00457 case PIX_FMT_VDPAU_MPEG1:
00458 return "vdpau_mpeg1";
00459 case PIX_FMT_VDPAU_MPEG2:
00460 return "vdpau_mpeg2";
00461 case PIX_FMT_VDPAU_WMV3:
00462 return "vdpau_wmv3";
00463 case PIX_FMT_VDPAU_VC1:
00464 return "vdpau_vc1";
00465 default:
00466 return "Unknown format";
00467 }
00468 }
00469
00470 static inline void yuv2yuvXinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
00471 int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
00472 uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)
00473 {
00474
00475 int i;
00476 for (i=0; i<dstW; i++)
00477 {
00478 int val=1<<18;
00479 int j;
00480 for (j=0; j<lumFilterSize; j++)
00481 val += lumSrc[j][i] * lumFilter[j];
00482
00483 dest[i]= av_clip_uint8(val>>19);
00484 }
00485
00486 if (uDest)
00487 for (i=0; i<chrDstW; i++)
00488 {
00489 int u=1<<18;
00490 int v=1<<18;
00491 int j;
00492 for (j=0; j<chrFilterSize; j++)
00493 {
00494 u += chrSrc[j][i] * chrFilter[j];
00495 v += chrSrc[j][i + VOFW] * chrFilter[j];
00496 }
00497
00498 uDest[i]= av_clip_uint8(u>>19);
00499 vDest[i]= av_clip_uint8(v>>19);
00500 }
00501 }
00502
00503 static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
00504 int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
00505 uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
00506 {
00507
00508 int i;
00509 for (i=0; i<dstW; i++)
00510 {
00511 int val=1<<18;
00512 int j;
00513 for (j=0; j<lumFilterSize; j++)
00514 val += lumSrc[j][i] * lumFilter[j];
00515
00516 dest[i]= av_clip_uint8(val>>19);
00517 }
00518
00519 if (!uDest)
00520 return;
00521
00522 if (dstFormat == PIX_FMT_NV12)
00523 for (i=0; i<chrDstW; i++)
00524 {
00525 int u=1<<18;
00526 int v=1<<18;
00527 int j;
00528 for (j=0; j<chrFilterSize; j++)
00529 {
00530 u += chrSrc[j][i] * chrFilter[j];
00531 v += chrSrc[j][i + VOFW] * chrFilter[j];
00532 }
00533
00534 uDest[2*i]= av_clip_uint8(u>>19);
00535 uDest[2*i+1]= av_clip_uint8(v>>19);
00536 }
00537 else
00538 for (i=0; i<chrDstW; i++)
00539 {
00540 int u=1<<18;
00541 int v=1<<18;
00542 int j;
00543 for (j=0; j<chrFilterSize; j++)
00544 {
00545 u += chrSrc[j][i] * chrFilter[j];
00546 v += chrSrc[j][i + VOFW] * chrFilter[j];
00547 }
00548
00549 uDest[2*i]= av_clip_uint8(v>>19);
00550 uDest[2*i+1]= av_clip_uint8(u>>19);
00551 }
00552 }
00553
00554 #define YSCALE_YUV_2_PACKEDX_NOCLIP_C(type) \
00555 for (i=0; i<(dstW>>1); i++){\
00556 int j;\
00557 int Y1 = 1<<18;\
00558 int Y2 = 1<<18;\
00559 int U = 1<<18;\
00560 int V = 1<<18;\
00561 type av_unused *r, *b, *g;\
00562 const int i2= 2*i;\
00563 \
00564 for (j=0; j<lumFilterSize; j++)\
00565 {\
00566 Y1 += lumSrc[j][i2] * lumFilter[j];\
00567 Y2 += lumSrc[j][i2+1] * lumFilter[j];\
00568 }\
00569 for (j=0; j<chrFilterSize; j++)\
00570 {\
00571 U += chrSrc[j][i] * chrFilter[j];\
00572 V += chrSrc[j][i+VOFW] * chrFilter[j];\
00573 }\
00574 Y1>>=19;\
00575 Y2>>=19;\
00576 U >>=19;\
00577 V >>=19;\
00578
00579 #define YSCALE_YUV_2_PACKEDX_C(type) \
00580 YSCALE_YUV_2_PACKEDX_NOCLIP_C(type)\
00581 if ((Y1|Y2|U|V)&256)\
00582 {\
00583 if (Y1>255) Y1=255; \
00584 else if (Y1<0)Y1=0; \
00585 if (Y2>255) Y2=255; \
00586 else if (Y2<0)Y2=0; \
00587 if (U>255) U=255; \
00588 else if (U<0) U=0; \
00589 if (V>255) V=255; \
00590 else if (V<0) V=0; \
00591 }
00592
00593 #define YSCALE_YUV_2_PACKEDX_FULL_C \
00594 for (i=0; i<dstW; i++){\
00595 int j;\
00596 int Y = 0;\
00597 int U = -128<<19;\
00598 int V = -128<<19;\
00599 int R,G,B;\
00600 \
00601 for (j=0; j<lumFilterSize; j++){\
00602 Y += lumSrc[j][i ] * lumFilter[j];\
00603 }\
00604 for (j=0; j<chrFilterSize; j++){\
00605 U += chrSrc[j][i ] * chrFilter[j];\
00606 V += chrSrc[j][i+VOFW] * chrFilter[j];\
00607 }\
00608 Y >>=10;\
00609 U >>=10;\
00610 V >>=10;\
00611
00612 #define YSCALE_YUV_2_RGBX_FULL_C(rnd) \
00613 YSCALE_YUV_2_PACKEDX_FULL_C\
00614 Y-= c->yuv2rgb_y_offset;\
00615 Y*= c->yuv2rgb_y_coeff;\
00616 Y+= rnd;\
00617 R= Y + V*c->yuv2rgb_v2r_coeff;\
00618 G= Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;\
00619 B= Y + U*c->yuv2rgb_u2b_coeff;\
00620 if ((R|G|B)&(0xC0000000)){\
00621 if (R>=(256<<22)) R=(256<<22)-1; \
00622 else if (R<0)R=0; \
00623 if (G>=(256<<22)) G=(256<<22)-1; \
00624 else if (G<0)G=0; \
00625 if (B>=(256<<22)) B=(256<<22)-1; \
00626 else if (B<0)B=0; \
00627 }\
00628
00629
00630 #define YSCALE_YUV_2_GRAY16_C \
00631 for (i=0; i<(dstW>>1); i++){\
00632 int j;\
00633 int Y1 = 1<<18;\
00634 int Y2 = 1<<18;\
00635 int U = 1<<18;\
00636 int V = 1<<18;\
00637 \
00638 const int i2= 2*i;\
00639 \
00640 for (j=0; j<lumFilterSize; j++)\
00641 {\
00642 Y1 += lumSrc[j][i2] * lumFilter[j];\
00643 Y2 += lumSrc[j][i2+1] * lumFilter[j];\
00644 }\
00645 Y1>>=11;\
00646 Y2>>=11;\
00647 if ((Y1|Y2|U|V)&65536)\
00648 {\
00649 if (Y1>65535) Y1=65535; \
00650 else if (Y1<0)Y1=0; \
00651 if (Y2>65535) Y2=65535; \
00652 else if (Y2<0)Y2=0; \
00653 }
00654
00655 #define YSCALE_YUV_2_RGBX_C(type) \
00656 YSCALE_YUV_2_PACKEDX_C(type) \
00657 r = (type *)c->table_rV[V]; \
00658 g = (type *)(c->table_gU[U] + c->table_gV[V]); \
00659 b = (type *)c->table_bU[U]; \
00660
00661 #define YSCALE_YUV_2_PACKED2_C \
00662 for (i=0; i<(dstW>>1); i++){ \
00663 const int i2= 2*i; \
00664 int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>19; \
00665 int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>19; \
00666 int U= (uvbuf0[i ]*uvalpha1+uvbuf1[i ]*uvalpha)>>19; \
00667 int V= (uvbuf0[i+VOFW]*uvalpha1+uvbuf1[i+VOFW]*uvalpha)>>19; \
00668
00669 #define YSCALE_YUV_2_GRAY16_2_C \
00670 for (i=0; i<(dstW>>1); i++){ \
00671 const int i2= 2*i; \
00672 int Y1= (buf0[i2 ]*yalpha1+buf1[i2 ]*yalpha)>>11; \
00673 int Y2= (buf0[i2+1]*yalpha1+buf1[i2+1]*yalpha)>>11; \
00674
00675 #define YSCALE_YUV_2_RGB2_C(type) \
00676 YSCALE_YUV_2_PACKED2_C\
00677 type *r, *b, *g;\
00678 r = (type *)c->table_rV[V];\
00679 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
00680 b = (type *)c->table_bU[U];\
00681
00682 #define YSCALE_YUV_2_PACKED1_C \
00683 for (i=0; i<(dstW>>1); i++){\
00684 const int i2= 2*i;\
00685 int Y1= buf0[i2 ]>>7;\
00686 int Y2= buf0[i2+1]>>7;\
00687 int U= (uvbuf1[i ])>>7;\
00688 int V= (uvbuf1[i+VOFW])>>7;\
00689
00690 #define YSCALE_YUV_2_GRAY16_1_C \
00691 for (i=0; i<(dstW>>1); i++){\
00692 const int i2= 2*i;\
00693 int Y1= buf0[i2 ]<<1;\
00694 int Y2= buf0[i2+1]<<1;\
00695
00696 #define YSCALE_YUV_2_RGB1_C(type) \
00697 YSCALE_YUV_2_PACKED1_C\
00698 type *r, *b, *g;\
00699 r = (type *)c->table_rV[V];\
00700 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
00701 b = (type *)c->table_bU[U];\
00702
00703 #define YSCALE_YUV_2_PACKED1B_C \
00704 for (i=0; i<(dstW>>1); i++){\
00705 const int i2= 2*i;\
00706 int Y1= buf0[i2 ]>>7;\
00707 int Y2= buf0[i2+1]>>7;\
00708 int U= (uvbuf0[i ] + uvbuf1[i ])>>8;\
00709 int V= (uvbuf0[i+VOFW] + uvbuf1[i+VOFW])>>8;\
00710
00711 #define YSCALE_YUV_2_RGB1B_C(type) \
00712 YSCALE_YUV_2_PACKED1B_C\
00713 type *r, *b, *g;\
00714 r = (type *)c->table_rV[V];\
00715 g = (type *)(c->table_gU[U] + c->table_gV[V]);\
00716 b = (type *)c->table_bU[U];\
00717
00718 #define YSCALE_YUV_2_MONO2_C \
00719 const uint8_t * const d128=dither_8x8_220[y&7];\
00720 uint8_t *g= c->table_gU[128] + c->table_gV[128];\
00721 for (i=0; i<dstW-7; i+=8){\
00722 int acc;\
00723 acc = g[((buf0[i ]*yalpha1+buf1[i ]*yalpha)>>19) + d128[0]];\
00724 acc+= acc + g[((buf0[i+1]*yalpha1+buf1[i+1]*yalpha)>>19) + d128[1]];\
00725 acc+= acc + g[((buf0[i+2]*yalpha1+buf1[i+2]*yalpha)>>19) + d128[2]];\
00726 acc+= acc + g[((buf0[i+3]*yalpha1+buf1[i+3]*yalpha)>>19) + d128[3]];\
00727 acc+= acc + g[((buf0[i+4]*yalpha1+buf1[i+4]*yalpha)>>19) + d128[4]];\
00728 acc+= acc + g[((buf0[i+5]*yalpha1+buf1[i+5]*yalpha)>>19) + d128[5]];\
00729 acc+= acc + g[((buf0[i+6]*yalpha1+buf1[i+6]*yalpha)>>19) + d128[6]];\
00730 acc+= acc + g[((buf0[i+7]*yalpha1+buf1[i+7]*yalpha)>>19) + d128[7]];\
00731 ((uint8_t*)dest)[0]= c->dstFormat == PIX_FMT_MONOBLACK ? acc : ~acc;\
00732 dest++;\
00733 }\
00734
00735
00736 #define YSCALE_YUV_2_MONOX_C \
00737 const uint8_t * const d128=dither_8x8_220[y&7];\
00738 uint8_t *g= c->table_gU[128] + c->table_gV[128];\
00739 int acc=0;\
00740 for (i=0; i<dstW-1; i+=2){\
00741 int j;\
00742 int Y1=1<<18;\
00743 int Y2=1<<18;\
00744 \
00745 for (j=0; j<lumFilterSize; j++)\
00746 {\
00747 Y1 += lumSrc[j][i] * lumFilter[j];\
00748 Y2 += lumSrc[j][i+1] * lumFilter[j];\
00749 }\
00750 Y1>>=19;\
00751 Y2>>=19;\
00752 if ((Y1|Y2)&256)\
00753 {\
00754 if (Y1>255) Y1=255;\
00755 else if (Y1<0)Y1=0;\
00756 if (Y2>255) Y2=255;\
00757 else if (Y2<0)Y2=0;\
00758 }\
00759 acc+= acc + g[Y1+d128[(i+0)&7]];\
00760 acc+= acc + g[Y2+d128[(i+1)&7]];\
00761 if ((i&7)==6){\
00762 ((uint8_t*)dest)[0]= c->dstFormat == PIX_FMT_MONOBLACK ? acc : ~acc;\
00763 dest++;\
00764 }\
00765 }
00766
00767
00768 #define YSCALE_YUV_2_ANYRGB_C(func, func2, func_g16, func_monoblack)\
00769 switch(c->dstFormat)\
00770 {\
00771 case PIX_FMT_RGB32:\
00772 case PIX_FMT_BGR32:\
00773 case PIX_FMT_RGB32_1:\
00774 case PIX_FMT_BGR32_1:\
00775 func(uint32_t)\
00776 ((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];\
00777 ((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];\
00778 } \
00779 break;\
00780 case PIX_FMT_RGB24:\
00781 func(uint8_t)\
00782 ((uint8_t*)dest)[0]= r[Y1];\
00783 ((uint8_t*)dest)[1]= g[Y1];\
00784 ((uint8_t*)dest)[2]= b[Y1];\
00785 ((uint8_t*)dest)[3]= r[Y2];\
00786 ((uint8_t*)dest)[4]= g[Y2];\
00787 ((uint8_t*)dest)[5]= b[Y2];\
00788 dest+=6;\
00789 }\
00790 break;\
00791 case PIX_FMT_BGR24:\
00792 func(uint8_t)\
00793 ((uint8_t*)dest)[0]= b[Y1];\
00794 ((uint8_t*)dest)[1]= g[Y1];\
00795 ((uint8_t*)dest)[2]= r[Y1];\
00796 ((uint8_t*)dest)[3]= b[Y2];\
00797 ((uint8_t*)dest)[4]= g[Y2];\
00798 ((uint8_t*)dest)[5]= r[Y2];\
00799 dest+=6;\
00800 }\
00801 break;\
00802 case PIX_FMT_RGB565:\
00803 case PIX_FMT_BGR565:\
00804 {\
00805 const int dr1= dither_2x2_8[y&1 ][0];\
00806 const int dg1= dither_2x2_4[y&1 ][0];\
00807 const int db1= dither_2x2_8[(y&1)^1][0];\
00808 const int dr2= dither_2x2_8[y&1 ][1];\
00809 const int dg2= dither_2x2_4[y&1 ][1];\
00810 const int db2= dither_2x2_8[(y&1)^1][1];\
00811 func(uint16_t)\
00812 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
00813 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
00814 }\
00815 }\
00816 break;\
00817 case PIX_FMT_RGB555:\
00818 case PIX_FMT_BGR555:\
00819 {\
00820 const int dr1= dither_2x2_8[y&1 ][0];\
00821 const int dg1= dither_2x2_8[y&1 ][1];\
00822 const int db1= dither_2x2_8[(y&1)^1][0];\
00823 const int dr2= dither_2x2_8[y&1 ][1];\
00824 const int dg2= dither_2x2_8[y&1 ][0];\
00825 const int db2= dither_2x2_8[(y&1)^1][1];\
00826 func(uint16_t)\
00827 ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
00828 ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
00829 }\
00830 }\
00831 break;\
00832 case PIX_FMT_RGB8:\
00833 case PIX_FMT_BGR8:\
00834 {\
00835 const uint8_t * const d64= dither_8x8_73[y&7];\
00836 const uint8_t * const d32= dither_8x8_32[y&7];\
00837 func(uint8_t)\
00838 ((uint8_t*)dest)[i2+0]= r[Y1+d32[(i2+0)&7]] + g[Y1+d32[(i2+0)&7]] + b[Y1+d64[(i2+0)&7]];\
00839 ((uint8_t*)dest)[i2+1]= r[Y2+d32[(i2+1)&7]] + g[Y2+d32[(i2+1)&7]] + b[Y2+d64[(i2+1)&7]];\
00840 }\
00841 }\
00842 break;\
00843 case PIX_FMT_RGB4:\
00844 case PIX_FMT_BGR4:\
00845 {\
00846 const uint8_t * const d64= dither_8x8_73 [y&7];\
00847 const uint8_t * const d128=dither_8x8_220[y&7];\
00848 func(uint8_t)\
00849 ((uint8_t*)dest)[i]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]]\
00850 + ((r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]])<<4);\
00851 }\
00852 }\
00853 break;\
00854 case PIX_FMT_RGB4_BYTE:\
00855 case PIX_FMT_BGR4_BYTE:\
00856 {\
00857 const uint8_t * const d64= dither_8x8_73 [y&7];\
00858 const uint8_t * const d128=dither_8x8_220[y&7];\
00859 func(uint8_t)\
00860 ((uint8_t*)dest)[i2+0]= r[Y1+d128[(i2+0)&7]] + g[Y1+d64[(i2+0)&7]] + b[Y1+d128[(i2+0)&7]];\
00861 ((uint8_t*)dest)[i2+1]= r[Y2+d128[(i2+1)&7]] + g[Y2+d64[(i2+1)&7]] + b[Y2+d128[(i2+1)&7]];\
00862 }\
00863 }\
00864 break;\
00865 case PIX_FMT_MONOBLACK:\
00866 case PIX_FMT_MONOWHITE:\
00867 {\
00868 func_monoblack\
00869 }\
00870 break;\
00871 case PIX_FMT_YUYV422:\
00872 func2\
00873 ((uint8_t*)dest)[2*i2+0]= Y1;\
00874 ((uint8_t*)dest)[2*i2+1]= U;\
00875 ((uint8_t*)dest)[2*i2+2]= Y2;\
00876 ((uint8_t*)dest)[2*i2+3]= V;\
00877 } \
00878 break;\
00879 case PIX_FMT_UYVY422:\
00880 func2\
00881 ((uint8_t*)dest)[2*i2+0]= U;\
00882 ((uint8_t*)dest)[2*i2+1]= Y1;\
00883 ((uint8_t*)dest)[2*i2+2]= V;\
00884 ((uint8_t*)dest)[2*i2+3]= Y2;\
00885 } \
00886 break;\
00887 case PIX_FMT_GRAY16BE:\
00888 func_g16\
00889 ((uint8_t*)dest)[2*i2+0]= Y1>>8;\
00890 ((uint8_t*)dest)[2*i2+1]= Y1;\
00891 ((uint8_t*)dest)[2*i2+2]= Y2>>8;\
00892 ((uint8_t*)dest)[2*i2+3]= Y2;\
00893 } \
00894 break;\
00895 case PIX_FMT_GRAY16LE:\
00896 func_g16\
00897 ((uint8_t*)dest)[2*i2+0]= Y1;\
00898 ((uint8_t*)dest)[2*i2+1]= Y1>>8;\
00899 ((uint8_t*)dest)[2*i2+2]= Y2;\
00900 ((uint8_t*)dest)[2*i2+3]= Y2>>8;\
00901 } \
00902 break;\
00903 }\
00904
00905
00906 static inline void yuv2packedXinC(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
00907 int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
00908 uint8_t *dest, int dstW, int y)
00909 {
00910 int i;
00911 YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGBX_C, YSCALE_YUV_2_PACKEDX_C(void), YSCALE_YUV_2_GRAY16_C, YSCALE_YUV_2_MONOX_C)
00912 }
00913
00914 static inline void yuv2rgbXinC_full(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
00915 int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
00916 uint8_t *dest, int dstW, int y)
00917 {
00918 int i;
00919 int step= fmt_depth(c->dstFormat)/8;
00920 int aidx= 3;
00921
00922 switch(c->dstFormat){
00923 case PIX_FMT_ARGB:
00924 dest++;
00925 aidx= -1;
00926 case PIX_FMT_RGB24:
00927 aidx--;
00928 case PIX_FMT_RGBA:
00929 YSCALE_YUV_2_RGBX_FULL_C(1<<21)
00930 dest[aidx]= 255;
00931 dest[0]= R>>22;
00932 dest[1]= G>>22;
00933 dest[2]= B>>22;
00934 dest+= step;
00935 }
00936 break;
00937 case PIX_FMT_ABGR:
00938 dest++;
00939 aidx= -1;
00940 case PIX_FMT_BGR24:
00941 aidx--;
00942 case PIX_FMT_BGRA:
00943 YSCALE_YUV_2_RGBX_FULL_C(1<<21)
00944 dest[aidx]= 255;
00945 dest[0]= B>>22;
00946 dest[1]= G>>22;
00947 dest[2]= R>>22;
00948 dest+= step;
00949 }
00950 break;
00951 default:
00952 assert(0);
00953 }
00954 }
00955
00956
00957
00958 #if ((!HAVE_MMX || !CONFIG_GPL) && !HAVE_ALTIVEC) || CONFIG_RUNTIME_CPUDETECT
00959 #define COMPILE_C
00960 #endif
00961
00962 #if ARCH_PPC
00963 #if HAVE_ALTIVEC
00964 #define COMPILE_ALTIVEC
00965 #endif
00966 #endif //ARCH_PPC
00967
00968 #if ARCH_X86
00969
00970 #if ((HAVE_MMX && !HAVE_AMD3DNOW && !HAVE_MMX2) || CONFIG_RUNTIME_CPUDETECT) && CONFIG_GPL
00971 #define COMPILE_MMX
00972 #endif
00973
00974 #if (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) && CONFIG_GPL
00975 #define COMPILE_MMX2
00976 #endif
00977
00978 #if ((HAVE_AMD3DNOW && !HAVE_MMX2) || CONFIG_RUNTIME_CPUDETECT) && CONFIG_GPL
00979 #define COMPILE_3DNOW
00980 #endif
00981 #endif //ARCH_X86
00982
00983 #undef HAVE_MMX
00984 #undef HAVE_MMX2
00985 #undef HAVE_AMD3DNOW
00986 #undef HAVE_ALTIVEC
00987 #define HAVE_MMX 0
00988 #define HAVE_MMX2 0
00989 #define HAVE_AMD3DNOW 0
00990 #define HAVE_ALTIVEC 0
00991
00992 #ifdef COMPILE_C
00993 #define RENAME(a) a ## _C
00994 #include "swscale_template.c"
00995 #endif
00996
00997 #ifdef COMPILE_ALTIVEC
00998 #undef RENAME
00999 #undef HAVE_ALTIVEC
01000 #define HAVE_ALTIVEC 1
01001 #define RENAME(a) a ## _altivec
01002 #include "swscale_template.c"
01003 #endif
01004
01005 #if ARCH_X86
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 #ifdef COMPILE_MMX
01019 #undef RENAME
01020 #undef HAVE_MMX
01021 #undef HAVE_MMX2
01022 #undef HAVE_AMD3DNOW
01023 #define HAVE_MMX 1
01024 #define HAVE_MMX2 0
01025 #define HAVE_AMD3DNOW 0
01026 #define RENAME(a) a ## _MMX
01027 #include "swscale_template.c"
01028 #endif
01029
01030
01031 #ifdef COMPILE_MMX2
01032 #undef RENAME
01033 #undef HAVE_MMX
01034 #undef HAVE_MMX2
01035 #undef HAVE_AMD3DNOW
01036 #define HAVE_MMX 1
01037 #define HAVE_MMX2 1
01038 #define HAVE_AMD3DNOW 0
01039 #define RENAME(a) a ## _MMX2
01040 #include "swscale_template.c"
01041 #endif
01042
01043
01044 #ifdef COMPILE_3DNOW
01045 #undef RENAME
01046 #undef HAVE_MMX
01047 #undef HAVE_MMX2
01048 #undef HAVE_AMD3DNOW
01049 #define HAVE_MMX 1
01050 #define HAVE_MMX2 0
01051 #define HAVE_AMD3DNOW 1
01052 #define RENAME(a) a ## _3DNow
01053 #include "swscale_template.c"
01054 #endif
01055
01056 #endif //ARCH_X86
01057
01058
01059
01060 static double getSplineCoeff(double a, double b, double c, double d, double dist)
01061 {
01062
01063 if (dist<=1.0) return ((d*dist + c)*dist + b)*dist +a;
01064 else return getSplineCoeff( 0.0,
01065 b+ 2.0*c + 3.0*d,
01066 c + 3.0*d,
01067 -b- 3.0*c - 6.0*d,
01068 dist-1.0);
01069 }
01070
01071 static inline int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc,
01072 int srcW, int dstW, int filterAlign, int one, int flags,
01073 SwsVector *srcFilter, SwsVector *dstFilter, double param[2])
01074 {
01075 int i;
01076 int filterSize;
01077 int filter2Size;
01078 int minFilterSize;
01079 int64_t *filter=NULL;
01080 int64_t *filter2=NULL;
01081 const int64_t fone= 1LL<<54;
01082 int ret= -1;
01083 #if ARCH_X86
01084 if (flags & SWS_CPU_CAPS_MMX)
01085 __asm__ volatile("emms\n\t"::: "memory");
01086 #endif
01087
01088
01089 *filterPos = av_malloc((dstW+1)*sizeof(int16_t));
01090
01091 if (FFABS(xInc - 0x10000) <10)
01092 {
01093 int i;
01094 filterSize= 1;
01095 filter= av_mallocz(dstW*sizeof(*filter)*filterSize);
01096
01097 for (i=0; i<dstW; i++)
01098 {
01099 filter[i*filterSize]= fone;
01100 (*filterPos)[i]=i;
01101 }
01102
01103 }
01104 else if (flags&SWS_POINT)
01105 {
01106 int i;
01107 int xDstInSrc;
01108 filterSize= 1;
01109 filter= av_malloc(dstW*sizeof(*filter)*filterSize);
01110
01111 xDstInSrc= xInc/2 - 0x8000;
01112 for (i=0; i<dstW; i++)
01113 {
01114 int xx= (xDstInSrc - ((filterSize-1)<<15) + (1<<15))>>16;
01115
01116 (*filterPos)[i]= xx;
01117 filter[i]= fone;
01118 xDstInSrc+= xInc;
01119 }
01120 }
01121 else if ((xInc <= (1<<16) && (flags&SWS_AREA)) || (flags&SWS_FAST_BILINEAR))
01122 {
01123 int i;
01124 int xDstInSrc;
01125 if (flags&SWS_BICUBIC) filterSize= 4;
01126 else if (flags&SWS_X ) filterSize= 4;
01127 else filterSize= 2;
01128 filter= av_malloc(dstW*sizeof(*filter)*filterSize);
01129
01130 xDstInSrc= xInc/2 - 0x8000;
01131 for (i=0; i<dstW; i++)
01132 {
01133 int xx= (xDstInSrc - ((filterSize-1)<<15) + (1<<15))>>16;
01134 int j;
01135
01136 (*filterPos)[i]= xx;
01137
01138 for (j=0; j<filterSize; j++)
01139 {
01140 int64_t coeff= fone - FFABS((xx<<16) - xDstInSrc)*(fone>>16);
01141 if (coeff<0) coeff=0;
01142 filter[i*filterSize + j]= coeff;
01143 xx++;
01144 }
01145 xDstInSrc+= xInc;
01146 }
01147 }
01148 else
01149 {
01150 int xDstInSrc;
01151 int sizeFactor;
01152
01153 if (flags&SWS_BICUBIC) sizeFactor= 4;
01154 else if (flags&SWS_X) sizeFactor= 8;
01155 else if (flags&SWS_AREA) sizeFactor= 1;
01156 else if (flags&SWS_GAUSS) sizeFactor= 8;
01157 else if (flags&SWS_LANCZOS) sizeFactor= param[0] != SWS_PARAM_DEFAULT ? ceil(2*param[0]) : 6;
01158 else if (flags&SWS_SINC) sizeFactor= 20;
01159 else if (flags&SWS_SPLINE) sizeFactor= 20;
01160 else if (flags&SWS_BILINEAR) sizeFactor= 2;
01161 else {
01162 sizeFactor= 0;
01163 assert(0);
01164 }
01165
01166 if (xInc <= 1<<16) filterSize= 1 + sizeFactor;
01167 else filterSize= 1 + (sizeFactor*srcW + dstW - 1)/ dstW;
01168
01169 if (filterSize > srcW-2) filterSize=srcW-2;
01170
01171 filter= av_malloc(dstW*sizeof(*filter)*filterSize);
01172
01173 xDstInSrc= xInc - 0x10000;
01174 for (i=0; i<dstW; i++)
01175 {
01176 int xx= (xDstInSrc - ((filterSize-2)<<16)) / (1<<17);
01177 int j;
01178 (*filterPos)[i]= xx;
01179 for (j=0; j<filterSize; j++)
01180 {
01181 int64_t d= ((int64_t)FFABS((xx<<17) - xDstInSrc))<<13;
01182 double floatd;
01183 int64_t coeff;
01184
01185 if (xInc > 1<<16)
01186 d= d*dstW/srcW;
01187 floatd= d * (1.0/(1<<30));
01188
01189 if (flags & SWS_BICUBIC)
01190 {
01191 int64_t B= (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1<<24);
01192 int64_t C= (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1<<24);
01193 int64_t dd = ( d*d)>>30;
01194 int64_t ddd= (dd*d)>>30;
01195
01196 if (d < 1LL<<30)
01197 coeff = (12*(1<<24)-9*B-6*C)*ddd + (-18*(1<<24)+12*B+6*C)*dd + (6*(1<<24)-2*B)*(1<<30);
01198 else if (d < 1LL<<31)
01199 coeff = (-B-6*C)*ddd + (6*B+30*C)*dd + (-12*B-48*C)*d + (8*B+24*C)*(1<<30);
01200 else
01201 coeff=0.0;
01202 coeff *= fone>>(30+24);
01203 }
01204
01205
01206
01207
01208
01209
01210 else if (flags & SWS_X)
01211 {
01212 double A= param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0;
01213 double c;
01214
01215 if (floatd<1.0)
01216 c = cos(floatd*PI);
01217 else
01218 c=-1.0;
01219 if (c<0.0) c= -pow(-c, A);
01220 else c= pow( c, A);
01221 coeff= (c*0.5 + 0.5)*fone;
01222 }
01223 else if (flags & SWS_AREA)
01224 {
01225 int64_t d2= d - (1<<29);
01226 if (d2*xInc < -(1LL<<(29+16))) coeff= 1.0 * (1LL<<(30+16));
01227 else if (d2*xInc < (1LL<<(29+16))) coeff= -d2*xInc + (1LL<<(29+16));
01228 else coeff=0.0;
01229 coeff *= fone>>(30+16);
01230 }
01231 else if (flags & SWS_GAUSS)
01232 {
01233 double p= param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
01234 coeff = (pow(2.0, - p*floatd*floatd))*fone;
01235 }
01236 else if (flags & SWS_SINC)
01237 {
01238 coeff = (d ? sin(floatd*PI)/(floatd*PI) : 1.0)*fone;
01239 }
01240 else if (flags & SWS_LANCZOS)
01241 {
01242 double p= param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
01243 coeff = (d ? sin(floatd*PI)*sin(floatd*PI/p)/(floatd*floatd*PI*PI/p) : 1.0)*fone;
01244 if (floatd>p) coeff=0;
01245 }
01246 else if (flags & SWS_BILINEAR)
01247 {
01248 coeff= (1<<30) - d;
01249 if (coeff<0) coeff=0;
01250 coeff *= fone >> 30;
01251 }
01252 else if (flags & SWS_SPLINE)
01253 {
01254 double p=-2.196152422706632;
01255 coeff = getSplineCoeff(1.0, 0.0, p, -p-1.0, floatd) * fone;
01256 }
01257 else {
01258 coeff= 0.0;
01259 assert(0);
01260 }
01261
01262 filter[i*filterSize + j]= coeff;
01263 xx++;
01264 }
01265 xDstInSrc+= 2*xInc;
01266 }
01267 }
01268
01269
01270
01271
01272 assert(filterSize>0);
01273 filter2Size= filterSize;
01274 if (srcFilter) filter2Size+= srcFilter->length - 1;
01275 if (dstFilter) filter2Size+= dstFilter->length - 1;
01276 assert(filter2Size>0);
01277 filter2= av_mallocz(filter2Size*dstW*sizeof(*filter2));
01278
01279 for (i=0; i<dstW; i++)
01280 {
01281 int j, k;
01282
01283 if(srcFilter){
01284 for (k=0; k<srcFilter->length; k++){
01285 for (j=0; j<filterSize; j++)
01286 filter2[i*filter2Size + k + j] += srcFilter->coeff[k]*filter[i*filterSize + j];
01287 }
01288 }else{
01289 for (j=0; j<filterSize; j++)
01290 filter2[i*filter2Size + j]= filter[i*filterSize + j];
01291 }
01292
01293
01294 (*filterPos)[i]+= (filterSize-1)/2 - (filter2Size-1)/2;
01295 }
01296 av_freep(&filter);
01297
01298
01299
01300 minFilterSize= 0;
01301 for (i=dstW-1; i>=0; i--)
01302 {
01303 int min= filter2Size;
01304 int j;
01305 int64_t cutOff=0.0;
01306
01307
01308 for (j=0; j<filter2Size; j++)
01309 {
01310 int k;
01311 cutOff += FFABS(filter2[i*filter2Size]);
01312
01313 if (cutOff > SWS_MAX_REDUCE_CUTOFF*fone) break;
01314
01315
01316 if (i<dstW-1 && (*filterPos)[i] >= (*filterPos)[i+1]) break;
01317
01318
01319 for (k=1; k<filter2Size; k++)
01320 filter2[i*filter2Size + k - 1]= filter2[i*filter2Size + k];
01321 filter2[i*filter2Size + k - 1]= 0;
01322 (*filterPos)[i]++;
01323 }
01324
01325 cutOff=0;
01326
01327 for (j=filter2Size-1; j>0; j--)
01328 {
01329 cutOff += FFABS(filter2[i*filter2Size + j]);
01330
01331 if (cutOff > SWS_MAX_REDUCE_CUTOFF*fone) break;
01332 min--;
01333 }
01334
01335 if (min>minFilterSize) minFilterSize= min;
01336 }
01337
01338 if (flags & SWS_CPU_CAPS_ALTIVEC) {
01339
01340
01341 if (minFilterSize < 5)
01342 filterAlign = 4;
01343
01344
01345
01346
01347
01348
01349 if (minFilterSize < 3)
01350 filterAlign = 1;
01351 }
01352
01353 if (flags & SWS_CPU_CAPS_MMX) {
01354
01355 if (minFilterSize == 1 && filterAlign == 2)
01356 filterAlign= 1;
01357 }
01358
01359 assert(minFilterSize > 0);
01360 filterSize= (minFilterSize +(filterAlign-1)) & (~(filterAlign-1));
01361 assert(filterSize > 0);
01362 filter= av_malloc(filterSize*dstW*sizeof(*filter));
01363 if (filterSize >= MAX_FILTER_SIZE*16/((flags&SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter)
01364 goto error;
01365 *outFilterSize= filterSize;
01366
01367 if (flags&SWS_PRINT_INFO)
01368 av_log(NULL, AV_LOG_VERBOSE, "SwScaler: reducing / aligning filtersize %d -> %d\n", filter2Size, filterSize);
01369
01370 for (i=0; i<dstW; i++)
01371 {
01372 int j;
01373
01374 for (j=0; j<filterSize; j++)
01375 {
01376 if (j>=filter2Size) filter[i*filterSize + j]= 0;
01377 else filter[i*filterSize + j]= filter2[i*filter2Size + j];
01378 if((flags & SWS_BITEXACT) && j>=minFilterSize)
01379 filter[i*filterSize + j]= 0;
01380 }
01381 }
01382
01383
01384
01385
01386
01387 for (i=0; i<dstW; i++)
01388 {
01389 int j;
01390 if ((*filterPos)[i] < 0)
01391 {
01392
01393 for (j=1; j<filterSize; j++)
01394 {
01395 int left= FFMAX(j + (*filterPos)[i], 0);
01396 filter[i*filterSize + left] += filter[i*filterSize + j];
01397 filter[i*filterSize + j]=0;
01398 }
01399 (*filterPos)[i]= 0;
01400 }
01401
01402 if ((*filterPos)[i] + filterSize > srcW)
01403 {
01404 int shift= (*filterPos)[i] + filterSize - srcW;
01405
01406 for (j=filterSize-2; j>=0; j--)
01407 {
01408 int right= FFMIN(j + shift, filterSize-1);
01409 filter[i*filterSize +right] += filter[i*filterSize +j];
01410 filter[i*filterSize +j]=0;
01411 }
01412 (*filterPos)[i]= srcW - filterSize;
01413 }
01414 }
01415
01416
01417
01418 *outFilter= av_mallocz(*outFilterSize*(dstW+1)*sizeof(int16_t));
01419
01420
01421 for (i=0; i<dstW; i++)
01422 {
01423 int j;
01424 int64_t error=0;
01425 int64_t sum=0;
01426
01427 for (j=0; j<filterSize; j++)
01428 {
01429 sum+= filter[i*filterSize + j];
01430 }
01431 sum= (sum + one/2)/ one;
01432 for (j=0; j<*outFilterSize; j++)
01433 {
01434 int64_t v= filter[i*filterSize + j] + error;
01435 int intV= ROUNDED_DIV(v, sum);
01436 (*outFilter)[i*(*outFilterSize) + j]= intV;
01437 error= v - intV*sum;
01438 }
01439 }
01440
01441 (*filterPos)[dstW]= (*filterPos)[dstW-1];
01442 for (i=0; i<*outFilterSize; i++)
01443 {
01444 int j= dstW*(*outFilterSize);
01445 (*outFilter)[j + i]= (*outFilter)[j + i - (*outFilterSize)];
01446 }
01447
01448 ret=0;
01449 error:
01450 av_free(filter);
01451 av_free(filter2);
01452 return ret;
01453 }
01454
01455 #ifdef COMPILE_MMX2
01456 static void initMMX2HScaler(int dstW, int xInc, uint8_t *funnyCode, int16_t *filter, int32_t *filterPos, int numSplits)
01457 {
01458 uint8_t *fragmentA;
01459 long imm8OfPShufW1A;
01460 long imm8OfPShufW2A;
01461 long fragmentLengthA;
01462 uint8_t *fragmentB;
01463 long imm8OfPShufW1B;
01464 long imm8OfPShufW2B;
01465 long fragmentLengthB;
01466 int fragmentPos;
01467
01468 int xpos, i;
01469
01470
01471
01472
01473
01474 __asm__ volatile(
01475 "jmp 9f \n\t"
01476
01477 "0: \n\t"
01478 "movq (%%"REG_d", %%"REG_a"), %%mm3 \n\t"
01479 "movd (%%"REG_c", %%"REG_S"), %%mm0 \n\t"
01480 "movd 1(%%"REG_c", %%"REG_S"), %%mm1 \n\t"
01481 "punpcklbw %%mm7, %%mm1 \n\t"
01482 "punpcklbw %%mm7, %%mm0 \n\t"
01483 "pshufw $0xFF, %%mm1, %%mm1 \n\t"
01484 "1: \n\t"
01485 "pshufw $0xFF, %%mm0, %%mm0 \n\t"
01486 "2: \n\t"
01487 "psubw %%mm1, %%mm0 \n\t"
01488 "movl 8(%%"REG_b", %%"REG_a"), %%esi \n\t"
01489 "pmullw %%mm3, %%mm0 \n\t"
01490 "psllw $7, %%mm1 \n\t"
01491 "paddw %%mm1, %%mm0 \n\t"
01492
01493 "movq %%mm0, (%%"REG_D", %%"REG_a") \n\t"
01494
01495 "add $8, %%"REG_a" \n\t"
01496
01497 "9: \n\t"
01498
01499 "lea " LOCAL_MANGLE(0b) ", %0 \n\t"
01500 "lea " LOCAL_MANGLE(1b) ", %1 \n\t"
01501 "lea " LOCAL_MANGLE(2b) ", %2 \n\t"
01502 "dec %1 \n\t"
01503 "dec %2 \n\t"
01504 "sub %0, %1 \n\t"
01505 "sub %0, %2 \n\t"
01506 "lea " LOCAL_MANGLE(9b) ", %3 \n\t"
01507 "sub %0, %3 \n\t"
01508
01509
01510 :"=r" (fragmentA), "=r" (imm8OfPShufW1A), "=r" (imm8OfPShufW2A),
01511 "=r" (fragmentLengthA)
01512 );
01513
01514 __asm__ volatile(
01515 "jmp 9f \n\t"
01516
01517 "0: \n\t"
01518 "movq (%%"REG_d", %%"REG_a"), %%mm3 \n\t"
01519 "movd (%%"REG_c", %%"REG_S"), %%mm0 \n\t"
01520 "punpcklbw %%mm7, %%mm0 \n\t"
01521 "pshufw $0xFF, %%mm0, %%mm1 \n\t"
01522 "1: \n\t"
01523 "pshufw $0xFF, %%mm0, %%mm0 \n\t"
01524 "2: \n\t"
01525 "psubw %%mm1, %%mm0 \n\t"
01526 "movl 8(%%"REG_b", %%"REG_a"), %%esi \n\t"
01527 "pmullw %%mm3, %%mm0 \n\t"
01528 "psllw $7, %%mm1 \n\t"
01529 "paddw %%mm1, %%mm0 \n\t"
01530
01531 "movq %%mm0, (%%"REG_D", %%"REG_a") \n\t"
01532
01533 "add $8, %%"REG_a" \n\t"
01534
01535 "9: \n\t"
01536
01537 "lea " LOCAL_MANGLE(0b) ", %0 \n\t"
01538 "lea " LOCAL_MANGLE(1b) ", %1 \n\t"
01539 "lea " LOCAL_MANGLE(2b) ", %2 \n\t"
01540 "dec %1 \n\t"
01541 "dec %2 \n\t"
01542 "sub %0, %1 \n\t"
01543 "sub %0, %2 \n\t"
01544 "lea " LOCAL_MANGLE(9b) ", %3 \n\t"
01545 "sub %0, %3 \n\t"
01546
01547
01548 :"=r" (fragmentB), "=r" (imm8OfPShufW1B), "=r" (imm8OfPShufW2B),
01549 "=r" (fragmentLengthB)
01550 );
01551
01552 xpos= 0;
01553 fragmentPos=0;
01554
01555 for (i=0; i<dstW/numSplits; i++)
01556 {
01557 int xx=xpos>>16;
01558
01559 if ((i&3) == 0)
01560 {
01561 int a=0;
01562 int b=((xpos+xInc)>>16) - xx;
01563 int c=((xpos+xInc*2)>>16) - xx;
01564 int d=((xpos+xInc*3)>>16) - xx;
01565
01566 filter[i ] = (( xpos & 0xFFFF) ^ 0xFFFF)>>9;
01567 filter[i+1] = (((xpos+xInc ) & 0xFFFF) ^ 0xFFFF)>>9;
01568 filter[i+2] = (((xpos+xInc*2) & 0xFFFF) ^ 0xFFFF)>>9;
01569 filter[i+3] = (((xpos+xInc*3) & 0xFFFF) ^ 0xFFFF)>>9;
01570 filterPos[i/2]= xx;
01571
01572 if (d+1<4)
01573 {
01574 int maxShift= 3-(d+1);
01575 int shift=0;
01576
01577 memcpy(funnyCode + fragmentPos, fragmentB, fragmentLengthB);
01578
01579 funnyCode[fragmentPos + imm8OfPShufW1B]=
01580 (a+1) | ((b+1)<<2) | ((c+1)<<4) | ((d+1)<<6);
01581 funnyCode[fragmentPos + imm8OfPShufW2B]=
01582 a | (b<<2) | (c<<4) | (d<<6);
01583
01584 if (i+3>=dstW) shift=maxShift;
01585 else if ((filterPos[i/2]&3) <= maxShift) shift=filterPos[i/2]&3;
01586
01587 if (shift && i>=shift)
01588 {
01589 funnyCode[fragmentPos + imm8OfPShufW1B]+= 0x55*shift;
01590 funnyCode[fragmentPos + imm8OfPShufW2B]+= 0x55*shift;
01591 filterPos[i/2]-=shift;
01592 }
01593
01594 fragmentPos+= fragmentLengthB;
01595 }
01596 else
01597 {
01598 int maxShift= 3-d;
01599 int shift=0;
01600
01601 memcpy(funnyCode + fragmentPos, fragmentA, fragmentLengthA);
01602
01603 funnyCode[fragmentPos + imm8OfPShufW1A]=
01604 funnyCode[fragmentPos + imm8OfPShufW2A]=
01605 a | (b<<2) | (c<<4) | (d<<6);
01606
01607 if (i+4>=dstW) shift=maxShift;
01608 else if ((filterPos[i/2]&3) <= maxShift) shift=filterPos[i/2]&3;
01609
01610 if (shift && i>=shift)
01611 {
01612 funnyCode[fragmentPos + imm8OfPShufW1A]+= 0x55*shift;
01613 funnyCode[fragmentPos + imm8OfPShufW2A]+= 0x55*shift;
01614 filterPos[i/2]-=shift;
01615 }
01616
01617 fragmentPos+= fragmentLengthA;
01618 }
01619
01620 funnyCode[fragmentPos]= RET;
01621 }
01622 xpos+=xInc;
01623 }
01624 filterPos[i/2]= xpos>>16;
01625 }
01626 #endif
01627
01628 static void globalInit(void){
01629
01630 int i;
01631 for (i=0; i<768; i++){
01632 int c= av_clip_uint8(i-256);
01633 clip_table[i]=c;
01634 }
01635 }
01636
01637 static SwsFunc getSwsFunc(int flags){
01638
01639 #if CONFIG_RUNTIME_CPUDETECT
01640 #if ARCH_X86 && CONFIG_GPL
01641
01642 if (flags & SWS_CPU_CAPS_MMX2)
01643 return swScale_MMX2;
01644 else if (flags & SWS_CPU_CAPS_3DNOW)
01645 return swScale_3DNow;
01646 else if (flags & SWS_CPU_CAPS_MMX)
01647 return swScale_MMX;
01648 else
01649 return swScale_C;
01650
01651 #else
01652 #if ARCH_PPC && defined COMPILE_ALTIVEC
01653 if (flags & SWS_CPU_CAPS_ALTIVEC)
01654 return swScale_altivec;
01655 else
01656 return swScale_C;
01657 #endif
01658 return swScale_C;
01659 #endif
01660 #else //CONFIG_RUNTIME_CPUDETECT
01661 #if HAVE_MMX2
01662 return swScale_MMX2;
01663 #elif HAVE_AMD3DNOW
01664 return swScale_3DNow;
01665 #elif HAVE_MMX
01666 return swScale_MMX;
01667 #elif HAVE_ALTIVEC
01668 return swScale_altivec;
01669 #else
01670 return swScale_C;
01671 #endif
01672 #endif
01673 }
01674
01675 static int PlanarToNV12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01676 int srcSliceH, uint8_t* dstParam[], int dstStride[]){
01677 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01678
01679 if (dstStride[0]==srcStride[0] && srcStride[0] > 0)
01680 memcpy(dst, src[0], srcSliceH*dstStride[0]);
01681 else
01682 {
01683 int i;
01684 uint8_t *srcPtr= src[0];
01685 uint8_t *dstPtr= dst;
01686 for (i=0; i<srcSliceH; i++)
01687 {
01688 memcpy(dstPtr, srcPtr, c->srcW);
01689 srcPtr+= srcStride[0];
01690 dstPtr+= dstStride[0];
01691 }
01692 }
01693 dst = dstParam[1] + dstStride[1]*srcSliceY/2;
01694 if (c->dstFormat == PIX_FMT_NV12)
01695 interleaveBytes(src[1], src[2], dst, c->srcW/2, srcSliceH/2, srcStride[1], srcStride[2], dstStride[0]);
01696 else
01697 interleaveBytes(src[2], src[1], dst, c->srcW/2, srcSliceH/2, srcStride[2], srcStride[1], dstStride[0]);
01698
01699 return srcSliceH;
01700 }
01701
01702 static int PlanarToYuy2Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01703 int srcSliceH, uint8_t* dstParam[], int dstStride[]){
01704 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01705
01706 yv12toyuy2(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
01707
01708 return srcSliceH;
01709 }
01710
01711 static int PlanarToUyvyWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01712 int srcSliceH, uint8_t* dstParam[], int dstStride[]){
01713 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01714
01715 yv12touyvy(src[0], src[1], src[2], dst, c->srcW, srcSliceH, srcStride[0], srcStride[1], dstStride[0]);
01716
01717 return srcSliceH;
01718 }
01719
01720 static int YUV422PToYuy2Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01721 int srcSliceH, uint8_t* dstParam[], int dstStride[]){
01722 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01723
01724 yuv422ptoyuy2(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
01725
01726 return srcSliceH;
01727 }
01728
01729 static int YUV422PToUyvyWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01730 int srcSliceH, uint8_t* dstParam[], int dstStride[]){
01731 uint8_t *dst=dstParam[0] + dstStride[0]*srcSliceY;
01732
01733 yuv422ptouyvy(src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0]);
01734
01735 return srcSliceH;
01736 }
01737
01738 static int pal2rgbWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01739 int srcSliceH, uint8_t* dst[], int dstStride[]){
01740 const enum PixelFormat srcFormat= c->srcFormat;
01741 const enum PixelFormat dstFormat= c->dstFormat;
01742 void (*conv)(const uint8_t *src, uint8_t *dst, long num_pixels,
01743 const uint8_t *palette)=NULL;
01744 int i;
01745 uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
01746 uint8_t *srcPtr= src[0];
01747
01748 if (!usePal(srcFormat))
01749 av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
01750 sws_format_name(srcFormat), sws_format_name(dstFormat));
01751
01752 switch(dstFormat){
01753 case PIX_FMT_RGB32 : conv = palette8topacked32; break;
01754 case PIX_FMT_BGR32 : conv = palette8topacked32; break;
01755 case PIX_FMT_BGR32_1: conv = palette8topacked32; break;
01756 case PIX_FMT_RGB32_1: conv = palette8topacked32; break;
01757 case PIX_FMT_RGB24 : conv = palette8topacked24; break;
01758 case PIX_FMT_BGR24 : conv = palette8topacked24; break;
01759 default: av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
01760 sws_format_name(srcFormat), sws_format_name(dstFormat)); break;
01761 }
01762
01763
01764 for (i=0; i<srcSliceH; i++) {
01765 conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
01766 srcPtr+= srcStride[0];
01767 dstPtr+= dstStride[0];
01768 }
01769
01770 return srcSliceH;
01771 }
01772
01773
01774 static int rgb2rgbWrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01775 int srcSliceH, uint8_t* dst[], int dstStride[]){
01776 const enum PixelFormat srcFormat= c->srcFormat;
01777 const enum PixelFormat dstFormat= c->dstFormat;
01778 const int srcBpp= (fmt_depth(srcFormat) + 7) >> 3;
01779 const int dstBpp= (fmt_depth(dstFormat) + 7) >> 3;
01780 const int srcId= fmt_depth(srcFormat) >> 2;
01781 const int dstId= fmt_depth(dstFormat) >> 2;
01782 void (*conv)(const uint8_t *src, uint8_t *dst, long src_size)=NULL;
01783
01784
01785 if ( (isBGR(srcFormat) && isBGR(dstFormat))
01786 || (isRGB(srcFormat) && isRGB(dstFormat))){
01787 switch(srcId | (dstId<<4)){
01788 case 0x34: conv= rgb16to15; break;
01789 case 0x36: conv= rgb24to15; break;
01790 case 0x38: conv= rgb32to15; break;
01791 case 0x43: conv= rgb15to16; break;
01792 case 0x46: conv= rgb24to16; break;
01793 case 0x48: conv= rgb32to16; break;
01794 case 0x63: conv= rgb15to24; break;
01795 case 0x64: conv= rgb16to24; break;
01796 case 0x68: conv= rgb32to24; break;
01797 case 0x83: conv= rgb15to32; break;
01798 case 0x84: conv= rgb16to32; break;
01799 case 0x86: conv= rgb24to32; break;
01800 default: av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
01801 sws_format_name(srcFormat), sws_format_name(dstFormat)); break;
01802 }
01803 }else if ( (isBGR(srcFormat) && isRGB(dstFormat))
01804 || (isRGB(srcFormat) && isBGR(dstFormat))){
01805 switch(srcId | (dstId<<4)){
01806 case 0x33: conv= rgb15tobgr15; break;
01807 case 0x34: conv= rgb16tobgr15; break;
01808 case 0x36: conv= rgb24tobgr15; break;
01809 case 0x38: conv= rgb32tobgr15; break;
01810 case 0x43: conv= rgb15tobgr16; break;
01811 case 0x44: conv= rgb16tobgr16; break;
01812 case 0x46: conv= rgb24tobgr16; break;
01813 case 0x48: conv= rgb32tobgr16; break;
01814 case 0x63: conv= rgb15tobgr24; break;
01815 case 0x64: conv= rgb16tobgr24; break;
01816 case 0x66: conv= rgb24tobgr24; break;
01817 case 0x68: conv= rgb32tobgr24; break;
01818 case 0x83: conv= rgb15tobgr32; break;
01819 case 0x84: conv= rgb16tobgr32; break;
01820 case 0x86: conv= rgb24tobgr32; break;
01821 case 0x88: conv= rgb32tobgr32; break;
01822 default: av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
01823 sws_format_name(srcFormat), sws_format_name(dstFormat)); break;
01824 }
01825 }else{
01826 av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
01827 sws_format_name(srcFormat), sws_format_name(dstFormat));
01828 }
01829
01830 if(conv)
01831 {
01832 uint8_t *srcPtr= src[0];
01833 if(srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1)
01834 srcPtr += ALT32_CORR;
01835
01836 if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0)
01837 conv(srcPtr, dst[0] + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]);
01838 else
01839 {
01840 int i;
01841 uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
01842
01843 for (i=0; i<srcSliceH; i++)
01844 {
01845 conv(srcPtr, dstPtr, c->srcW*srcBpp);
01846 srcPtr+= srcStride[0];
01847 dstPtr+= dstStride[0];
01848 }
01849 }
01850 }
01851 return srcSliceH;
01852 }
01853
01854 static int bgr24toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01855 int srcSliceH, uint8_t* dst[], int dstStride[]){
01856
01857 rgb24toyv12(
01858 src[0],
01859 dst[0]+ srcSliceY *dstStride[0],
01860 dst[1]+(srcSliceY>>1)*dstStride[1],
01861 dst[2]+(srcSliceY>>1)*dstStride[2],
01862 c->srcW, srcSliceH,
01863 dstStride[0], dstStride[1], srcStride[0]);
01864 return srcSliceH;
01865 }
01866
01867 static int yvu9toyv12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01868 int srcSliceH, uint8_t* dst[], int dstStride[]){
01869 int i;
01870
01871
01872 if (srcStride[0]==dstStride[0] && srcStride[0] > 0)
01873 memcpy(dst[0]+ srcSliceY*dstStride[0], src[0], srcStride[0]*srcSliceH);
01874 else{
01875 uint8_t *srcPtr= src[0];
01876 uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
01877
01878 for (i=0; i<srcSliceH; i++)
01879 {
01880 memcpy(dstPtr, srcPtr, c->srcW);
01881 srcPtr+= srcStride[0];
01882 dstPtr+= dstStride[0];
01883 }
01884 }
01885
01886 if (c->dstFormat==PIX_FMT_YUV420P){
01887 planar2x(src[1], dst[1], c->chrSrcW, c->chrSrcH, srcStride[1], dstStride[1]);
01888 planar2x(src[2], dst[2], c->chrSrcW, c->chrSrcH, srcStride[2], dstStride[2]);
01889 }else{
01890 planar2x(src[1], dst[2], c->chrSrcW, c->chrSrcH, srcStride[1], dstStride[2]);
01891 planar2x(src[2], dst[1], c->chrSrcW, c->chrSrcH, srcStride[2], dstStride[1]);
01892 }
01893 return srcSliceH;
01894 }
01895
01896
01897 static int packedCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01898 int srcSliceH, uint8_t* dst[], int dstStride[])
01899 {
01900 if (dstStride[0]==srcStride[0] && srcStride[0] > 0)
01901 memcpy(dst[0] + dstStride[0]*srcSliceY, src[0], srcSliceH*dstStride[0]);
01902 else
01903 {
01904 int i;
01905 uint8_t *srcPtr= src[0];
01906 uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
01907 int length=0;
01908
01909
01910 while(length+c->srcW <= FFABS(dstStride[0])
01911 && length+c->srcW <= FFABS(srcStride[0])) length+= c->srcW;
01912 assert(length!=0);
01913
01914 for (i=0; i<srcSliceH; i++)
01915 {
01916 memcpy(dstPtr, srcPtr, length);
01917 srcPtr+= srcStride[0];
01918 dstPtr+= dstStride[0];
01919 }
01920 }
01921 return srcSliceH;
01922 }
01923
01924 static int planarCopy(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01925 int srcSliceH, uint8_t* dst[], int dstStride[])
01926 {
01927 int plane;
01928 for (plane=0; plane<3; plane++)
01929 {
01930 int length= plane==0 ? c->srcW : -((-c->srcW )>>c->chrDstHSubSample);
01931 int y= plane==0 ? srcSliceY: -((-srcSliceY)>>c->chrDstVSubSample);
01932 int height= plane==0 ? srcSliceH: -((-srcSliceH)>>c->chrDstVSubSample);
01933
01934 if ((isGray(c->srcFormat) || isGray(c->dstFormat)) && plane>0)
01935 {
01936 if (!isGray(c->dstFormat))
01937 memset(dst[plane], 128, dstStride[plane]*height);
01938 }
01939 else
01940 {
01941 if (dstStride[plane]==srcStride[plane] && srcStride[plane] > 0)
01942 memcpy(dst[plane] + dstStride[plane]*y, src[plane], height*dstStride[plane]);
01943 else
01944 {
01945 int i;
01946 uint8_t *srcPtr= src[plane];
01947 uint8_t *dstPtr= dst[plane] + dstStride[plane]*y;
01948 for (i=0; i<height; i++)
01949 {
01950 memcpy(dstPtr, srcPtr, length);
01951 srcPtr+= srcStride[plane];
01952 dstPtr+= dstStride[plane];
01953 }
01954 }
01955 }
01956 }
01957 return srcSliceH;
01958 }
01959
01960 static int gray16togray(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01961 int srcSliceH, uint8_t* dst[], int dstStride[]){
01962
01963 int length= c->srcW;
01964 int y= srcSliceY;
01965 int height= srcSliceH;
01966 int i, j;
01967 uint8_t *srcPtr= src[0];
01968 uint8_t *dstPtr= dst[0] + dstStride[0]*y;
01969
01970 if (!isGray(c->dstFormat)){
01971 int height= -((-srcSliceH)>>c->chrDstVSubSample);
01972 memset(dst[1], 128, dstStride[1]*height);
01973 memset(dst[2], 128, dstStride[2]*height);
01974 }
01975 if (c->srcFormat == PIX_FMT_GRAY16LE) srcPtr++;
01976 for (i=0; i<height; i++)
01977 {
01978 for (j=0; j<length; j++) dstPtr[j] = srcPtr[j<<1];
01979 srcPtr+= srcStride[0];
01980 dstPtr+= dstStride[0];
01981 }
01982 return srcSliceH;
01983 }
01984
01985 static int graytogray16(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
01986 int srcSliceH, uint8_t* dst[], int dstStride[]){
01987
01988 int length= c->srcW;
01989 int y= srcSliceY;
01990 int height= srcSliceH;
01991 int i, j;
01992 uint8_t *srcPtr= src[0];
01993 uint8_t *dstPtr= dst[0] + dstStride[0]*y;
01994 for (i=0; i<height; i++)
01995 {
01996 for (j=0; j<length; j++)
01997 {
01998 dstPtr[j<<1] = srcPtr[j];
01999 dstPtr[(j<<1)+1] = srcPtr[j];
02000 }
02001 srcPtr+= srcStride[0];
02002 dstPtr+= dstStride[0];
02003 }
02004 return srcSliceH;
02005 }
02006
02007 static int gray16swap(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
02008 int srcSliceH, uint8_t* dst[], int dstStride[]){
02009
02010 int length= c->srcW;
02011 int y= srcSliceY;
02012 int height= srcSliceH;
02013 int i, j;
02014 uint16_t *srcPtr= (uint16_t*)src[0];
02015 uint16_t *dstPtr= (uint16_t*)(dst[0] + dstStride[0]*y/2);
02016 for (i=0; i<height; i++)
02017 {
02018 for (j=0; j<length; j++) dstPtr[j] = bswap_16(srcPtr[j]);
02019 srcPtr+= srcStride[0]/2;
02020 dstPtr+= dstStride[0]/2;
02021 }
02022 return srcSliceH;
02023 }
02024
02025
02026 static void getSubSampleFactors(int *h, int *v, int format){
02027 switch(format){
02028 case PIX_FMT_UYVY422:
02029 case PIX_FMT_YUYV422:
02030 *h=1;
02031 *v=0;
02032 break;
02033 case PIX_FMT_YUV420P:
02034 case PIX_FMT_YUVA420P:
02035 case PIX_FMT_GRAY16BE:
02036 case PIX_FMT_GRAY16LE:
02037 case PIX_FMT_GRAY8:
02038 case PIX_FMT_NV12:
02039 case PIX_FMT_NV21:
02040 *h=1;
02041 *v=1;
02042 break;
02043 case PIX_FMT_YUV440P:
02044 *h=0;
02045 *v=1;
02046 break;
02047 case PIX_FMT_YUV410P:
02048 *h=2;
02049 *v=2;
02050 break;
02051 case PIX_FMT_YUV444P:
02052 *h=0;
02053 *v=0;
02054 break;
02055 case PIX_FMT_YUV422P:
02056 *h=1;
02057 *v=0;
02058 break;
02059 case PIX_FMT_YUV411P:
02060 *h=2;
02061 *v=0;
02062 break;
02063 default:
02064 *h=0;
02065 *v=0;
02066 break;
02067 }
02068 }
02069
02070 static uint16_t roundToInt16(int64_t f){
02071 int r= (f + (1<<15))>>16;
02072 if (r<-0x7FFF) return 0x8000;
02073 else if (r> 0x7FFF) return 0x7FFF;
02074 else return r;
02075 }
02076
02082 int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation){
02083 int64_t crv = inv_table[0];
02084 int64_t cbu = inv_table[1];
02085 int64_t cgu = -inv_table[2];
02086 int64_t cgv = -inv_table[3];
02087 int64_t cy = 1<<16;
02088 int64_t oy = 0;
02089
02090 memcpy(c->srcColorspaceTable, inv_table, sizeof(int)*4);
02091 memcpy(c->dstColorspaceTable, table, sizeof(int)*4);
02092
02093 c->brightness= brightness;
02094 c->contrast = contrast;
02095 c->saturation= saturation;
02096 c->srcRange = srcRange;
02097 c->dstRange = dstRange;
02098 if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return 0;
02099
02100 c->uOffset= 0x0400040004000400LL;
02101 c->vOffset= 0x0400040004000400LL;
02102
02103 if (!srcRange){
02104 cy= (cy*255) / 219;
02105 oy= 16<<16;
02106 }else{
02107 crv= (crv*224) / 255;
02108 cbu= (cbu*224) / 255;
02109 cgu= (cgu*224) / 255;
02110 cgv= (cgv*224) / 255;
02111 }
02112
02113 cy = (cy *contrast )>>16;
02114 crv= (crv*contrast * saturation)>>32;
02115 cbu= (cbu*contrast * saturation)>>32;
02116 cgu= (cgu*contrast * saturation)>>32;
02117 cgv= (cgv*contrast * saturation)>>32;
02118
02119 oy -= 256*brightness;
02120
02121 c->yCoeff= roundToInt16(cy *8192) * 0x0001000100010001ULL;
02122 c->vrCoeff= roundToInt16(crv*8192) * 0x0001000100010001ULL;
02123 c->ubCoeff= roundToInt16(cbu*8192) * 0x0001000100010001ULL;
02124 c->vgCoeff= roundToInt16(cgv*8192) * 0x0001000100010001ULL;
02125 c->ugCoeff= roundToInt16(cgu*8192) * 0x0001000100010001ULL;
02126 c->yOffset= roundToInt16(oy * 8) * 0x0001000100010001ULL;
02127
02128 c->yuv2rgb_y_coeff = (int16_t)roundToInt16(cy <<13);
02129 c->yuv2rgb_y_offset = (int16_t)roundToInt16(oy << 9);
02130 c->yuv2rgb_v2r_coeff= (int16_t)roundToInt16(crv<<13);
02131 c->yuv2rgb_v2g_coeff= (int16_t)roundToInt16(cgv<<13);
02132 c->yuv2rgb_u2g_coeff= (int16_t)roundToInt16(cgu<<13);
02133 c->yuv2rgb_u2b_coeff= (int16_t)roundToInt16(cbu<<13);
02134
02135 sws_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation);
02136
02137
02138 #ifdef COMPILE_ALTIVEC
02139 if (c->flags & SWS_CPU_CAPS_ALTIVEC)
02140 sws_yuv2rgb_altivec_init_tables (c, inv_table, brightness, contrast, saturation);
02141 #endif
02142 return 0;
02143 }
02144
02148 int sws_getColorspaceDetails(SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation){
02149 if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1;
02150
02151 *inv_table = c->srcColorspaceTable;
02152 *table = c->dstColorspaceTable;
02153 *srcRange = c->srcRange;
02154 *dstRange = c->dstRange;
02155 *brightness= c->brightness;
02156 *contrast = c->contrast;
02157 *saturation= c->saturation;
02158
02159 return 0;
02160 }
02161
02162 static int handle_jpeg(enum PixelFormat *format)
02163 {
02164 switch (*format) {
02165 case PIX_FMT_YUVJ420P:
02166 *format = PIX_FMT_YUV420P;
02167 return 1;
02168 case PIX_FMT_YUVJ422P:
02169 *format = PIX_FMT_YUV422P;
02170 return 1;
02171 case PIX_FMT_YUVJ444P:
02172 *format = PIX_FMT_YUV444P;
02173 return 1;
02174 case PIX_FMT_YUVJ440P:
02175 *format = PIX_FMT_YUV440P;
02176 return 1;
02177 default:
02178 return 0;
02179 }
02180 }
02181
02182 SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, int dstW, int dstH, enum PixelFormat dstFormat, int flags,
02183 SwsFilter *srcFilter, SwsFilter *dstFilter, double *param){
02184
02185 SwsContext *c;
02186 int i;
02187 int usesVFilter, usesHFilter;
02188 int unscaled, needsDither;
02189 int srcRange, dstRange;
02190 SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};
02191 #if ARCH_X86
02192 if (flags & SWS_CPU_CAPS_MMX)
02193 __asm__ volatile("emms\n\t"::: "memory");
02194 #endif
02195
02196 #if !CONFIG_RUNTIME_CPUDETECT //ensure that the flags match the compiled variant if cpudetect is off
02197 flags &= ~(SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2|SWS_CPU_CAPS_3DNOW|SWS_CPU_CAPS_ALTIVEC|SWS_CPU_CAPS_BFIN);
02198 #if HAVE_MMX2
02199 flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2;
02200 #elif HAVE_AMD3DNOW
02201 flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_3DNOW;
02202 #elif HAVE_MMX
02203 flags |= SWS_CPU_CAPS_MMX;
02204 #elif HAVE_ALTIVEC
02205 flags |= SWS_CPU_CAPS_ALTIVEC;
02206 #elif ARCH_BFIN
02207 flags |= SWS_CPU_CAPS_BFIN;
02208 #endif
02209 #endif
02210 if (clip_table[512] != 255) globalInit();
02211 if (!rgb15to16) sws_rgb2rgb_init(flags);
02212
02213 unscaled = (srcW == dstW && srcH == dstH);
02214 needsDither= (isBGR(dstFormat) || isRGB(dstFormat))
02215 && (fmt_depth(dstFormat))<24
02216 && ((fmt_depth(dstFormat))<(fmt_depth(srcFormat)) || (!(isRGB(srcFormat) || isBGR(srcFormat))));
02217
02218 srcRange = handle_jpeg(&srcFormat);
02219 dstRange = handle_jpeg(&dstFormat);
02220
02221 if (!isSupportedIn(srcFormat))
02222 {
02223 av_log(NULL, AV_LOG_ERROR, "swScaler: %s is not supported as input pixel format\n", sws_format_name(srcFormat));
02224 return NULL;
02225 }
02226 if (!isSupportedOut(dstFormat))
02227 {
02228 av_log(NULL, AV_LOG_ERROR, "swScaler: %s is not supported as output pixel format\n", sws_format_name(dstFormat));
02229 return NULL;
02230 }
02231
02232 i= flags & ( SWS_POINT
02233 |SWS_AREA
02234 |SWS_BILINEAR
02235 |SWS_FAST_BILINEAR
02236 |SWS_BICUBIC
02237 |SWS_X
02238 |SWS_GAUSS
02239 |SWS_LANCZOS
02240 |SWS_SINC
02241 |SWS_SPLINE
02242 |SWS_BICUBLIN);
02243 if(!i || (i & (i-1)))
02244 {
02245 av_log(NULL, AV_LOG_ERROR, "swScaler: Exactly one scaler algorithm must be chosen\n");
02246 return NULL;
02247 }
02248
02249
02250 if (srcW<4 || srcH<1 || dstW<8 || dstH<1)
02251 {
02252 av_log(NULL, AV_LOG_ERROR, "swScaler: %dx%d -> %dx%d is invalid scaling dimension\n",
02253 srcW, srcH, dstW, dstH);
02254 return NULL;
02255 }
02256 if(srcW > VOFW || dstW > VOFW){
02257 av_log(NULL, AV_LOG_ERROR, "swScaler: Compile-time maximum width is "AV_STRINGIFY(VOFW)" change VOF/VOFW and recompile\n");
02258 return NULL;
02259 }
02260
02261 if (!dstFilter) dstFilter= &dummyFilter;
02262 if (!srcFilter) srcFilter= &dummyFilter;
02263
02264 c= av_mallocz(sizeof(SwsContext));
02265
02266 c->av_class = &sws_context_class;
02267 c->srcW= srcW;
02268 c->srcH= srcH;
02269 c->dstW= dstW;
02270 c->dstH= dstH;
02271 c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW;
02272 c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH;
02273 c->flags= flags;
02274 c->dstFormat= dstFormat;
02275 c->srcFormat= srcFormat;
02276 c->vRounder= 4* 0x0001000100010001ULL;
02277
02278 usesHFilter= usesVFilter= 0;
02279 if (dstFilter->lumV && dstFilter->lumV->length>1) usesVFilter=1;
02280 if (dstFilter->lumH && dstFilter->lumH->length>1) usesHFilter=1;
02281 if (dstFilter->chrV && dstFilter->chrV->length>1) usesVFilter=1;
02282 if (dstFilter->chrH && dstFilter->chrH->length>1) usesHFilter=1;
02283 if (srcFilter->lumV && srcFilter->lumV->length>1) usesVFilter=1;
02284 if (srcFilter->lumH && srcFilter->lumH->length>1) usesHFilter=1;
02285 if (srcFilter->chrV && srcFilter->chrV->length>1) usesVFilter=1;
02286 if (srcFilter->chrH && srcFilter->chrH->length>1) usesHFilter=1;
02287
02288 getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);
02289 getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);
02290
02291
02292 if ((isBGR(dstFormat) || isRGB(dstFormat)) && !(flags&SWS_FULL_CHR_H_INT)) c->chrDstHSubSample=1;
02293
02294
02295 c->vChrDrop= (flags&SWS_SRC_V_CHR_DROP_MASK)>>SWS_SRC_V_CHR_DROP_SHIFT;
02296 c->chrSrcVSubSample+= c->vChrDrop;
02297
02298
02299 if ((isBGR(srcFormat) || isRGB(srcFormat)) && !(flags&SWS_FULL_CHR_H_INP)
02300 && srcFormat!=PIX_FMT_RGB8 && srcFormat!=PIX_FMT_BGR8
02301 && srcFormat!=PIX_FMT_RGB4 && srcFormat!=PIX_FMT_BGR4
02302 && srcFormat!=PIX_FMT_RGB4_BYTE && srcFormat!=PIX_FMT_BGR4_BYTE
02303 && ((dstW>>c->chrDstHSubSample) <= (srcW>>1) || (flags&(SWS_FAST_BILINEAR|SWS_POINT))))
02304 c->chrSrcHSubSample=1;
02305
02306 if (param){
02307 c->param[0] = param[0];
02308 c->param[1] = param[1];
02309 }else{
02310 c->param[0] =
02311 c->param[1] = SWS_PARAM_DEFAULT;
02312 }
02313
02314 c->chrIntHSubSample= c->chrDstHSubSample;
02315 c->chrIntVSubSample= c->chrSrcVSubSample;
02316
02317
02318 c->chrSrcW= -((-srcW) >> c->chrSrcHSubSample);
02319 c->chrSrcH= -((-srcH) >> c->chrSrcVSubSample);
02320 c->chrDstW= -((-dstW) >> c->chrDstHSubSample);
02321 c->chrDstH= -((-dstH) >> c->chrDstVSubSample);
02322
02323 sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], srcRange, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] , dstRange, 0, 1<<16, 1<<16);
02324
02325
02326 if (unscaled && !usesHFilter && !usesVFilter && (srcRange == dstRange || isBGR(dstFormat) || isRGB(dstFormat)))
02327 {
02328
02329 if ((srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P) && (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21))
02330 {
02331 c->swScale= PlanarToNV12Wrapper;
02332 }
02333
02334 if ((srcFormat==PIX_FMT_YUV420P || srcFormat==PIX_FMT_YUV422P || srcFormat==PIX_FMT_YUVA420P) && (isBGR(dstFormat) || isRGB(dstFormat))
02335 && !(flags & SWS_ACCURATE_RND) && !(dstH&1))
02336 {
02337 c->swScale= sws_yuv2rgb_get_func_ptr(c);
02338 }
02339
02340 if (srcFormat==PIX_FMT_YUV410P && dstFormat==PIX_FMT_YUV420P && !(flags & SWS_BITEXACT))
02341 {
02342 c->swScale= yvu9toyv12Wrapper;
02343 }
02344
02345
02346 if (srcFormat==PIX_FMT_BGR24 && dstFormat==PIX_FMT_YUV420P && !(flags & SWS_ACCURATE_RND))
02347 c->swScale= bgr24toyv12Wrapper;
02348
02349
02350 if ( (isBGR(srcFormat) || isRGB(srcFormat))
02351 && (isBGR(dstFormat) || isRGB(dstFormat))
02352 && srcFormat != PIX_FMT_BGR8 && dstFormat != PIX_FMT_BGR8
02353 && srcFormat != PIX_FMT_RGB8 && dstFormat != PIX_FMT_RGB8
02354 && srcFormat != PIX_FMT_BGR4 && dstFormat != PIX_FMT_BGR4
02355 && srcFormat != PIX_FMT_RGB4 && dstFormat != PIX_FMT_RGB4
02356 && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE
02357 && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE
02358 && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK
02359 && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE
02360 && dstFormat != PIX_FMT_RGB32_1
02361 && dstFormat != PIX_FMT_BGR32_1
02362 && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
02363 c->swScale= rgb2rgbWrapper;
02364
02365 if ((usePal(srcFormat) && (
02366 dstFormat == PIX_FMT_RGB32 ||
02367 dstFormat == PIX_FMT_RGB32_1 ||
02368 dstFormat == PIX_FMT_RGB24 ||
02369 dstFormat == PIX_FMT_BGR32 ||
02370 dstFormat == PIX_FMT_BGR32_1 ||
02371 dstFormat == PIX_FMT_BGR24)))
02372 c->swScale= pal2rgbWrapper;
02373
02374 if (srcFormat == PIX_FMT_YUV422P)
02375 {
02376 if (dstFormat == PIX_FMT_YUYV422)
02377 c->swScale= YUV422PToYuy2Wrapper;
02378 else if (dstFormat == PIX_FMT_UYVY422)
02379 c->swScale= YUV422PToUyvyWrapper;
02380 }
02381
02382
02383 if (c->flags&(SWS_FAST_BILINEAR|SWS_POINT)){
02384
02385 if (srcFormat == PIX_FMT_YUV420P || srcFormat == PIX_FMT_YUVA420P)
02386 {
02387 if (dstFormat == PIX_FMT_YUYV422)
02388 c->swScale= PlanarToYuy2Wrapper;
02389 else if (dstFormat == PIX_FMT_UYVY422)
02390 c->swScale= PlanarToUyvyWrapper;
02391 }
02392 }
02393
02394 #ifdef COMPILE_ALTIVEC
02395 if ((c->flags & SWS_CPU_CAPS_ALTIVEC) &&
02396 !(c->flags & SWS_BITEXACT) &&
02397 srcFormat == PIX_FMT_YUV420P) {
02398
02399 if (dstFormat == PIX_FMT_YUYV422)
02400 c->swScale= yv12toyuy2_unscaled_altivec;
02401 else if (dstFormat == PIX_FMT_UYVY422)
02402 c->swScale= yv12touyvy_unscaled_altivec;
02403 }
02404 #endif
02405
02406
02407 if ( srcFormat == dstFormat
02408 || (srcFormat == PIX_FMT_YUVA420P && dstFormat == PIX_FMT_YUV420P)
02409 || (isPlanarYUV(srcFormat) && isGray(dstFormat))
02410 || (isPlanarYUV(dstFormat) && isGray(srcFormat)))
02411 {
02412 if (isPacked(c->srcFormat))
02413 c->swScale= packedCopy;
02414 else
02415 c->swScale= planarCopy;
02416 }
02417
02418
02419 if (isGray16(srcFormat) && (isPlanarYUV(dstFormat) || (dstFormat == PIX_FMT_GRAY8)))
02420 {
02421 c->swScale= gray16togray;
02422 }
02423 if ((isPlanarYUV(srcFormat) || (srcFormat == PIX_FMT_GRAY8)) && isGray16(dstFormat))
02424 {
02425 c->swScale= graytogray16;
02426 }
02427 if (srcFormat != dstFormat && isGray16(srcFormat) && isGray16(dstFormat))
02428 {
02429 c->swScale= gray16swap;
02430 }
02431
02432 #if ARCH_BFIN
02433 if (flags & SWS_CPU_CAPS_BFIN)
02434 ff_bfin_get_unscaled_swscale (c);
02435 #endif
02436
02437 if (c->swScale){
02438 if (flags&SWS_PRINT_INFO)
02439 av_log(c, AV_LOG_INFO, "using unscaled %s -> %s special converter\n",
02440 sws_format_name(srcFormat), sws_format_name(dstFormat));
02441 return c;
02442 }
02443 }
02444
02445 if (flags & SWS_CPU_CAPS_MMX2)
02446 {
02447 c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
02448 if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR))
02449 {
02450 if (flags&SWS_PRINT_INFO)
02451 av_log(c, AV_LOG_INFO, "output width is not a multiple of 32 -> no MMX2 scaler\n");
02452 }
02453 if (usesHFilter) c->canMMX2BeUsed=0;
02454 }
02455 else
02456 c->canMMX2BeUsed=0;
02457
02458 c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW;
02459 c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH;
02460
02461
02462
02463
02464
02465
02466
02467 if (flags&SWS_FAST_BILINEAR)
02468 {
02469 if (c->canMMX2BeUsed)
02470 {
02471 c->lumXInc+= 20;
02472 c->chrXInc+= 20;
02473 }
02474
02475 else if (flags & SWS_CPU_CAPS_MMX)
02476 {
02477 c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;
02478 c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;
02479 }
02480 }
02481
02482
02483 {
02484 const int filterAlign=
02485 (flags & SWS_CPU_CAPS_MMX) ? 4 :
02486 (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 :
02487 1;
02488
02489 initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc,
02490 srcW , dstW, filterAlign, 1<<14,
02491 (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags,
02492 srcFilter->lumH, dstFilter->lumH, c->param);
02493 initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc,
02494 c->chrSrcW, c->chrDstW, filterAlign, 1<<14,
02495 (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,
02496 srcFilter->chrH, dstFilter->chrH, c->param);
02497
02498 #define MAX_FUNNY_CODE_SIZE 10000
02499 #if defined(COMPILE_MMX2)
02500
02501 if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR))
02502 {
02503 #ifdef MAP_ANONYMOUS
02504 c->funnyYCode = (uint8_t*)mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
02505 c->funnyUVCode = (uint8_t*)mmap(NULL, MAX_FUNNY_CODE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
02506 #else
02507 c->funnyYCode = av_malloc(MAX_FUNNY_CODE_SIZE);
02508 c->funnyUVCode = av_malloc(MAX_FUNNY_CODE_SIZE);
02509 #endif
02510
02511 c->lumMmx2Filter = av_malloc((dstW /8+8)*sizeof(int16_t));
02512 c->chrMmx2Filter = av_malloc((c->chrDstW /4+8)*sizeof(int16_t));
02513 c->lumMmx2FilterPos= av_malloc((dstW /2/8+8)*sizeof(int32_t));
02514 c->chrMmx2FilterPos= av_malloc((c->chrDstW/2/4+8)*sizeof(int32_t));
02515
02516 initMMX2HScaler( dstW, c->lumXInc, c->funnyYCode , c->lumMmx2Filter, c->lumMmx2FilterPos, 8);
02517 initMMX2HScaler(c->chrDstW, c->chrXInc, c->funnyUVCode, c->chrMmx2Filter, c->chrMmx2FilterPos, 4);
02518 }
02519 #endif
02520 }
02521
02522
02523
02524
02525 {
02526 const int filterAlign=
02527 (flags & SWS_CPU_CAPS_MMX) && (flags & SWS_ACCURATE_RND) ? 2 :
02528 (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 :
02529 1;
02530
02531 initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc,
02532 srcH , dstH, filterAlign, (1<<12),
02533 (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags,
02534 srcFilter->lumV, dstFilter->lumV, c->param);
02535 initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc,
02536 c->chrSrcH, c->chrDstH, filterAlign, (1<<12),
02537 (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,
02538 srcFilter->chrV, dstFilter->chrV, c->param);
02539
02540 #if HAVE_ALTIVEC
02541 c->vYCoeffsBank = av_malloc(sizeof (vector signed short)*c->vLumFilterSize*c->dstH);
02542 c->vCCoeffsBank = av_malloc(sizeof (vector signed short)*c->vChrFilterSize*c->chrDstH);
02543
02544 for (i=0;i<c->vLumFilterSize*c->dstH;i++) {
02545 int j;
02546 short *p = (short *)&c->vYCoeffsBank[i];
02547 for (j=0;j<8;j++)
02548 p[j] = c->vLumFilter[i];
02549 }
02550
02551 for (i=0;i<c->vChrFilterSize*c->chrDstH;i++) {
02552 int j;
02553 short *p = (short *)&c->vCCoeffsBank[i];
02554 for (j=0;j<8;j++)
02555 p[j] = c->vChrFilter[i];
02556 }
02557 #endif
02558 }
02559
02560
02561 c->vLumBufSize= c->vLumFilterSize;
02562 c->vChrBufSize= c->vChrFilterSize;
02563 for (i=0; i<dstH; i++)
02564 {
02565 int chrI= i*c->chrDstH / dstH;
02566 int nextSlice= FFMAX(c->vLumFilterPos[i ] + c->vLumFilterSize - 1,
02567 ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<<c->chrSrcVSubSample));
02568
02569 nextSlice>>= c->chrSrcVSubSample;
02570 nextSlice<<= c->chrSrcVSubSample;
02571 if (c->vLumFilterPos[i ] + c->vLumBufSize < nextSlice)
02572 c->vLumBufSize= nextSlice - c->vLumFilterPos[i];
02573 if (c->vChrFilterPos[chrI] + c->vChrBufSize < (nextSlice>>c->chrSrcVSubSample))
02574 c->vChrBufSize= (nextSlice>>c->chrSrcVSubSample) - c->vChrFilterPos[chrI];
02575 }
02576
02577
02578 c->lumPixBuf= av_malloc(c->vLumBufSize*2*sizeof(int16_t*));
02579 c->chrPixBuf= av_malloc(c->vChrBufSize*2*sizeof(int16_t*));
02580
02581
02582 for (i=0; i<c->vLumBufSize; i++)
02583 c->lumPixBuf[i]= c->lumPixBuf[i+c->vLumBufSize]= av_mallocz(VOF+1);
02584 for (i=0; i<c->vChrBufSize; i++)
02585 c->chrPixBuf[i]= c->chrPixBuf[i+c->vChrBufSize]= av_malloc((VOF+1)*2);
02586
02587
02588 for (i=0; i<c->vChrBufSize; i++) memset(c->chrPixBuf[i], 64, (VOF+1)*2);
02589
02590 assert(2*VOFW == VOF);
02591
02592 assert(c->chrDstH <= dstH);
02593
02594 if (flags&SWS_PRINT_INFO)
02595 {
02596 #ifdef DITHER1XBPP
02597 const char *dither= " dithered";
02598 #else
02599 const char *dither= "";
02600 #endif
02601 if (flags&SWS_FAST_BILINEAR)
02602 av_log(c, AV_LOG_INFO, "FAST_BILINEAR scaler, ");
02603 else if (flags&SWS_BILINEAR)
02604 av_log(c, AV_LOG_INFO, "BILINEAR scaler, ");
02605 else if (flags&SWS_BICUBIC)
02606 av_log(c, AV_LOG_INFO, "BICUBIC scaler, ");
02607 else if (flags&SWS_X)
02608 av_log(c, AV_LOG_INFO, "Experimental scaler, ");
02609 else if (flags&SWS_POINT)
02610 av_log(c, AV_LOG_INFO, "Nearest Neighbor / POINT scaler, ");
02611 else if (flags&SWS_AREA)
02612 av_log(c, AV_LOG_INFO, "Area Averageing scaler, ");
02613 else if (flags&SWS_BICUBLIN)
02614 av_log(c, AV_LOG_INFO, "luma BICUBIC / chroma BILINEAR scaler, ");
02615 else if (flags&SWS_GAUSS)
02616 av_log(c, AV_LOG_INFO, "Gaussian scaler, ");
02617 else if (flags&SWS_SINC)
02618 av_log(c, AV_LOG_INFO, "Sinc scaler, ");
02619 else if (flags&SWS_LANCZOS)
02620 av_log(c, AV_LOG_INFO, "Lanczos scaler, ");
02621 else if (flags&SWS_SPLINE)
02622 av_log(c, AV_LOG_INFO, "Bicubic spline scaler, ");
02623 else
02624 av_log(c, AV_LOG_INFO, "ehh flags invalid?! ");
02625
02626 if (dstFormat==PIX_FMT_BGR555 || dstFormat==PIX_FMT_BGR565)
02627 av_log(c, AV_LOG_INFO, "from %s to%s %s ",
02628 sws_format_name(srcFormat), dither, sws_format_name(dstFormat));
02629 else
02630 av_log(c, AV_LOG_INFO, "from %s to %s ",
02631 sws_format_name(srcFormat), sws_format_name(dstFormat));
02632
02633 if (flags & SWS_CPU_CAPS_MMX2)
02634 av_log(c, AV_LOG_INFO, "using MMX2\n");
02635 else if (flags & SWS_CPU_CAPS_3DNOW)
02636 av_log(c, AV_LOG_INFO, "using 3DNOW\n");
02637 else if (flags & SWS_CPU_CAPS_MMX)
02638 av_log(c, AV_LOG_INFO, "using MMX\n");
02639 else if (flags & SWS_CPU_CAPS_ALTIVEC)
02640 av_log(c, AV_LOG_INFO, "using AltiVec\n");
02641 else
02642 av_log(c, AV_LOG_INFO, "using C\n");
02643 }
02644
02645 if (flags & SWS_PRINT_INFO)
02646 {
02647 if (flags & SWS_CPU_CAPS_MMX)
02648 {
02649 if (c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR))
02650 av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR MMX2 scaler for horizontal scaling\n");
02651 else
02652 {
02653 if (c->hLumFilterSize==4)
02654 av_log(c, AV_LOG_VERBOSE, "using 4-tap MMX scaler for horizontal luminance scaling\n");
02655 else if (c->hLumFilterSize==8)
02656 av_log(c, AV_LOG_VERBOSE, "using 8-tap MMX scaler for horizontal luminance scaling\n");
02657 else
02658 av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal luminance scaling\n");
02659
02660 if (c->hChrFilterSize==4)
02661 av_log(c, AV_LOG_VERBOSE, "using 4-tap MMX scaler for horizontal chrominance scaling\n");
02662 else if (c->hChrFilterSize==8)
02663 av_log(c, AV_LOG_VERBOSE, "using 8-tap MMX scaler for horizontal chrominance scaling\n");
02664 else
02665 av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal chrominance scaling\n");
02666 }
02667 }
02668 else
02669 {
02670 #if ARCH_X86
02671 av_log(c, AV_LOG_VERBOSE, "using x86 asm scaler for horizontal scaling\n");
02672 #else
02673 if (flags & SWS_FAST_BILINEAR)
02674 av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR C scaler for horizontal scaling\n");
02675 else
02676 av_log(c, AV_LOG_VERBOSE, "using C scaler for horizontal scaling\n");
02677 #endif
02678 }
02679 if (isPlanarYUV(dstFormat))
02680 {
02681 if (c->vLumFilterSize==1)
02682 av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical scaling (YV12 like)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
02683 else
02684 av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (YV12 like)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
02685 }
02686 else
02687 {
02688 if (c->vLumFilterSize==1 && c->vChrFilterSize==2)
02689 av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical luminance scaling (BGR)\n"
02690 " 2-tap scaler for vertical chrominance scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
02691 else if (c->vLumFilterSize==2 && c->vChrFilterSize==2)
02692 av_log(c, AV_LOG_VERBOSE, "using 2-tap linear %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
02693 else
02694 av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
02695 }
02696
02697 if (dstFormat==PIX_FMT_BGR24)
02698 av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR24 converter\n",
02699 (flags & SWS_CPU_CAPS_MMX2) ? "MMX2" : ((flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"));
02700 else if (dstFormat==PIX_FMT_RGB32)
02701 av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR32 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
02702 else if (dstFormat==PIX_FMT_BGR565)
02703 av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR16 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
02704 else if (dstFormat==PIX_FMT_BGR555)
02705 av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR15 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
02706
02707 av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
02708 }
02709 if (flags & SWS_PRINT_INFO)
02710 {
02711 av_log(c, AV_LOG_DEBUG, "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
02712 c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);
02713 av_log(c, AV_LOG_DEBUG, "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",
02714 c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH, c->chrXInc, c->chrYInc);
02715 }
02716
02717 c->swScale= getSwsFunc(flags);
02718 return c;
02719 }
02720
02725 int sws_scale(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
02726 int srcSliceH, uint8_t* dst[], int dstStride[]){
02727 int i;
02728 uint8_t* src2[4]= {src[0], src[1], src[2]};
02729
02730 if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
02731 av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
02732 return 0;
02733 }
02734 if (c->sliceDir == 0) {
02735 if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
02736 }
02737
02738 if (usePal(c->srcFormat)){
02739 for (i=0; i<256; i++){
02740 int p, r, g, b,y,u,v;
02741 if(c->srcFormat == PIX_FMT_PAL8){
02742 p=((uint32_t*)(src[1]))[i];
02743 r= (p>>16)&0xFF;
02744 g= (p>> 8)&0xFF;
02745 b= p &0xFF;
02746 }else if(c->srcFormat == PIX_FMT_RGB8){
02747 r= (i>>5 )*36;
02748 g= ((i>>2)&7)*36;
02749 b= (i&3 )*85;
02750 }else if(c->srcFormat == PIX_FMT_BGR8){
02751 b= (i>>6 )*85;
02752 g= ((i>>3)&7)*36;
02753 r= (i&7 )*36;
02754 }else if(c->srcFormat == PIX_FMT_RGB4_BYTE){
02755 r= (i>>3 )*255;
02756 g= ((i>>1)&3)*85;
02757 b= (i&1 )*255;
02758 }else {
02759 assert(c->srcFormat == PIX_FMT_BGR4_BYTE);
02760 b= (i>>3 )*255;
02761 g= ((i>>1)&3)*85;
02762 r= (i&1 )*255;
02763 }
02764 y= av_clip_uint8((RY*r + GY*g + BY*b + ( 33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
02765 u= av_clip_uint8((RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
02766 v= av_clip_uint8((RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
02767 c->pal_yuv[i]= y + (u<<8) + (v<<16);
02768
02769
02770 switch(c->dstFormat) {
02771 case PIX_FMT_BGR32:
02772 #ifndef WORDS_BIGENDIAN
02773 case PIX_FMT_RGB24:
02774 #endif
02775 c->pal_rgb[i]= r + (g<<8) + (b<<16);
02776 break;
02777 case PIX_FMT_BGR32_1:
02778 #ifdef WORDS_BIGENDIAN
02779 case PIX_FMT_BGR24:
02780 #endif
02781 c->pal_rgb[i]= (r + (g<<8) + (b<<16)) << 8;
02782 break;
02783 case PIX_FMT_RGB32_1:
02784 #ifdef WORDS_BIGENDIAN
02785 case PIX_FMT_RGB24:
02786 #endif
02787 c->pal_rgb[i]= (b + (g<<8) + (r<<16)) << 8;
02788 break;
02789 case PIX_FMT_RGB32:
02790 #ifndef WORDS_BIGENDIAN
02791 case PIX_FMT_BGR24:
02792 #endif
02793 default:
02794 c->pal_rgb[i]= b + (g<<8) + (r<<16);
02795 }
02796 }
02797 }
02798
02799
02800 if (c->sliceDir == 1) {
02801
02802 int srcStride2[4]= {srcStride[0], srcStride[1], srcStride[2]};
02803 int dstStride2[4]= {dstStride[0], dstStride[1], dstStride[2]};
02804 return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst, dstStride2);
02805 } else {
02806
02807 uint8_t* dst2[4]= {dst[0] + (c->dstH-1)*dstStride[0],
02808 dst[1] + ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[1],
02809 dst[2] + ((c->dstH>>c->chrDstVSubSample)-1)*dstStride[2]};
02810 int srcStride2[4]= {-srcStride[0], -srcStride[1], -srcStride[2]};
02811 int dstStride2[4]= {-dstStride[0], -dstStride[1], -dstStride[2]};
02812
02813 src2[0] += (srcSliceH-1)*srcStride[0];
02814 if (!usePal(c->srcFormat))
02815 src2[1] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[1];
02816 src2[2] += ((srcSliceH>>c->chrSrcVSubSample)-1)*srcStride[2];
02817
02818 return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2);
02819 }
02820 }
02821
02822 #if LIBSWSCALE_VERSION_MAJOR < 1
02823 int sws_scale_ordered(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
02824 int srcSliceH, uint8_t* dst[], int dstStride[]){
02825 return sws_scale(c, src, srcStride, srcSliceY, srcSliceH, dst, dstStride);
02826 }
02827 #endif
02828
02829 SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
02830 float lumaSharpen, float chromaSharpen,
02831 float chromaHShift, float chromaVShift,
02832 int verbose)
02833 {
02834 SwsFilter *filter= av_malloc(sizeof(SwsFilter));
02835
02836 if (lumaGBlur!=0.0){
02837 filter->lumH= sws_getGaussianVec(lumaGBlur, 3.0);
02838 filter->lumV= sws_getGaussianVec(lumaGBlur, 3.0);
02839 }else{
02840 filter->lumH= sws_getIdentityVec();
02841 filter->lumV= sws_getIdentityVec();
02842 }
02843
02844 if (chromaGBlur!=0.0){
02845 filter->chrH= sws_getGaussianVec(chromaGBlur, 3.0);
02846 filter->chrV= sws_getGaussianVec(chromaGBlur, 3.0);
02847 }else{
02848 filter->chrH= sws_getIdentityVec();
02849 filter->chrV= sws_getIdentityVec();
02850 }
02851
02852 if (chromaSharpen!=0.0){
02853 SwsVector *id= sws_getIdentityVec();
02854 sws_scaleVec(filter->chrH, -chromaSharpen);
02855 sws_scaleVec(filter->chrV, -chromaSharpen);
02856 sws_addVec(filter->chrH, id);
02857 sws_addVec(filter->chrV, id);
02858 sws_freeVec(id);
02859 }
02860
02861 if (lumaSharpen!=0.0){
02862 SwsVector *id= sws_getIdentityVec();
02863 sws_scaleVec(filter->lumH, -lumaSharpen);
02864 sws_scaleVec(filter->lumV, -lumaSharpen);
02865 sws_addVec(filter->lumH, id);
02866 sws_addVec(filter->lumV, id);
02867 sws_freeVec(id);
02868 }
02869
02870 if (chromaHShift != 0.0)
02871 sws_shiftVec(filter->chrH, (int)(chromaHShift+0.5));
02872
02873 if (chromaVShift != 0.0)
02874 sws_shiftVec(filter->chrV, (int)(chromaVShift+0.5));
02875
02876 sws_normalizeVec(filter->chrH, 1.0);
02877 sws_normalizeVec(filter->chrV, 1.0);
02878 sws_normalizeVec(filter->lumH, 1.0);
02879 sws_normalizeVec(filter->lumV, 1.0);
02880
02881 if (verbose) sws_printVec2(filter->chrH, NULL, AV_LOG_DEBUG);
02882 if (verbose) sws_printVec2(filter->lumH, NULL, AV_LOG_DEBUG);
02883
02884 return filter;
02885 }
02886
02887 SwsVector *sws_getGaussianVec(double variance, double quality){
02888 const int length= (int)(variance*quality + 0.5) | 1;
02889 int i;
02890 double *coeff= av_malloc(length*sizeof(double));
02891 double middle= (length-1)*0.5;
02892 SwsVector *vec= av_malloc(sizeof(SwsVector));
02893
02894 vec->coeff= coeff;
02895 vec->length= length;
02896
02897 for (i=0; i<length; i++)
02898 {
02899 double dist= i-middle;
02900 coeff[i]= exp(-dist*dist/(2*variance*variance)) / sqrt(2*variance*PI);
02901 }
02902
02903 sws_normalizeVec(vec, 1.0);
02904
02905 return vec;
02906 }
02907
02908 SwsVector *sws_getConstVec(double c, int length){
02909 int i;
02910 double *coeff= av_malloc(length*sizeof(double));
02911 SwsVector *vec= av_malloc(sizeof(SwsVector));
02912
02913 vec->coeff= coeff;
02914 vec->length= length;
02915
02916 for (i=0; i<length; i++)
02917 coeff[i]= c;
02918
02919 return vec;
02920 }
02921
02922
02923 SwsVector *sws_getIdentityVec(void){
02924 return sws_getConstVec(1.0, 1);
02925 }
02926
02927 double sws_dcVec(SwsVector *a){
02928 int i;
02929 double sum=0;
02930
02931 for (i=0; i<a->length; i++)
02932 sum+= a->coeff[i];
02933
02934 return sum;
02935 }
02936
02937 void sws_scaleVec(SwsVector *a, double scalar){
02938 int i;
02939
02940 for (i=0; i<a->length; i++)
02941 a->coeff[i]*= scalar;
02942 }
02943
02944 void sws_normalizeVec(SwsVector *a, double height){
02945 sws_scaleVec(a, height/sws_dcVec(a));
02946 }
02947
02948 static SwsVector *sws_getConvVec(SwsVector *a, SwsVector *b){
02949 int length= a->length + b->length - 1;
02950 double *coeff= av_malloc(length*sizeof(double));
02951 int i, j;
02952 SwsVector *vec= av_malloc(sizeof(SwsVector));
02953
02954 vec->coeff= coeff;
02955 vec->length= length;
02956
02957 for (i=0; i<length; i++) coeff[i]= 0.0;
02958
02959 for (i=0; i<a->length; i++)
02960 {
02961 for (j=0; j<b->length; j++)
02962 {
02963 coeff[i+j]+= a->coeff[i]*b->coeff[j];
02964 }
02965 }
02966
02967 return vec;
02968 }
02969
02970 static SwsVector *sws_sumVec(SwsVector *a, SwsVector *b){
02971 int length= FFMAX(a->length, b->length);
02972 double *coeff= av_malloc(length*sizeof(double));
02973 int i;
02974 SwsVector *vec= av_malloc(sizeof(SwsVector));
02975
02976 vec->coeff= coeff;
02977 vec->length= length;
02978
02979 for (i=0; i<length; i++) coeff[i]= 0.0;
02980
02981 for (i=0; i<a->length; i++) coeff[i + (length-1)/2 - (a->length-1)/2]+= a->coeff[i];
02982 for (i=0; i<b->length; i++) coeff[i + (length-1)/2 - (b->length-1)/2]+= b->coeff[i];
02983
02984 return vec;
02985 }
02986
02987 static SwsVector *sws_diffVec(SwsVector *a, SwsVector *b){
02988 int length= FFMAX(a->length, b->length);
02989 double *coeff= av_malloc(length*sizeof(double));
02990 int i;
02991 SwsVector *vec= av_malloc(sizeof(SwsVector));
02992
02993 vec->coeff= coeff;
02994 vec->length= length;
02995
02996 for (i=0; i<length; i++) coeff[i]= 0.0;
02997
02998 for (i=0; i<a->length; i++) coeff[i + (length-1)/2 - (a->length-1)/2]+= a->coeff[i];
02999 for (i=0; i<b->length; i++) coeff[i + (length-1)/2 - (b->length-1)/2]-= b->coeff[i];
03000
03001 return vec;
03002 }
03003
03004
03005 static SwsVector *sws_getShiftedVec(SwsVector *a, int shift){
03006 int length= a->length + FFABS(shift)*2;
03007 double *coeff= av_malloc(length*sizeof(double));
03008 int i;
03009 SwsVector *vec= av_malloc(sizeof(SwsVector));
03010
03011 vec->coeff= coeff;
03012 vec->length= length;
03013
03014 for (i=0; i<length; i++) coeff[i]= 0.0;
03015
03016 for (i=0; i<a->length; i++)
03017 {
03018 coeff[i + (length-1)/2 - (a->length-1)/2 - shift]= a->coeff[i];
03019 }
03020
03021 return vec;
03022 }
03023
03024 void sws_shiftVec(SwsVector *a, int shift){
03025 SwsVector *shifted= sws_getShiftedVec(a, shift);
03026 av_free(a->coeff);
03027 a->coeff= shifted->coeff;
03028 a->length= shifted->length;
03029 av_free(shifted);
03030 }
03031
03032 void sws_addVec(SwsVector *a, SwsVector *b){
03033 SwsVector *sum= sws_sumVec(a, b);
03034 av_free(a->coeff);
03035 a->coeff= sum->coeff;
03036 a->length= sum->length;
03037 av_free(sum);
03038 }
03039
03040 void sws_subVec(SwsVector *a, SwsVector *b){
03041 SwsVector *diff= sws_diffVec(a, b);
03042 av_free(a->coeff);
03043 a->coeff= diff->coeff;
03044 a->length= diff->length;
03045 av_free(diff);
03046 }
03047
03048 void sws_convVec(SwsVector *a, SwsVector *b){
03049 SwsVector *conv= sws_getConvVec(a, b);
03050 av_free(a->coeff);
03051 a->coeff= conv->coeff;
03052 a->length= conv->length;
03053 av_free(conv);
03054 }
03055
03056 SwsVector *sws_cloneVec(SwsVector *a){
03057 double *coeff= av_malloc(a->length*sizeof(double));
03058 int i;
03059 SwsVector *vec= av_malloc(sizeof(SwsVector));
03060
03061 vec->coeff= coeff;
03062 vec->length= a->length;
03063
03064 for (i=0; i<a->length; i++) coeff[i]= a->coeff[i];
03065
03066 return vec;
03067 }
03068
03069 void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level){
03070 int i;
03071 double max=0;
03072 double min=0;
03073 double range;
03074
03075 for (i=0; i<a->length; i++)
03076 if (a->coeff[i]>max) max= a->coeff[i];
03077
03078 for (i=0; i<a->length; i++)
03079 if (a->coeff[i]<min) min= a->coeff[i];
03080
03081 range= max - min;
03082
03083 for (i=0; i<a->length; i++)
03084 {
03085 int x= (int)((a->coeff[i]-min)*60.0/range +0.5);
03086 av_log(log_ctx, log_level, "%1.3f ", a->coeff[i]);
03087 for (;x>0; x--) av_log(log_ctx, log_level, " ");
03088 av_log(log_ctx, log_level, "|\n");
03089 }
03090 }
03091
03092 #if LIBSWSCALE_VERSION_MAJOR < 1
03093 void sws_printVec(SwsVector *a){
03094 sws_printVec2(a, NULL, AV_LOG_DEBUG);
03095 }
03096 #endif
03097
03098 void sws_freeVec(SwsVector *a){
03099 if (!a) return;
03100 av_freep(&a->coeff);
03101 a->length=0;
03102 av_free(a);
03103 }
03104
03105 void sws_freeFilter(SwsFilter *filter){
03106 if (!filter) return;
03107
03108 if (filter->lumH) sws_freeVec(filter->lumH);
03109 if (filter->lumV) sws_freeVec(filter->lumV);
03110 if (filter->chrH) sws_freeVec(filter->chrH);
03111 if (filter->chrV) sws_freeVec(filter->chrV);
03112 av_free(filter);
03113 }
03114
03115
03116 void sws_freeContext(SwsContext *c){
03117 int i;
03118 if (!c) return;
03119
03120 if (c->lumPixBuf)
03121 {
03122 for (i=0; i<c->vLumBufSize; i++)
03123 av_freep(&c->lumPixBuf[i]);
03124 av_freep(&c->lumPixBuf);
03125 }
03126
03127 if (c->chrPixBuf)
03128 {
03129 for (i=0; i<c->vChrBufSize; i++)
03130 av_freep(&c->chrPixBuf[i]);
03131 av_freep(&c->chrPixBuf);
03132 }
03133
03134 av_freep(&c->vLumFilter);
03135 av_freep(&c->vChrFilter);
03136 av_freep(&c->hLumFilter);
03137 av_freep(&c->hChrFilter);
03138 #if HAVE_ALTIVEC
03139 av_freep(&c->vYCoeffsBank);
03140 av_freep(&c->vCCoeffsBank);
03141 #endif
03142
03143 av_freep(&c->vLumFilterPos);
03144 av_freep(&c->vChrFilterPos);
03145 av_freep(&c->hLumFilterPos);
03146 av_freep(&c->hChrFilterPos);
03147
03148 #if ARCH_X86 && CONFIG_GPL
03149 #ifdef MAP_ANONYMOUS
03150 if (c->funnyYCode) munmap(c->funnyYCode, MAX_FUNNY_CODE_SIZE);
03151 if (c->funnyUVCode) munmap(c->funnyUVCode, MAX_FUNNY_CODE_SIZE);
03152 #else
03153 av_free(c->funnyYCode);
03154 av_free(c->funnyUVCode);
03155 #endif
03156 c->funnyYCode=NULL;
03157 c->funnyUVCode=NULL;
03158 #endif
03159
03160 av_freep(&c->lumMmx2Filter);
03161 av_freep(&c->chrMmx2Filter);
03162 av_freep(&c->lumMmx2FilterPos);
03163 av_freep(&c->chrMmx2FilterPos);
03164 av_freep(&c->yuvTable);
03165
03166 av_free(c);
03167 }
03168
03169 struct SwsContext *sws_getCachedContext(struct SwsContext *context,
03170 int srcW, int srcH, enum PixelFormat srcFormat,
03171 int dstW, int dstH, enum PixelFormat dstFormat, int flags,
03172 SwsFilter *srcFilter, SwsFilter *dstFilter, double *param)
03173 {
03174 static const double default_param[2] = {SWS_PARAM_DEFAULT, SWS_PARAM_DEFAULT};
03175
03176 if (!param)
03177 param = default_param;
03178
03179 if (context) {
03180 if (context->srcW != srcW || context->srcH != srcH ||
03181 context->srcFormat != srcFormat ||
03182 context->dstW != dstW || context->dstH != dstH ||
03183 context->dstFormat != dstFormat || context->flags != flags ||
03184 context->param[0] != param[0] || context->param[1] != param[1])
03185 {
03186 sws_freeContext(context);
03187 context = NULL;
03188 }
03189 }
03190 if (!context) {
03191 return sws_getContext(srcW, srcH, srcFormat,
03192 dstW, dstH, dstFormat, flags,
03193 srcFilter, dstFilter, param);
03194 }
03195 return context;
03196 }
03197