* qatar/master: (22 commits) configure: enable memalign_hack automatically when needed swscale: unbreak the build on non-x86 systems. swscale: remove if(bitexact) branch from functions. swscale: remove if(canMMX2BeUsed) conditional. swscale: remove swScale_{c,MMX,MMX2} duplication. swscale: use emms_c(). Move emms_c() from libavcodec to libavutil. tiff: set palette in the context when specified in TIFF_PAL tag rtsp: use strtoul to parse rtptime and seq values. pgssubdec: fix incorrect colors. dvdsubdec: fix incorrect colors. ape: Allow demuxing of files with metadata tags. swscale: remove dead macro WRITEBGR24OLD. swscale: remove AMD3DNOW "optimizations". swscale: remove duplicate code in ppc/ subdirectory. swscale: remove duplicated x86/ functions. swscale: force --enable-runtime-cpudetect and remove SWS_CPU_CAPS_*. vsrc_buffer.h: add file doxy vsrc_buffer: tweak error message in init() msmpeg4: reindent. ...
Unified · Split
| @@ -2859,11 +2859,6 @@ check_header X11/extensions/XvMClib.h · 2858 unmodified lines | |||
| 2859 | 2859 | ||
| 2860 | check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex | 2860 | check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex |
| 2861 | 2861 | ||
| 2862 | if ! enabled_any memalign memalign_hack posix_memalign malloc_aligned && | ||
| 2863 | enabled_any $need_memalign ; then | ||
| 2864 | die "Error, no aligned memory allocator but SSE enabled, disable it or use --enable-memalign-hack." | ||
| 2865 | fi | ||
| 2866 | |||
| 2867 | disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib | 2862 | disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib |
| 2868 | disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib | 2863 | disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib |
| 2869 | 2864 | ||
| @@ -3156,6 +3151,9 @@ check_deps $CONFIG_LIST \ · 286 unmodified lines | |||
| 3156 | 3151 | ||
| 3157 | enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; } | 3152 | enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; } |
| 3158 | 3153 | ||
| 3154 | ! enabled_any memalign posix_memalign malloc_aligned && | ||
| 3155 | enabled_any $need_memalign && enable memalign_hack | ||
| 3156 | |||
| 3159 | echo "install prefix $prefix" | 3157 | echo "install prefix $prefix" |
| 3160 | echo "source path $source_path" | 3158 | echo "source path $source_path" |
| 3161 | echo "C compiler $cc" | 3159 | echo "C compiler $cc" |
| @@ -433,3 +433,49 @@ For more information about libx264 and the supported options see: · 432 unmodified lines | |||
| 433 | @url{http://www.videolan.org/developers/x264.html} | 433 | @url{http://www.videolan.org/developers/x264.html} |
| 434 | 434 | ||
| 435 | @c man end VIDEO ENCODERS | 435 | @c man end VIDEO ENCODERS |
| 436 | |||
| 437 | @subheading Floating-Point-Only AC-3 Encoding Options | ||
| 438 | |||
| 439 | These options are only valid for the floating-point encoder and do not exist | ||
| 440 | for the fixed-point encoder due to the corresponding features not being | ||
| 441 | implemented in fixed-point. | ||
| 442 | |||
| 443 | @table @option | ||
| 444 | |||
| 445 | @item -channel_coupling @var{boolean} | ||
| 446 | Enables/Disables use of channel coupling, which is an optional AC-3 feature | ||
| 447 | that increases quality by combining high frequency information from multiple | ||
| 448 | channels into a single channel. The per-channel high frequency information is | ||
| 449 | sent with less accuracy in both the frequency and time domains. This allows | ||
| 450 | more bits to be used for lower frequencies while preserving enough information | ||
| 451 | to reconstruct the high frequencies. This option is enabled by default for the | ||
| 452 | floating-point encoder and should generally be left as enabled except for | ||
| 453 | testing purposes or to increase encoding speed. | ||
| 454 | @table @option | ||
| 455 | @item -1 | ||
| 456 | @itemx auto | ||
| 457 | Selected by Encoder (default) | ||
| 458 | @item 0 | ||
| 459 | @itemx off | ||
| 460 | Disable Channel Coupling | ||
| 461 | @item 1 | ||
| 462 | @itemx on | ||
| 463 | Enable Channel Coupling | ||
| 464 | @end table | ||
| 465 | |||
| 466 | @item -cpl_start_band @var{number} | ||
| 467 | Coupling Start Band. Sets the channel coupling start band, from 1 to 15. If a | ||
| 468 | value higher than the bandwidth is used, it will be reduced to 1 less than the | ||
| 469 | coupling end band. If @var{auto} is used, the start band will be determined by | ||
| 470 | the encoder based on the bit rate, sample rate, and channel layout. This option | ||
| 471 | has no effect if channel coupling is disabled. | ||
| 472 | @table @option | ||
| 473 | @item -1 | ||
| 474 | @itemx auto | ||
| 475 | Selected by Encoder (default) | ||
| 476 | @end table | ||
| 477 | |||
| 478 | @end table | ||
| 479 | |||
| 480 | @c man end ENCODERS | ||
| 481 | |||
| @@ -269,8 +269,6 @@ OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ · 268 unmodified lines | |||
| 269 | mpegvideo.o error_resilience.o | 269 | mpegvideo.o error_resilience.o |
| 270 | OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o | 270 | OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o |
| 271 | OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o | 271 | OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o |
| 272 | OBJS-$(CONFIG_MSMPEG4V1_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ | ||
| 273 | h263.o ituh263dec.o mpeg4videodec.o | ||
| 274 | OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ | 272 | OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ |
| 275 | h263.o ituh263dec.o mpeg4videodec.o | 273 | h263.o ituh263dec.o mpeg4videodec.o |
| 276 | OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ | 274 | OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ |
| @@ -28,7 +28,8 @@ · 27 unmodified lines | |||
| 28 | #define AVCODEC_AC3_H | 28 | #define AVCODEC_AC3_H |
| 29 | 29 | ||
| 30 | #define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ | 30 | #define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ |
| 31 | #define AC3_MAX_CHANNELS 6 /* including LFE channel */ | 31 | #define AC3_MAX_CHANNELS 7 /**< maximum number of channels, including coupling channel */ |
| 32 | #define CPL_CH 0 /**< coupling channel index */ | ||
| 32 | 33 | ||
| 33 | #define AC3_MAX_COEFS 256 | 34 | #define AC3_MAX_COEFS 256 |
| 34 | #define AC3_BLOCK_SIZE 256 | 35 | #define AC3_BLOCK_SIZE 256 |
| @@ -158,7 +159,9 @@ typedef struct AC3EncOptions { · 123 unmodified lines | |||
| 158 | 159 | ||
| 159 | /* other encoding options */ | 160 | /* other encoding options */ |
| 160 | int allow_per_frame_metadata; | 161 | int allow_per_frame_metadata; |
| 161 | int stereo_rematrixing; | 162 | int stereo_rematrixing; |
| 163 | int channel_coupling; | ||
| 164 | int cpl_start; | ||
| 162 | } AC3EncOptions; | 165 | } AC3EncOptions; |
| 163 | 166 | ||
| 164 | 167 | ||
| @@ -58,11 +58,6 @@ · 57 unmodified lines | |||
| 58 | #include "fft.h" | 58 | #include "fft.h" |
| 59 | #include "fmtconvert.h" | 59 | #include "fmtconvert.h" |
| 60 | 60 | ||
| 61 | /* override ac3.h to include coupling channel */ | ||
| 62 | #undef AC3_MAX_CHANNELS | ||
| 63 | #define AC3_MAX_CHANNELS 7 | ||
| 64 | #define CPL_CH 0 | ||
| 65 | |||
| 66 | #define AC3_OUTPUT_LFEON 8 | 61 | #define AC3_OUTPUT_LFEON 8 |
| 67 | 62 | ||
| 68 | #define SPX_MAX_BANDS 17 | 63 | #define SPX_MAX_BANDS 17 |
| @@ -53,12 +53,6 @@ const uint8_t ff_eac3_hebap_tab[64] = { · 52 unmodified lines | |||
| 53 | 19, 19, 19, 19, | 53 | 19, 19, 19, 19, |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | /** | ||
| 57 | * Table E2.16 Default Coupling Banding Structure | ||
| 58 | */ | ||
| 59 | const uint8_t ff_eac3_default_cpl_band_struct[18] = | ||
| 60 | { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 }; | ||
| 61 | |||
| 62 | /** | 56 | /** |
| 63 | * Table E2.15 Default Spectral Extension Banding Structure | 57 | * Table E2.15 Default Spectral Extension Banding Structure |
| 64 | */ | 58 | */ |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | |||
| 27 | extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3]; | 27 | extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3]; |
| 28 | 28 | ||
| 29 | extern const uint8_t ff_eac3_hebap_tab[64]; | 29 | extern const uint8_t ff_eac3_hebap_tab[64]; |
| 30 | extern const uint8_t ff_eac3_default_cpl_band_struct[18]; | ||
| 31 | extern const uint8_t ff_eac3_default_spx_band_struct[17]; | 30 | extern const uint8_t ff_eac3_default_spx_band_struct[17]; |
| 32 | 31 | ||
| 33 | #endif /* AVCODEC_AC3DEC_DATA_H */ | 32 | #endif /* AVCODEC_AC3DEC_DATA_H */ |
| @@ -70,6 +70,7 @@ typedef struct AC3MDCTContext { · 69 unmodified lines | |||
| 70 | FFTContext fft; ///< FFT context for MDCT calculation | 70 | FFTContext fft; ///< FFT context for MDCT calculation |
| 71 | } AC3MDCTContext; | 71 | } AC3MDCTContext; |
| 72 | 72 | ||
| 73 | |||
| 73 | /** | 74 | /** |
| 74 | * Data for a single audio block. | 75 | * Data for a single audio block. |
| 75 | */ | 76 | */ |
| @@ -83,10 +84,22 @@ typedef struct AC3Block { · 7 unmodified lines | |||
| 83 | int16_t **band_psd; ///< psd per critical band | 84 | int16_t **band_psd; ///< psd per critical band |
| 84 | int16_t **mask; ///< masking curve | 85 | int16_t **mask; ///< masking curve |
| 85 | uint16_t **qmant; ///< quantized mantissas | 86 | uint16_t **qmant; ///< quantized mantissas |
| 87 | uint8_t **cpl_coord_exp; ///< coupling coord exponents (cplcoexp) | ||
| 88 | uint8_t **cpl_coord_mant; ///< coupling coord mantissas (cplcomant) | ||
| 86 | uint8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values | 89 | uint8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values |
| 87 | uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block | 90 | uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block |
| 91 | int num_rematrixing_bands; ///< number of rematrixing bands | ||
| 88 | uint8_t rematrixing_flags[4]; ///< rematrixing flags | 92 | uint8_t rematrixing_flags[4]; ///< rematrixing flags |
| 89 | struct AC3Block *exp_ref_block[AC3_MAX_CHANNELS]; ///< reference blocks for EXP_REUSE | 93 | struct AC3Block *exp_ref_block[AC3_MAX_CHANNELS]; ///< reference blocks for EXP_REUSE |
| 94 | int new_cpl_strategy; ///< send new coupling strategy | ||
| 95 | int cpl_in_use; ///< coupling in use for this block (cplinu) | ||
| 96 | uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) | ||
| 97 | int num_cpl_channels; ///< number of channels in coupling | ||
| 98 | uint8_t new_cpl_coords; ///< send new coupling coordinates (cplcoe) | ||
| 99 | uint8_t cpl_master_exp[AC3_MAX_CHANNELS]; ///< coupling coord master exponents (mstrcplco) | ||
| 100 | int new_snr_offsets; ///< send new SNR offsets | ||
| 101 | int new_cpl_leak; ///< send new coupling leak info | ||
| 102 | int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant) | ||
| 90 | } AC3Block; | 103 | } AC3Block; |
| 91 | 104 | ||
| 92 | /** | 105 | /** |
| @@ -133,10 +146,16 @@ typedef struct AC3EncodeContext { · 40 unmodified lines | |||
| 133 | 146 | ||
| 134 | int cutoff; ///< user-specified cutoff frequency, in Hz | 147 | int cutoff; ///< user-specified cutoff frequency, in Hz |
| 135 | int bandwidth_code; ///< bandwidth code (0 to 60) (chbwcod) | 148 | int bandwidth_code; ///< bandwidth code (0 to 60) (chbwcod) |
| 136 | int nb_coefs[AC3_MAX_CHANNELS]; | 149 | int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin (strtmant) |
| 150 | int cpl_end_freq; ///< coupling channel end frequency bin | ||
| 151 | |||
| 152 | int cpl_on; ///< coupling turned on for this frame | ||
| 153 | int cpl_enabled; ///< coupling enabled for all frames | ||
| 154 | int num_cpl_subbands; ///< number of coupling subbands (ncplsubnd) | ||
| 155 | int num_cpl_bands; ///< number of coupling bands (ncplbnd) | ||
| 156 | uint8_t cpl_band_sizes[AC3_MAX_CPL_BANDS]; ///< number of coeffs in each coupling band | ||
| 137 | 157 | ||
| 138 | int rematrixing_enabled; ///< stereo rematrixing enabled | 158 | int rematrixing_enabled; ///< stereo rematrixing enabled |
| 139 | int num_rematrixing_bands; ///< number of rematrixing bands | ||
| 140 | 159 | ||
| 141 | /* bitrate allocation control */ | 160 | /* bitrate allocation control */ |
| 142 | int slow_gain_code; ///< slow gain code (sgaincod) | 161 | int slow_gain_code; ///< slow gain code (sgaincod) |
| @@ -163,6 +182,8 @@ typedef struct AC3EncodeContext { · 20 unmodified lines | |||
| 163 | int16_t *band_psd_buffer; | 182 | int16_t *band_psd_buffer; |
| 164 | int16_t *mask_buffer; | 183 | int16_t *mask_buffer; |
| 165 | uint16_t *qmant_buffer; | 184 | uint16_t *qmant_buffer; |
| 185 | uint8_t *cpl_coord_exp_buffer; | ||
| 186 | uint8_t *cpl_coord_mant_buffer; | ||
| 166 | 187 | ||
| 167 | uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies | 188 | uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies |
| 168 | 189 | ||
| @@ -237,6 +258,12 @@ const AVOption ff_ac3_options[] = { · 68 unmodified lines | |||
| 237 | {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, | 258 | {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, |
| 238 | /* Other Encoding Options */ | 259 | /* Other Encoding Options */ |
| 239 | {"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM}, | 260 | {"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM}, |
| 261 | #if CONFIG_AC3ENC_FLOAT | ||
| 262 | {"channel_coupling", "Channel Coupling", OFFSET(channel_coupling), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM, "channel_coupling"}, | ||
| 263 | {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"}, | ||
| 264 | {"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 15, AC3ENC_PARAM, "cpl_start_band"}, | ||
| 265 | {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"}, | ||
| 266 | #endif | ||
| 240 | {NULL} | 267 | {NULL} |
| 241 | }; | 268 | }; |
| 242 | #endif | 269 | #endif |
| @@ -267,9 +294,9 @@ static void scale_coefficients(AC3EncodeContext *s); · 24 unmodified lines | |||
| 267 | 294 | ||
| 268 | /** | 295 | /** |
| 269 | * LUT for number of exponent groups. | 296 | * LUT for number of exponent groups. |
| 270 | * exponent_group_tab[exponent strategy-1][number of coefficients] | 297 | * exponent_group_tab[coupling][exponent strategy-1][number of coefficients] |
| 271 | */ | 298 | */ |
| 272 | static uint8_t exponent_group_tab[3][256]; | 299 | static uint8_t exponent_group_tab[2][3][256]; |
| 273 | 300 | ||
| 274 | 301 | ||
| 275 | /** | 302 | /** |
| @@ -330,6 +357,49 @@ static const uint8_t ac3_bandwidth_tab[5][3][19] = { · 54 unmodified lines | |||
| 330 | }; | 357 | }; |
| 331 | 358 | ||
| 332 | 359 | ||
| 360 | /** | ||
| 361 | * LUT to select the coupling start band based on the bit rate, sample rate, and | ||
| 362 | * number of full-bandwidth channels. -1 = coupling off | ||
| 363 | * ac3_coupling_start_tab[channel_mode-2][sample rate code][bit rate code] | ||
| 364 | * | ||
| 365 | * TODO: more testing for optimal parameters. | ||
| 366 | * multi-channel tests at 44.1kHz and 32kHz. | ||
| 367 | */ | ||
| 368 | static const int8_t ac3_coupling_start_tab[6][3][19] = { | ||
| 369 | // 32 40 48 56 64 80 96 112 128 160 192 224 256 320 384 448 512 576 640 | ||
| 370 | |||
| 371 | // 2/0 | ||
| 372 | { { 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, 8, 11, 12, -1, -1, -1, -1, -1, -1 }, | ||
| 373 | { 0, 0, 0, 0, 0, 0, 1, 3, 5, 7, 10, 12, 13, -1, -1, -1, -1, -1, -1 }, | ||
| 374 | { 0, 0, 0, 0, 1, 2, 2, 9, 13, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, | ||
| 375 | |||
| 376 | // 3/0 | ||
| 377 | { { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 }, | ||
| 378 | { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 }, | ||
| 379 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, | ||
| 380 | |||
| 381 | // 2/1 - untested | ||
| 382 | { { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 }, | ||
| 383 | { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 }, | ||
| 384 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, | ||
| 385 | |||
| 386 | // 3/1 | ||
| 387 | { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 }, | ||
| 388 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 }, | ||
| 389 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, | ||
| 390 | |||
| 391 | // 2/2 - untested | ||
| 392 | { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 }, | ||
| 393 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 }, | ||
| 394 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, | ||
| 395 | |||
| 396 | // 3/2 | ||
| 397 | { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 8, 11, 12, 12, -1, -1 }, | ||
| 398 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 8, 11, 12, 12, -1, -1 }, | ||
| 399 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }, | ||
| 400 | }; | ||
| 401 | |||
| 402 | |||
| 333 | /** | 403 | /** |
| 334 | * Adjust the frame size to make the average bit rate match the target bit rate. | 404 | * Adjust the frame size to make the average bit rate match the target bit rate. |
| 335 | * This is only needed for 11025, 22050, and 44100 sample rates. | 405 | * This is only needed for 11025, 22050, and 44100 sample rates. |
| @@ -392,15 +462,297 @@ static void apply_mdct(AC3EncodeContext *s) · 56 unmodified lines | |||
| 392 | 462 | ||
| 393 | apply_window(&s->dsp, s->windowed_samples, input_samples, s->mdct.window, AC3_WINDOW_SIZE); | 463 | apply_window(&s->dsp, s->windowed_samples, input_samples, s->mdct.window, AC3_WINDOW_SIZE); |
| 394 | 464 | ||
| 395 | block->coeff_shift[ch] = normalize_samples(s); | 465 | block->coeff_shift[ch+1] = normalize_samples(s); |
| 396 | 466 | ||
| 397 | s->mdct.fft.mdct_calcw(&s->mdct.fft, block->mdct_coef[ch], | 467 | s->mdct.fft.mdct_calcw(&s->mdct.fft, block->mdct_coef[ch+1], |
| 398 | s->windowed_samples); | 468 | s->windowed_samples); |
| 399 | } | 469 | } |
| 400 | } | 470 | } |
| 401 | } | 471 | } |
| 402 | 472 | ||
| 403 | 473 | ||
| 474 | static void compute_coupling_strategy(AC3EncodeContext *s) | ||
| 475 | { | ||
| 476 | int blk, ch; | ||
| 477 | int got_cpl_snr; | ||
| 478 | |||
| 479 | /* set coupling use flags for each block/channel */ | ||
| 480 | /* TODO: turn coupling on/off and adjust start band based on bit usage */ | ||
| 481 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||
| 482 | AC3Block *block = &s->blocks[blk]; | ||
| 483 | for (ch = 1; ch <= s->fbw_channels; ch++) | ||
| 484 | block->channel_in_cpl[ch] = s->cpl_on; | ||
| 485 | } | ||
| 486 | |||
| 487 | /* enable coupling for each block if at least 2 channels have coupling | ||
| 488 | enabled for that block */ | ||
| 489 | got_cpl_snr = 0; | ||
| 490 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||
| 491 | AC3Block *block = &s->blocks[blk]; | ||
| 492 | block->num_cpl_channels = 0; | ||
| 493 | for (ch = 1; ch <= s->fbw_channels; ch++) | ||
| 494 | block->num_cpl_channels += block->channel_in_cpl[ch]; | ||
| 495 | block->cpl_in_use = block->num_cpl_channels > 1; | ||
| 496 | if (!block->cpl_in_use) { | ||
| 497 | block->num_cpl_channels = 0; | ||
| 498 | for (ch = 1; ch <= s->fbw_channels; ch++) | ||
| 499 | block->channel_in_cpl[ch] = 0; | ||
| 500 | } | ||
| 501 | |||
| 502 | block->new_cpl_strategy = !blk; | ||
| 503 | if (blk) { | ||
| 504 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 505 | if (block->channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) { | ||
| 506 | block->new_cpl_strategy = 1; | ||
| 507 | break; | ||
| 508 | } | ||
| 509 | } | ||
| 510 | } | ||
| 511 | block->new_cpl_leak = block->new_cpl_strategy; | ||
| 512 | |||
| 513 | if (!blk || (block->cpl_in_use && !got_cpl_snr)) { | ||
| 514 | block->new_snr_offsets = 1; | ||
| 515 | if (block->cpl_in_use) | ||
| 516 | got_cpl_snr = 1; | ||
| 517 | } else { | ||
| 518 | block->new_snr_offsets = 0; | ||
| 519 | } | ||
| 520 | } | ||
| 521 | |||
| 522 | /* set bandwidth for each channel */ | ||
| 523 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||
| 524 | AC3Block *block = &s->blocks[blk]; | ||
| 525 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 526 | if (block->channel_in_cpl[ch]) | ||
| 527 | block->end_freq[ch] = s->start_freq[CPL_CH]; | ||
| 528 | else | ||
| 529 | block->end_freq[ch] = s->bandwidth_code * 3 + 73; | ||
| 530 | } | ||
| 531 | } | ||
| 532 | } | ||
| 533 | |||
| 534 | |||
| 535 | /** | ||
| 536 | * Calculate a single coupling coordinate. | ||
| 537 | */ | ||
| 538 | static inline float calc_cpl_coord(float energy_ch, float energy_cpl) | ||
| 539 | { | ||
| 540 | float coord = 0.125; | ||
| 541 | if (energy_cpl > 0) | ||
| 542 | coord *= sqrtf(energy_ch / energy_cpl); | ||
| 543 | return coord; | ||
| 544 | } | ||
| 545 | |||
| 546 | |||
| 547 | /** | ||
| 548 | * Calculate coupling channel and coupling coordinates. | ||
| 549 | * TODO: Currently this is only used for the floating-point encoder. I was | ||
| 550 | * able to make it work for the fixed-point encoder, but quality was | ||
| 551 | * generally lower in most cases than not using coupling. If a more | ||
| 552 | * adaptive coupling strategy were to be implemented it might be useful | ||
| 553 | * at that time to use coupling for the fixed-point encoder as well. | ||
| 554 | */ | ||
| 555 | static void apply_channel_coupling(AC3EncodeContext *s) | ||
| 556 | { | ||
| 557 | #if CONFIG_AC3ENC_FLOAT | ||
| 558 | DECLARE_ALIGNED(16, float, cpl_coords) [AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16]; | ||
| 559 | DECLARE_ALIGNED(16, int32_t, fixed_cpl_coords)[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16]; | ||
| 560 | int blk, ch, bnd, i, j; | ||
| 561 | CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}}; | ||
| 562 | int num_cpl_coefs = s->num_cpl_subbands * 12; | ||
| 563 | |||
| 564 | /* calculate coupling channel from fbw channels */ | ||
| 565 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||
| 566 | AC3Block *block = &s->blocks[blk]; | ||
| 567 | CoefType *cpl_coef = &block->mdct_coef[CPL_CH][s->start_freq[CPL_CH]]; | ||
| 568 | if (!block->cpl_in_use) | ||
| 569 | continue; | ||
| 570 | memset(cpl_coef-1, 0, (num_cpl_coefs+4) * sizeof(*cpl_coef)); | ||
| 571 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 572 | CoefType *ch_coef = &block->mdct_coef[ch][s->start_freq[CPL_CH]]; | ||
| 573 | if (!block->channel_in_cpl[ch]) | ||
| 574 | continue; | ||
| 575 | for (i = 0; i < num_cpl_coefs; i++) | ||
| 576 | cpl_coef[i] += ch_coef[i]; | ||
| 577 | } | ||
| 578 | /* note: coupling start bin % 4 will always be 1 and num_cpl_coefs | ||
| 579 | will always be a multiple of 12, so we need to subtract 1 from | ||
| 580 | the start and add 4 to the length when using optimized | ||
| 581 | functions which require 16-byte alignment. */ | ||
| 582 | |||
| 583 | /* coefficients must be clipped to +/- 1.0 in order to be encoded */ | ||
| 584 | s->dsp.vector_clipf(cpl_coef-1, cpl_coef-1, -1.0f, 1.0f, num_cpl_coefs+4); | ||
| 585 | |||
| 586 | /* scale coupling coefficients from float to 24-bit fixed-point */ | ||
| 587 | s->ac3dsp.float_to_fixed24(&block->fixed_coef[CPL_CH][s->start_freq[CPL_CH]-1], | ||
| 588 | cpl_coef-1, num_cpl_coefs+4); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* calculate energy in each band in coupling channel and each fbw channel */ | ||
| 592 | /* TODO: possibly use SIMD to speed up energy calculation */ | ||
| 593 | bnd = 0; | ||
| 594 | i = s->start_freq[CPL_CH]; | ||
| 595 | while (i < s->cpl_end_freq) { | ||
| 596 | int band_size = s->cpl_band_sizes[bnd]; | ||
| 597 | for (ch = CPL_CH; ch <= s->fbw_channels; ch++) { | ||
| 598 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||
| 599 | AC3Block *block = &s->blocks[blk]; | ||
| 600 | if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch])) | ||
| 601 | continue; | ||
| 602 | for (j = 0; j < band_size; j++) { | ||
| 603 | CoefType v = block->mdct_coef[ch][i+j]; | ||
| 604 | MAC_COEF(energy[blk][ch][bnd], v, v); | ||
| 605 | } | ||
| 606 | } | ||
| 607 | } | ||
| 608 | i += band_size; | ||
| 609 | bnd++; | ||
| 610 | } | ||
| 611 | |||
| 612 | /* determine which blocks to send new coupling coordinates for */ | ||
| 613 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||
| 614 | AC3Block *block = &s->blocks[blk]; | ||
| 615 | AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL; | ||
| 616 | int new_coords = 0; | ||
| 617 | CoefSumType coord_diff[AC3_MAX_CHANNELS] = {0,}; | ||
| 618 | |||
| 619 | if (block->cpl_in_use) { | ||
| 620 | /* calculate coupling coordinates for all blocks and calculate the | ||
| 621 | average difference between coordinates in successive blocks */ | ||
| 622 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 623 | if (!block->channel_in_cpl[ch]) | ||
| 624 | continue; | ||
| 625 | |||
| 626 | for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | ||
| 627 | cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd], | ||
| 628 | energy[blk][CPL_CH][bnd]); | ||
| 629 | if (blk > 0 && block0->cpl_in_use && | ||
| 630 | block0->channel_in_cpl[ch]) { | ||
| 631 | coord_diff[ch] += fabs(cpl_coords[blk-1][ch][bnd] - | ||
| 632 | cpl_coords[blk ][ch][bnd]); | ||
| 633 | } | ||
| 634 | } | ||
| 635 | coord_diff[ch] /= s->num_cpl_bands; | ||
| 636 | } | ||
| 637 | |||
| 638 | /* send new coordinates if this is the first block, if previous | ||
| 639 | * block did not use coupling but this block does, the channels | ||
| 640 | * using coupling has changed from the previous block, or the | ||
| 641 | * coordinate difference from the last block for any channel is | ||
| 642 | * greater than a threshold value. */ | ||
| 643 | if (blk == 0) { | ||
| 644 | new_coords = 1; | ||
| 645 | } else if (!block0->cpl_in_use) { | ||
| 646 | new_coords = 1; | ||
| 647 | } else { | ||
| 648 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 649 | if (block->channel_in_cpl[ch] && !block0->channel_in_cpl[ch]) { | ||
| 650 | new_coords = 1; | ||
| 651 | break; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | if (!new_coords) { | ||
| 655 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 656 | if (block->channel_in_cpl[ch] && coord_diff[ch] > 0.04) { | ||
| 657 | new_coords = 1; | ||
| 658 | break; | ||
| 659 | } | ||
| 660 | } | ||
| 661 | } | ||
| 662 | } | ||
| 663 | } | ||
| 664 | block->new_cpl_coords = new_coords; | ||
| 665 | } | ||
| 666 | |||
| 667 | /* calculate final coupling coordinates, taking into account reusing of | ||
| 668 | coordinates in successive blocks */ | ||
| 669 | for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | ||
| 670 | blk = 0; | ||
| 671 | while (blk < AC3_MAX_BLOCKS) { | ||
| 672 | int blk1; | ||
| 673 | CoefSumType energy_cpl; | ||
| 674 | AC3Block *block = &s->blocks[blk]; | ||
| 675 | |||
| 676 | if (!block->cpl_in_use) { | ||
| 677 | blk++; | ||
| 678 | continue; | ||
| 679 | } | ||
| 680 | |||
| 681 | energy_cpl = energy[blk][CPL_CH][bnd]; | ||
| 682 | blk1 = blk+1; | ||
| 683 | while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) { | ||
| 684 | if (s->blocks[blk1].cpl_in_use) | ||
| 685 | energy_cpl += energy[blk1][CPL_CH][bnd]; | ||
| 686 | blk1++; | ||
| 687 | } | ||
| 688 | |||
| 689 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 690 | CoefType energy_ch; | ||
| 691 | if (!block->channel_in_cpl[ch]) | ||
| 692 | continue; | ||
| 693 | energy_ch = energy[blk][ch][bnd]; | ||
| 694 | blk1 = blk+1; | ||
| 695 | while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) { | ||
| 696 | if (s->blocks[blk1].cpl_in_use) | ||
| 697 | energy_ch += energy[blk1][ch][bnd]; | ||
| 698 | blk1++; | ||
| 699 | } | ||
| 700 | cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl); | ||
| 701 | } | ||
| 702 | blk = blk1; | ||
| 703 | } | ||
| 704 | } | ||
| 705 | |||
| 706 | /* calculate exponents/mantissas for coupling coordinates */ | ||
| 707 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||
| 708 | AC3Block *block = &s->blocks[blk]; | ||
| 709 | if (!block->cpl_in_use || !block->new_cpl_coords) | ||
| 710 | continue; | ||
| 711 | |||
| 712 | s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1], | ||
| 713 | cpl_coords[blk][1], | ||
| 714 | s->fbw_channels * 16); | ||
| 715 | s->ac3dsp.extract_exponents(block->cpl_coord_exp[1], | ||
| 716 | fixed_cpl_coords[blk][1], | ||
| 717 | s->fbw_channels * 16); | ||
| 718 | |||
| 719 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 720 | int bnd, min_exp, max_exp, master_exp; | ||
| 721 | |||
| 722 | /* determine master exponent */ | ||
| 723 | min_exp = max_exp = block->cpl_coord_exp[ch][0]; | ||
| 724 | for (bnd = 1; bnd < s->num_cpl_bands; bnd++) { | ||
| 725 | int exp = block->cpl_coord_exp[ch][bnd]; | ||
| 726 | min_exp = FFMIN(exp, min_exp); | ||
| 727 | max_exp = FFMAX(exp, max_exp); | ||
| 728 | } | ||
| 729 | master_exp = ((max_exp - 15) + 2) / 3; | ||
| 730 | master_exp = FFMAX(master_exp, 0); | ||
| 731 | while (min_exp < master_exp * 3) | ||
| 732 | master_exp--; | ||
| 733 | for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | ||
| 734 | block->cpl_coord_exp[ch][bnd] = av_clip(block->cpl_coord_exp[ch][bnd] - | ||
| 735 | master_exp * 3, 0, 15); | ||
| 736 | } | ||
| 737 | block->cpl_master_exp[ch] = master_exp; | ||
| 738 | |||
| 739 | /* quantize mantissas */ | ||
| 740 | for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | ||
| 741 | int cpl_exp = block->cpl_coord_exp[ch][bnd]; | ||
| 742 | int cpl_mant = (fixed_cpl_coords[blk][ch][bnd] << (5 + cpl_exp + master_exp * 3)) >> 24; | ||
| 743 | if (cpl_exp == 15) | ||
| 744 | cpl_mant >>= 1; | ||
| 745 | else | ||
| 746 | cpl_mant -= 16; | ||
| 747 | |||
| 748 | block->cpl_coord_mant[ch][bnd] = cpl_mant; | ||
| 749 | } | ||
| 750 | } | ||
| 751 | } | ||
| 752 | #endif /* CONFIG_AC3ENC_FLOAT */ | ||
| 753 | } | ||
| 754 | |||
| 755 | |||
| 404 | /** | 756 | /** |
| 405 | * Determine rematrixing flags for each block and band. | 757 | * Determine rematrixing flags for each block and band. |
| 406 | */ | 758 | */ |
| @@ -413,23 +765,32 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) · 6 unmodified lines | |||
| 413 | if (s->channel_mode != AC3_CHMODE_STEREO) | 765 | if (s->channel_mode != AC3_CHMODE_STEREO) |
| 414 | return; | 766 | return; |
| 415 | 767 | ||
| 416 | s->num_rematrixing_bands = 4; | ||
| 417 | |||
| 418 | nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); | ||
| 419 | |||
| 420 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 768 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 421 | block = &s->blocks[blk]; | 769 | block = &s->blocks[blk]; |
| 422 | block->new_rematrixing_strategy = !blk; | 770 | block->new_rematrixing_strategy = !blk; |
| 423 | if (!s->rematrixing_enabled) | 771 | |
| 772 | if (!s->rematrixing_enabled) { | ||
| 773 | block0 = block; | ||
| 424 | continue; | 774 | continue; |
| 425 | for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) { | 775 | } |
| 776 | |||
| 777 | block->num_rematrixing_bands = 4; | ||
| 778 | if (block->cpl_in_use) { | ||
| 779 | block->num_rematrixing_bands -= (s->start_freq[CPL_CH] <= 61); | ||
| 780 | block->num_rematrixing_bands -= (s->start_freq[CPL_CH] == 37); | ||
| 781 | if (blk && block->num_rematrixing_bands != block0->num_rematrixing_bands) | ||
| 782 | block->new_rematrixing_strategy = 1; | ||
| 783 | } | ||
| 784 | nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]); | ||
| 785 | |||
| 786 | for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) { | ||
| 426 | /* calculate calculate sum of squared coeffs for one band in one block */ | 787 | /* calculate calculate sum of squared coeffs for one band in one block */ |
| 427 | int start = ff_ac3_rematrix_band_tab[bnd]; | 788 | int start = ff_ac3_rematrix_band_tab[bnd]; |
| 428 | int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); | 789 | int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); |
| 429 | CoefSumType sum[4] = {0,}; | 790 | CoefSumType sum[4] = {0,}; |
| 430 | for (i = start; i < end; i++) { | 791 | for (i = start; i < end; i++) { |
| 431 | CoefType lt = block->mdct_coef[0][i]; | 792 | CoefType lt = block->mdct_coef[1][i]; |
| 432 | CoefType rt = block->mdct_coef[1][i]; | 793 | CoefType rt = block->mdct_coef[2][i]; |
| 433 | CoefType md = lt + rt; | 794 | CoefType md = lt + rt; |
| 434 | CoefType sd = lt - rt; | 795 | CoefType sd = lt - rt; |
| 435 | MAC_COEF(sum[0], lt, lt); | 796 | MAC_COEF(sum[0], lt, lt); |
| @@ -468,21 +829,20 @@ static void apply_rematrixing(AC3EncodeContext *s) · 32 unmodified lines | |||
| 468 | if (!s->rematrixing_enabled) | 829 | if (!s->rematrixing_enabled) |
| 469 | return; | 830 | return; |
| 470 | 831 | ||
| 471 | nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); | ||
| 472 | |||
| 473 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 832 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 474 | AC3Block *block = &s->blocks[blk]; | 833 | AC3Block *block = &s->blocks[blk]; |
| 475 | if (block->new_rematrixing_strategy) | 834 | if (block->new_rematrixing_strategy) |
| 476 | flags = block->rematrixing_flags; | 835 | flags = block->rematrixing_flags; |
| 477 | for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) { | 836 | nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]); |
| 837 | for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) { | ||
| 478 | if (flags[bnd]) { | 838 | if (flags[bnd]) { |
| 479 | start = ff_ac3_rematrix_band_tab[bnd]; | 839 | start = ff_ac3_rematrix_band_tab[bnd]; |
| 480 | end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); | 840 | end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); |
| 481 | for (i = start; i < end; i++) { | 841 | for (i = start; i < end; i++) { |
| 482 | int32_t lt = block->fixed_coef[0][i]; | 842 | int32_t lt = block->fixed_coef[1][i]; |
| 483 | int32_t rt = block->fixed_coef[1][i]; | 843 | int32_t rt = block->fixed_coef[2][i]; |
| 484 | block->fixed_coef[0][i] = (lt + rt) >> 1; | 844 | block->fixed_coef[1][i] = (lt + rt) >> 1; |
| 485 | block->fixed_coef[1][i] = (lt - rt) >> 1; | 845 | block->fixed_coef[2][i] = (lt - rt) >> 1; |
| 486 | } | 846 | } |
| 487 | } | 847 | } |
| 488 | } | 848 | } |
| @@ -499,12 +859,13 @@ static av_cold void exponent_init(AC3EncodeContext *s) · 10 unmodified lines | |||
| 499 | 859 | ||
| 500 | for (expstr = EXP_D15-1; expstr <= EXP_D45-1; expstr++) { | 860 | for (expstr = EXP_D15-1; expstr <= EXP_D45-1; expstr++) { |
| 501 | grpsize = 3 << expstr; | 861 | grpsize = 3 << expstr; |
| 502 | for (i = 73; i < 256; i++) { | 862 | for (i = 12; i < 256; i++) { |
| 503 | exponent_group_tab[expstr][i] = (i + grpsize - 4) / grpsize; | 863 | exponent_group_tab[0][expstr][i] = (i + grpsize - 4) / grpsize; |
| 864 | exponent_group_tab[1][expstr][i] = (i ) / grpsize; | ||
| 504 | } | 865 | } |
| 505 | } | 866 | } |
| 506 | /* LFE */ | 867 | /* LFE */ |
| 507 | exponent_group_tab[0][7] = 2; | 868 | exponent_group_tab[0][0][7] = 2; |
| 508 | } | 869 | } |
| 509 | 870 | ||
| 510 | 871 | ||
| @@ -517,7 +878,7 @@ static void extract_exponents(AC3EncodeContext *s) · 6 unmodified lines | |||
| 517 | { | 878 | { |
| 518 | int blk, ch; | 879 | int blk, ch; |
| 519 | 880 | ||
| 520 | for (ch = 0; ch < s->channels; ch++) { | 881 | for (ch = !s->cpl_on; ch <= s->channels; ch++) { |
| 521 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 882 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 522 | AC3Block *block = &s->blocks[blk]; | 883 | AC3Block *block = &s->blocks[blk]; |
| 523 | s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch], | 884 | s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch], |
| @@ -542,7 +903,7 @@ static void compute_exp_strategy(AC3EncodeContext *s) · 18 unmodified lines | |||
| 542 | { | 903 | { |
| 543 | int ch, blk, blk1; | 904 | int ch, blk, blk1; |
| 544 | 905 | ||
| 545 | for (ch = 0; ch < s->fbw_channels; ch++) { | 906 | for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) { |
| 546 | uint8_t *exp_strategy = s->exp_strategy[ch]; | 907 | uint8_t *exp_strategy = s->exp_strategy[ch]; |
| 547 | uint8_t *exp = s->blocks[0].exp[ch]; | 908 | uint8_t *exp = s->blocks[0].exp[ch]; |
| 548 | int exp_diff; | 909 | int exp_diff; |
| @@ -551,13 +912,18 @@ static void compute_exp_strategy(AC3EncodeContext *s) · 2 unmodified lines | |||
| 551 | reused in the next frame */ | 912 | reused in the next frame */ |
| 552 | exp_strategy[0] = EXP_NEW; | 913 | exp_strategy[0] = EXP_NEW; |
| 553 | exp += AC3_MAX_COEFS; | 914 | exp += AC3_MAX_COEFS; |
| 554 | for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { | 915 | for (blk = 1; blk < AC3_MAX_BLOCKS; blk++, exp += AC3_MAX_COEFS) { |
| 916 | if ((ch == CPL_CH && (!s->blocks[blk].cpl_in_use || !s->blocks[blk-1].cpl_in_use)) || | ||
| 917 | (ch > CPL_CH && (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]))) { | ||
| 918 | exp_strategy[blk] = EXP_NEW; | ||
| 919 | continue; | ||
| 920 | } | ||
| 555 | exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16); | 921 | exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16); |
| 556 | if (exp_diff > EXP_DIFF_THRESHOLD) | 922 | exp_strategy[blk] = EXP_REUSE; |
| 923 | if (ch == CPL_CH && exp_diff > (EXP_DIFF_THRESHOLD * (s->blocks[blk].end_freq[ch] - s->start_freq[ch]) / AC3_MAX_COEFS)) | ||
| 924 | exp_strategy[blk] = EXP_NEW; | ||
| 925 | else if (ch > CPL_CH && exp_diff > EXP_DIFF_THRESHOLD) | ||
| 557 | exp_strategy[blk] = EXP_NEW; | 926 | exp_strategy[blk] = EXP_NEW; |
| 558 | else | ||
| 559 | exp_strategy[blk] = EXP_REUSE; | ||
| 560 | exp += AC3_MAX_COEFS; | ||
| 561 | } | 927 | } |
| 562 | 928 | ||
| 563 | /* now select the encoding strategy type : if exponents are often | 929 | /* now select the encoding strategy type : if exponents are often |
| @@ -588,25 +954,26 @@ static void compute_exp_strategy(AC3EncodeContext *s) · 24 unmodified lines | |||
| 588 | /** | 954 | /** |
| 589 | * Update the exponents so that they are the ones the decoder will decode. | 955 | * Update the exponents so that they are the ones the decoder will decode. |
| 590 | */ | 956 | */ |
| 591 | static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy) | 957 | static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy, |
| 958 | int cpl) | ||
| 592 | { | 959 | { |
| 593 | int nb_groups, i, k; | 960 | int nb_groups, i, k; |
| 594 | 961 | ||
| 595 | nb_groups = exponent_group_tab[exp_strategy-1][nb_exps] * 3; | 962 | nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_exps] * 3; |
| 596 | 963 | ||
| 597 | /* for each group, compute the minimum exponent */ | 964 | /* for each group, compute the minimum exponent */ |
| 598 | switch(exp_strategy) { | 965 | switch(exp_strategy) { |
| 599 | case EXP_D25: | 966 | case EXP_D25: |
| 600 | for (i = 1, k = 1; i <= nb_groups; i++) { | 967 | for (i = 1, k = 1-cpl; i <= nb_groups; i++) { |
| 601 | uint8_t exp_min = exp[k]; | 968 | uint8_t exp_min = exp[k]; |
| 602 | if (exp[k+1] < exp_min) | 969 | if (exp[k+1] < exp_min) |
| 603 | exp_min = exp[k+1]; | 970 | exp_min = exp[k+1]; |
| 604 | exp[i] = exp_min; | 971 | exp[i-cpl] = exp_min; |
| 605 | k += 2; | 972 | k += 2; |
| 606 | } | 973 | } |
| 607 | break; | 974 | break; |
| 608 | case EXP_D45: | 975 | case EXP_D45: |
| 609 | for (i = 1, k = 1; i <= nb_groups; i++) { | 976 | for (i = 1, k = 1-cpl; i <= nb_groups; i++) { |
| 610 | uint8_t exp_min = exp[k]; | 977 | uint8_t exp_min = exp[k]; |
| 611 | if (exp[k+1] < exp_min) | 978 | if (exp[k+1] < exp_min) |
| 612 | exp_min = exp[k+1]; | 979 | exp_min = exp[k+1]; |
| @@ -614,14 +981,14 @@ static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy) · 1 unmodified line | |||
| 614 | exp_min = exp[k+2]; | 981 | exp_min = exp[k+2]; |
| 615 | if (exp[k+3] < exp_min) | 982 | if (exp[k+3] < exp_min) |
| 616 | exp_min = exp[k+3]; | 983 | exp_min = exp[k+3]; |
| 617 | exp[i] = exp_min; | 984 | exp[i-cpl] = exp_min; |
| 618 | k += 4; | 985 | k += 4; |
| 619 | } | 986 | } |
| 620 | break; | 987 | break; |
| 621 | } | 988 | } |
| 622 | 989 | ||
| 623 | /* constraint for DC exponent */ | 990 | /* constraint for DC exponent */ |
| 624 | if (exp[0] > 15) | 991 | if (!cpl && exp[0] > 15) |
| 625 | exp[0] = 15; | 992 | exp[0] = 15; |
| 626 | 993 | ||
| 627 | /* decrease the delta between each groups to within 2 so that they can be | 994 | /* decrease the delta between each groups to within 2 so that they can be |
| @@ -632,18 +999,21 @@ static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy) · 4 unmodified lines | |||
| 632 | while (--i >= 0) | 999 | while (--i >= 0) |
| 633 | exp[i] = FFMIN(exp[i], exp[i+1] + 2); | 1000 | exp[i] = FFMIN(exp[i], exp[i+1] + 2); |
| 634 | 1001 | ||
| 1002 | if (cpl) | ||
| 1003 | exp[-1] = exp[0] & ~1; | ||
| 1004 | |||
| 635 | /* now we have the exponent values the decoder will see */ | 1005 | /* now we have the exponent values the decoder will see */ |
| 636 | switch (exp_strategy) { | 1006 | switch (exp_strategy) { |
| 637 | case EXP_D25: | 1007 | case EXP_D25: |
| 638 | for (i = nb_groups, k = nb_groups * 2; i > 0; i--) { | 1008 | for (i = nb_groups, k = (nb_groups * 2)-cpl; i > 0; i--) { |
| 639 | uint8_t exp1 = exp[i]; | 1009 | uint8_t exp1 = exp[i-cpl]; |
| 640 | exp[k--] = exp1; | 1010 | exp[k--] = exp1; |
| 641 | exp[k--] = exp1; | 1011 | exp[k--] = exp1; |
| 642 | } | 1012 | } |
| 643 | break; | 1013 | break; |
| 644 | case EXP_D45: | 1014 | case EXP_D45: |
| 645 | for (i = nb_groups, k = nb_groups * 4; i > 0; i--) { | 1015 | for (i = nb_groups, k = (nb_groups * 4)-cpl; i > 0; i--) { |
| 646 | exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i]; | 1016 | exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i-cpl]; |
| 647 | k -= 4; | 1017 | k -= 4; |
| 648 | } | 1018 | } |
| 649 | break; | 1019 | break; |
| @@ -659,32 +1029,40 @@ static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy) · 9 unmodified lines | |||
| 659 | */ | 1029 | */ |
| 660 | static void encode_exponents(AC3EncodeContext *s) | 1030 | static void encode_exponents(AC3EncodeContext *s) |
| 661 | { | 1031 | { |
| 662 | int blk, blk1, ch; | 1032 | int blk, blk1, ch, cpl; |
| 663 | uint8_t *exp, *exp_strategy; | 1033 | uint8_t *exp, *exp_strategy; |
| 664 | int nb_coefs, num_reuse_blocks; | 1034 | int nb_coefs, num_reuse_blocks; |
| 665 | 1035 | ||
| 666 | for (ch = 0; ch < s->channels; ch++) { | 1036 | for (ch = !s->cpl_on; ch <= s->channels; ch++) { |
| 667 | exp = s->blocks[0].exp[ch]; | 1037 | exp = s->blocks[0].exp[ch] + s->start_freq[ch]; |
| 668 | exp_strategy = s->exp_strategy[ch]; | 1038 | exp_strategy = s->exp_strategy[ch]; |
| 669 | nb_coefs = s->nb_coefs[ch]; | ||
| 670 | 1039 | ||
| 1040 | cpl = (ch == CPL_CH); | ||
| 671 | blk = 0; | 1041 | blk = 0; |
| 672 | while (blk < AC3_MAX_BLOCKS) { | 1042 | while (blk < AC3_MAX_BLOCKS) { |
| 1043 | AC3Block *block = &s->blocks[blk]; | ||
| 1044 | if (cpl && !block->cpl_in_use) { | ||
| 1045 | exp += AC3_MAX_COEFS; | ||
| 1046 | blk++; | ||
| 1047 | continue; | ||
| 1048 | } | ||
| 1049 | nb_coefs = block->end_freq[ch] - s->start_freq[ch]; | ||
| 673 | blk1 = blk + 1; | 1050 | blk1 = blk + 1; |
| 674 | 1051 | ||
| 675 | /* count the number of EXP_REUSE blocks after the current block | 1052 | /* count the number of EXP_REUSE blocks after the current block |
| 676 | and set exponent reference block pointers */ | 1053 | and set exponent reference block pointers */ |
| 677 | s->blocks[blk].exp_ref_block[ch] = &s->blocks[blk]; | 1054 | block->exp_ref_block[ch] = block; |
| 678 | while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) { | 1055 | while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) { |
| 679 | s->blocks[blk1].exp_ref_block[ch] = &s->blocks[blk]; | 1056 | s->blocks[blk1].exp_ref_block[ch] = block; |
| 680 | blk1++; | 1057 | blk1++; |
| 681 | } | 1058 | } |
| 682 | num_reuse_blocks = blk1 - blk - 1; | 1059 | num_reuse_blocks = blk1 - blk - 1; |
| 683 | 1060 | ||
| 684 | /* for the EXP_REUSE case we select the min of the exponents */ | 1061 | /* for the EXP_REUSE case we select the min of the exponents */ |
| 685 | s->ac3dsp.ac3_exponent_min(exp, num_reuse_blocks, nb_coefs); | 1062 | s->ac3dsp.ac3_exponent_min(exp-s->start_freq[ch], num_reuse_blocks, |
| 1063 | AC3_MAX_COEFS); | ||
| 686 | 1064 | ||
| 687 | encode_exponents_blk_ch(exp, nb_coefs, exp_strategy[blk]); | 1065 | encode_exponents_blk_ch(exp, nb_coefs, exp_strategy[blk], cpl); |
| 688 | 1066 | ||
| 689 | exp += AC3_MAX_COEFS * (num_reuse_blocks + 1); | 1067 | exp += AC3_MAX_COEFS * (num_reuse_blocks + 1); |
| 690 | blk = blk1; | 1068 | blk = blk1; |
| @@ -700,7 +1078,7 @@ static void encode_exponents(AC3EncodeContext *s) · 9 unmodified lines | |||
| 700 | */ | 1078 | */ |
| 701 | static void group_exponents(AC3EncodeContext *s) | 1079 | static void group_exponents(AC3EncodeContext *s) |
| 702 | { | 1080 | { |
| 703 | int blk, ch, i; | 1081 | int blk, ch, i, cpl; |
| 704 | int group_size, nb_groups, bit_count; | 1082 | int group_size, nb_groups, bit_count; |
| 705 | uint8_t *p; | 1083 | uint8_t *p; |
| 706 | int delta0, delta1, delta2; | 1084 | int delta0, delta1, delta2; |
| @@ -709,14 +1087,15 @@ static void group_exponents(AC3EncodeContext *s) · 2 unmodified lines | |||
| 709 | bit_count = 0; | 1087 | bit_count = 0; |
| 710 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 1088 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 711 | AC3Block *block = &s->blocks[blk]; | 1089 | AC3Block *block = &s->blocks[blk]; |
| 712 | for (ch = 0; ch < s->channels; ch++) { | 1090 | for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { |
| 713 | int exp_strategy = s->exp_strategy[ch][blk]; | 1091 | int exp_strategy = s->exp_strategy[ch][blk]; |
| 714 | if (exp_strategy == EXP_REUSE) | 1092 | if (exp_strategy == EXP_REUSE) |
| 715 | continue; | 1093 | continue; |
| 1094 | cpl = (ch == CPL_CH); | ||
| 716 | group_size = exp_strategy + (exp_strategy == EXP_D45); | 1095 | group_size = exp_strategy + (exp_strategy == EXP_D45); |
| 717 | nb_groups = exponent_group_tab[exp_strategy-1][s->nb_coefs[ch]]; | 1096 | nb_groups = exponent_group_tab[cpl][exp_strategy-1][block->end_freq[ch]-s->start_freq[ch]]; |
| 718 | bit_count += 4 + (nb_groups * 7); | 1097 | bit_count += 4 + (nb_groups * 7); |
| 719 | p = block->exp[ch]; | 1098 | p = block->exp[ch] + s->start_freq[ch] - cpl; |
| 720 | 1099 | ||
| 721 | /* DC exponent */ | 1100 | /* DC exponent */ |
| 722 | exp1 = *p++; | 1101 | exp1 = *p++; |
| @@ -783,9 +1162,7 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 60 unmodified lines | |||
| 783 | 1162 | ||
| 784 | /* assumptions: | 1163 | /* assumptions: |
| 785 | * no dynamic range codes | 1164 | * no dynamic range codes |
| 786 | * no channel coupling | ||
| 787 | * bit allocation parameters do not change between blocks | 1165 | * bit allocation parameters do not change between blocks |
| 788 | * SNR offsets do not change between blocks | ||
| 789 | * no delta bit allocation | 1166 | * no delta bit allocation |
| 790 | * no skipped data | 1167 | * no skipped data |
| 791 | * no auxilliary data | 1168 | * no auxilliary data |
| @@ -806,11 +1183,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 14 unmodified lines | |||
| 806 | /* dynamic range */ | 1183 | /* dynamic range */ |
| 807 | frame_bits++; | 1184 | frame_bits++; |
| 808 | 1185 | ||
| 809 | /* coupling strategy */ | ||
| 810 | frame_bits++; | ||
| 811 | if (!blk) | ||
| 812 | frame_bits++; | ||
| 813 | |||
| 814 | /* exponent strategy */ | 1186 | /* exponent strategy */ |
| 815 | frame_bits += 2 * s->fbw_channels; | 1187 | frame_bits += 2 * s->fbw_channels; |
| 816 | if (s->lfe_on) | 1188 | if (s->lfe_on) |
| @@ -821,11 +1193,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 4 unmodified lines | |||
| 821 | if (!blk) | 1193 | if (!blk) |
| 822 | frame_bits += 2 + 2 + 2 + 2 + 3; | 1194 | frame_bits += 2 + 2 + 2 + 2 + 3; |
| 823 | 1195 | ||
| 824 | /* snr offsets and fast gain codes */ | ||
| 825 | frame_bits++; | ||
| 826 | if (!blk) | ||
| 827 | frame_bits += 6 + s->channels * (4 + 3); | ||
| 828 | |||
| 829 | /* delta bit allocation */ | 1196 | /* delta bit allocation */ |
| 830 | frame_bits++; | 1197 | frame_bits++; |
| 831 | 1198 | ||
| @@ -857,7 +1224,7 @@ static void bit_alloc_init(AC3EncodeContext *s) · 25 unmodified lines | |||
| 857 | s->slow_gain_code = 1; | 1224 | s->slow_gain_code = 1; |
| 858 | s->db_per_bit_code = 3; | 1225 | s->db_per_bit_code = 3; |
| 859 | s->floor_code = 7; | 1226 | s->floor_code = 7; |
| 860 | for (ch = 0; ch < s->channels; ch++) | 1227 | for (ch = 0; ch <= s->channels; ch++) |
| 861 | s->fast_gain_code[ch] = 4; | 1228 | s->fast_gain_code[ch] = 4; |
| 862 | 1229 | ||
| 863 | /* initial snr offset */ | 1230 | /* initial snr offset */ |
| @@ -871,6 +1238,8 @@ static void bit_alloc_init(AC3EncodeContext *s) · 7 unmodified lines | |||
| 871 | s->bit_alloc.slow_gain = ff_ac3_slow_gain_tab[s->slow_gain_code]; | 1238 | s->bit_alloc.slow_gain = ff_ac3_slow_gain_tab[s->slow_gain_code]; |
| 872 | s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code]; | 1239 | s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code]; |
| 873 | s->bit_alloc.floor = ff_ac3_floor_tab[s->floor_code]; | 1240 | s->bit_alloc.floor = ff_ac3_floor_tab[s->floor_code]; |
| 1241 | s->bit_alloc.cpl_fast_leak = 0; | ||
| 1242 | s->bit_alloc.cpl_slow_leak = 0; | ||
| 874 | 1243 | ||
| 875 | count_frame_bits_fixed(s); | 1244 | count_frame_bits_fixed(s); |
| 876 | } | 1245 | } |
| @@ -899,17 +1268,64 @@ static void count_frame_bits(AC3EncodeContext *s) · 22 unmodified lines | |||
| 899 | 1268 | ||
| 900 | /* audio blocks */ | 1269 | /* audio blocks */ |
| 901 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 1270 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 1271 | AC3Block *block = &s->blocks[blk]; | ||
| 1272 | |||
| 1273 | /* coupling strategy */ | ||
| 1274 | frame_bits++; | ||
| 1275 | if (block->new_cpl_strategy) { | ||
| 1276 | frame_bits++; | ||
| 1277 | if (block->cpl_in_use) { | ||
| 1278 | frame_bits += s->fbw_channels; | ||
| 1279 | if (s->channel_mode == AC3_CHMODE_STEREO) | ||
| 1280 | frame_bits++; | ||
| 1281 | frame_bits += 4 + 4; | ||
| 1282 | frame_bits += s->num_cpl_subbands - 1; | ||
| 1283 | } | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | /* coupling coordinates */ | ||
| 1287 | if (block->cpl_in_use) { | ||
| 1288 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 1289 | if (block->channel_in_cpl[ch]) { | ||
| 1290 | frame_bits++; | ||
| 1291 | if (block->new_cpl_coords) { | ||
| 1292 | frame_bits += 2; | ||
| 1293 | frame_bits += (4 + 4) * s->num_cpl_bands; | ||
| 1294 | } | ||
| 1295 | } | ||
| 1296 | } | ||
| 1297 | } | ||
| 1298 | |||
| 902 | /* stereo rematrixing */ | 1299 | /* stereo rematrixing */ |
| 903 | if (s->channel_mode == AC3_CHMODE_STEREO) { | 1300 | if (s->channel_mode == AC3_CHMODE_STEREO) { |
| 904 | frame_bits++; | 1301 | frame_bits++; |
| 905 | if (s->blocks[blk].new_rematrixing_strategy) | 1302 | if (s->blocks[blk].new_rematrixing_strategy) |
| 906 | frame_bits += s->num_rematrixing_bands; | 1303 | frame_bits += block->num_rematrixing_bands; |
| 907 | } | 1304 | } |
| 908 | 1305 | ||
| 909 | /* bandwidth codes & gain range */ | 1306 | /* bandwidth codes & gain range */ |
| 910 | for (ch = 0; ch < s->fbw_channels; ch++) { | 1307 | for (ch = 1; ch <= s->fbw_channels; ch++) { |
| 911 | if (s->exp_strategy[ch][blk] != EXP_REUSE) | 1308 | if (s->exp_strategy[ch][blk] != EXP_REUSE) { |
| 912 | frame_bits += 6 + 2; | 1309 | if (!block->channel_in_cpl[ch]) |
| 1310 | frame_bits += 6; | ||
| 1311 | frame_bits += 2; | ||
| 1312 | } | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | /* coupling exponent strategy */ | ||
| 1316 | if (block->cpl_in_use) | ||
| 1317 | frame_bits += 2; | ||
| 1318 | |||
| 1319 | /* snr offsets and fast gain codes */ | ||
| 1320 | frame_bits++; | ||
| 1321 | if (block->new_snr_offsets) | ||
| 1322 | frame_bits += 6 + (s->channels + block->cpl_in_use) * (4 + 3); | ||
| 1323 | |||
| 1324 | /* coupling leak info */ | ||
| 1325 | if (block->cpl_in_use) { | ||
| 1326 | frame_bits++; | ||
| 1327 | if (block->new_cpl_leak) | ||
| 1328 | frame_bits += 3 + 3; | ||
| 913 | } | 1329 | } |
| 914 | } | 1330 | } |
| 915 | 1331 | ||
| @@ -943,16 +1359,16 @@ static void bit_alloc_masking(AC3EncodeContext *s) · 27 unmodified lines | |||
| 943 | 1359 | ||
| 944 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 1360 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 945 | AC3Block *block = &s->blocks[blk]; | 1361 | AC3Block *block = &s->blocks[blk]; |
| 946 | for (ch = 0; ch < s->channels; ch++) { | 1362 | for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { |
| 947 | /* We only need psd and mask for calculating bap. | 1363 | /* We only need psd and mask for calculating bap. |
| 948 | Since we currently do not calculate bap when exponent | 1364 | Since we currently do not calculate bap when exponent |
| 949 | strategy is EXP_REUSE we do not need to calculate psd or mask. */ | 1365 | strategy is EXP_REUSE we do not need to calculate psd or mask. */ |
| 950 | if (s->exp_strategy[ch][blk] != EXP_REUSE) { | 1366 | if (s->exp_strategy[ch][blk] != EXP_REUSE) { |
| 951 | ff_ac3_bit_alloc_calc_psd(block->exp[ch], 0, | 1367 | ff_ac3_bit_alloc_calc_psd(block->exp[ch], s->start_freq[ch], |
| 952 | s->nb_coefs[ch], | 1368 | block->end_freq[ch], block->psd[ch], |
| 953 | block->psd[ch], block->band_psd[ch]); | 1369 | block->band_psd[ch]); |
| 954 | ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, block->band_psd[ch], | 1370 | ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, block->band_psd[ch], |
| 955 | 0, s->nb_coefs[ch], | 1371 | s->start_freq[ch], block->end_freq[ch], |
| 956 | ff_ac3_fast_gain_tab[s->fast_gain_code[ch]], | 1372 | ff_ac3_fast_gain_tab[s->fast_gain_code[ch]], |
| 957 | ch == s->lfe_channel, | 1373 | ch == s->lfe_channel, |
| 958 | DBA_NONE, 0, NULL, NULL, NULL, | 1374 | DBA_NONE, 0, NULL, NULL, NULL, |
| @@ -970,11 +1386,12 @@ static void bit_alloc_masking(AC3EncodeContext *s) · 11 unmodified lines | |||
| 970 | static void reset_block_bap(AC3EncodeContext *s) | 1386 | static void reset_block_bap(AC3EncodeContext *s) |
| 971 | { | 1387 | { |
| 972 | int blk, ch; | 1388 | int blk, ch; |
| 1389 | int channels = s->channels + 1; | ||
| 973 | if (s->blocks[0].bap[0] == s->bap_buffer) | 1390 | if (s->blocks[0].bap[0] == s->bap_buffer) |
| 974 | return; | 1391 | return; |
| 975 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 1392 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 976 | for (ch = 0; ch < s->channels; ch++) { | 1393 | for (ch = 0; ch < channels; ch++) { |
| 977 | s->blocks[blk].bap[ch] = &s->bap_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)]; | 1394 | s->blocks[blk].bap[ch] = &s->bap_buffer[AC3_MAX_COEFS * (blk * channels + ch)]; |
| 978 | } | 1395 | } |
| 979 | } | 1396 | } |
| 980 | } | 1397 | } |
| @@ -1000,28 +1417,37 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset) · 19 unmodified lines | |||
| 1000 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 1417 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 1001 | AC3Block *block = &s->blocks[blk]; | 1418 | AC3Block *block = &s->blocks[blk]; |
| 1002 | AC3Block *ref_block; | 1419 | AC3Block *ref_block; |
| 1420 | int av_uninit(ch0); | ||
| 1421 | int got_cpl = !block->cpl_in_use; | ||
| 1003 | // initialize grouped mantissa counts. these are set so that they are | 1422 | // initialize grouped mantissa counts. these are set so that they are |
| 1004 | // padded to the next whole group size when bits are counted in | 1423 | // padded to the next whole group size when bits are counted in |
| 1005 | // compute_mantissa_size_final | 1424 | // compute_mantissa_size_final |
| 1006 | mant_cnt[0] = mant_cnt[3] = 0; | 1425 | mant_cnt[0] = mant_cnt[3] = 0; |
| 1007 | mant_cnt[1] = mant_cnt[2] = 2; | 1426 | mant_cnt[1] = mant_cnt[2] = 2; |
| 1008 | mant_cnt[4] = 1; | 1427 | mant_cnt[4] = 1; |
| 1009 | for (ch = 0; ch < s->channels; ch++) { | 1428 | for (ch = 1; ch <= s->channels; ch++) { |
| 1429 | if (!got_cpl && ch > 1 && block->channel_in_cpl[ch-1]) { | ||
| 1430 | ch0 = ch - 1; | ||
| 1431 | ch = CPL_CH; | ||
| 1432 | got_cpl = 1; | ||
| 1433 | } | ||
| 1434 | |||
| 1010 | /* Currently the only bit allocation parameters which vary across | 1435 | /* Currently the only bit allocation parameters which vary across |
| 1011 | blocks within a frame are the exponent values. We can take | 1436 | blocks within a frame are the exponent values. We can take |
| 1012 | advantage of that by reusing the bit allocation pointers | 1437 | advantage of that by reusing the bit allocation pointers |
| 1013 | whenever we reuse exponents. */ | 1438 | whenever we reuse exponents. */ |
| 1014 | ref_block = block->exp_ref_block[ch]; | 1439 | ref_block = block->exp_ref_block[ch]; |
| 1015 | if (s->exp_strategy[ch][blk] != EXP_REUSE) { | 1440 | if (s->exp_strategy[ch][blk] != EXP_REUSE) { |
| 1016 | s->ac3dsp.bit_alloc_calc_bap(ref_block->mask[ch], | 1441 | s->ac3dsp.bit_alloc_calc_bap(ref_block->mask[ch], ref_block->psd[ch], |
| 1017 | ref_block->psd[ch], 0, | 1442 | s->start_freq[ch], block->end_freq[ch], |
| 1018 | s->nb_coefs[ch], snr_offset, | 1443 | snr_offset, s->bit_alloc.floor, |
| 1019 | s->bit_alloc.floor, ff_ac3_bap_tab, | 1444 | ff_ac3_bap_tab, ref_block->bap[ch]); |
| 1020 | ref_block->bap[ch]); | ||
| 1021 | } | 1445 | } |
| 1022 | mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt, | 1446 | mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt, |
| 1023 | ref_block->bap[ch], | 1447 | ref_block->bap[ch]+s->start_freq[ch], |
| 1024 | s->nb_coefs[ch]); | 1448 | block->end_freq[ch]-s->start_freq[ch]); |
| 1449 | if (ch == CPL_CH) | ||
| 1450 | ch = ch0; | ||
| 1025 | } | 1451 | } |
| 1026 | mantissa_bits += compute_mantissa_size_final(mant_cnt); | 1452 | mantissa_bits += compute_mantissa_size_final(mant_cnt); |
| 1027 | } | 1453 | } |
| @@ -1047,7 +1473,7 @@ static int cbr_bit_allocation(AC3EncodeContext *s) · 19 unmodified lines | |||
| 1047 | 1473 | ||
| 1048 | /* if previous frame SNR offset was 1023, check if current frame can also | 1474 | /* if previous frame SNR offset was 1023, check if current frame can also |
| 1049 | use SNR offset of 1023. if so, skip the search. */ | 1475 | use SNR offset of 1023. if so, skip the search. */ |
| 1050 | if ((snr_offset | s->fine_snr_offset[0]) == 1023) { | 1476 | if ((snr_offset | s->fine_snr_offset[1]) == 1023) { |
| 1051 | if (bit_alloc(s, 1023) <= bits_left) | 1477 | if (bit_alloc(s, 1023) <= bits_left) |
| 1052 | return 0; | 1478 | return 0; |
| 1053 | } | 1479 | } |
| @@ -1071,7 +1497,7 @@ static int cbr_bit_allocation(AC3EncodeContext *s) · 17 unmodified lines | |||
| 1071 | reset_block_bap(s); | 1497 | reset_block_bap(s); |
| 1072 | 1498 | ||
| 1073 | s->coarse_snr_offset = snr_offset >> 4; | 1499 | s->coarse_snr_offset = snr_offset >> 4; |
| 1074 | for (ch = 0; ch < s->channels; ch++) | 1500 | for (ch = !s->cpl_on; ch <= s->channels; ch++) |
| 1075 | s->fine_snr_offset[ch] = snr_offset & 0xF; | 1501 | s->fine_snr_offset[ch] = snr_offset & 0xF; |
| 1076 | 1502 | ||
| 1077 | return 0; | 1503 | return 0; |
| @@ -1089,26 +1515,26 @@ static int downgrade_exponents(AC3EncodeContext *s) · 11 unmodified lines | |||
| 1089 | { | 1515 | { |
| 1090 | int ch, blk; | 1516 | int ch, blk; |
| 1091 | 1517 | ||
| 1092 | for (ch = 0; ch < s->fbw_channels; ch++) { | 1518 | for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { |
| 1093 | for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { | 1519 | for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) { |
| 1094 | if (s->exp_strategy[ch][blk] == EXP_D15) { | 1520 | if (s->exp_strategy[ch][blk] == EXP_D15) { |
| 1095 | s->exp_strategy[ch][blk] = EXP_D25; | 1521 | s->exp_strategy[ch][blk] = EXP_D25; |
| 1096 | return 0; | 1522 | return 0; |
| 1097 | } | 1523 | } |
| 1098 | } | 1524 | } |
| 1099 | } | 1525 | } |
| 1100 | for (ch = 0; ch < s->fbw_channels; ch++) { | 1526 | for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { |
| 1101 | for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { | 1527 | for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) { |
| 1102 | if (s->exp_strategy[ch][blk] == EXP_D25) { | 1528 | if (s->exp_strategy[ch][blk] == EXP_D25) { |
| 1103 | s->exp_strategy[ch][blk] = EXP_D45; | 1529 | s->exp_strategy[ch][blk] = EXP_D45; |
| 1104 | return 0; | 1530 | return 0; |
| 1105 | } | 1531 | } |
| 1106 | } | 1532 | } |
| 1107 | } | 1533 | } |
| 1108 | for (ch = 0; ch < s->fbw_channels; ch++) { | 1534 | /* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if |
| 1109 | /* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if | 1535 | the block number > 0 */ |
| 1110 | the block number > 0 */ | 1536 | for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) { |
| 1111 | for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) { | 1537 | for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) { |
| 1112 | if (s->exp_strategy[ch][blk] > EXP_REUSE) { | 1538 | if (s->exp_strategy[ch][blk] > EXP_REUSE) { |
| 1113 | s->exp_strategy[ch][blk] = EXP_REUSE; | 1539 | s->exp_strategy[ch][blk] = EXP_REUSE; |
| 1114 | return 0; | 1540 | return 0; |
| @@ -1135,7 +1561,18 @@ static int compute_bit_allocation(AC3EncodeContext *s) · 20 unmodified lines | |||
| 1135 | 1561 | ||
| 1136 | ret = cbr_bit_allocation(s); | 1562 | ret = cbr_bit_allocation(s); |
| 1137 | while (ret) { | 1563 | while (ret) { |
| 1138 | /* fallback 1: downgrade exponents */ | 1564 | /* fallback 1: disable channel coupling */ |
| 1565 | if (s->cpl_on) { | ||
| 1566 | s->cpl_on = 0; | ||
| 1567 | compute_coupling_strategy(s); | ||
| 1568 | compute_rematrixing_strategy(s); | ||
| 1569 | apply_rematrixing(s); | ||
| 1570 | process_exponents(s); | ||
| 1571 | ret = compute_bit_allocation(s); | ||
| 1572 | continue; | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | /* fallback 2: downgrade exponents */ | ||
| 1139 | if (!downgrade_exponents(s)) { | 1576 | if (!downgrade_exponents(s)) { |
| 1140 | extract_exponents(s); | 1577 | extract_exponents(s); |
| 1141 | encode_exponents(s); | 1578 | encode_exponents(s); |
| @@ -1189,12 +1626,13 @@ static inline int asym_quant(int c, int e, int qbits) · 47 unmodified lines | |||
| 1189 | * Quantize a set of mantissas for a single channel in a single block. | 1626 | * Quantize a set of mantissas for a single channel in a single block. |
| 1190 | */ | 1627 | */ |
| 1191 | static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, | 1628 | static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, |
| 1192 | uint8_t *exp, | 1629 | uint8_t *exp, uint8_t *bap, |
| 1193 | uint8_t *bap, uint16_t *qmant, int n) | 1630 | uint16_t *qmant, int start_freq, |
| 1631 | int end_freq) | ||
| 1194 | { | 1632 | { |
| 1195 | int i; | 1633 | int i; |
| 1196 | 1634 | ||
| 1197 | for (i = 0; i < n; i++) { | 1635 | for (i = start_freq; i < end_freq; i++) { |
| 1198 | int v; | 1636 | int v; |
| 1199 | int c = fixed_coef[i]; | 1637 | int c = fixed_coef[i]; |
| 1200 | int e = exp[i]; | 1638 | int e = exp[i]; |
| @@ -1284,19 +1722,27 @@ static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, · 83 unmodified lines | |||
| 1284 | */ | 1722 | */ |
| 1285 | static void quantize_mantissas(AC3EncodeContext *s) | 1723 | static void quantize_mantissas(AC3EncodeContext *s) |
| 1286 | { | 1724 | { |
| 1287 | int blk, ch; | 1725 | int blk, ch, ch0=0, got_cpl; |
| 1288 | |||
| 1289 | 1726 | ||
| 1290 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 1727 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 1291 | AC3Block *block = &s->blocks[blk]; | 1728 | AC3Block *block = &s->blocks[blk]; |
| 1292 | AC3Block *ref_block; | 1729 | AC3Block *ref_block; |
| 1293 | AC3Mant m = { 0 }; | 1730 | AC3Mant m = { 0 }; |
| 1294 | 1731 | ||
| 1295 | for (ch = 0; ch < s->channels; ch++) { | 1732 | got_cpl = !block->cpl_in_use; |
| 1733 | for (ch = 1; ch <= s->channels; ch++) { | ||
| 1734 | if (!got_cpl && ch > 1 && block->channel_in_cpl[ch-1]) { | ||
| 1735 | ch0 = ch - 1; | ||
| 1736 | ch = CPL_CH; | ||
| 1737 | got_cpl = 1; | ||
| 1738 | } | ||
| 1296 | ref_block = block->exp_ref_block[ch]; | 1739 | ref_block = block->exp_ref_block[ch]; |
| 1297 | quantize_mantissas_blk_ch(&m, block->fixed_coef[ch], | 1740 | quantize_mantissas_blk_ch(&m, block->fixed_coef[ch], |
| 1298 | ref_block->exp[ch], ref_block->bap[ch], | 1741 | ref_block->exp[ch], |
| 1299 | block->qmant[ch], s->nb_coefs[ch]); | 1742 | ref_block->bap[ch], block->qmant[ch], |
| 1743 | s->start_freq[ch], block->end_freq[ch]); | ||
| 1744 | if (ch == CPL_CH) | ||
| 1745 | ch = ch0; | ||
| 1300 | } | 1746 | } |
| 1301 | } | 1747 | } |
| 1302 | } | 1748 | } |
| @@ -1363,7 +1809,8 @@ static void output_frame_header(AC3EncodeContext *s) · 60 unmodified lines | |||
| 1363 | */ | 1809 | */ |
| 1364 | static void output_audio_block(AC3EncodeContext *s, int blk) | 1810 | static void output_audio_block(AC3EncodeContext *s, int blk) |
| 1365 | { | 1811 | { |
| 1366 | int ch, i, baie, rbnd; | 1812 | int ch, i, baie, bnd, got_cpl; |
| 1813 | int av_uninit(ch0); | ||
| 1367 | AC3Block *block = &s->blocks[blk]; | 1814 | AC3Block *block = &s->blocks[blk]; |
| 1368 | 1815 | ||
| 1369 | /* block switching */ | 1816 | /* block switching */ |
| @@ -1378,11 +1825,38 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 8 unmodified lines | |||
| 1378 | put_bits(&s->pb, 1, 0); | 1825 | put_bits(&s->pb, 1, 0); |
| 1379 | 1826 | ||
| 1380 | /* channel coupling */ | 1827 | /* channel coupling */ |
| 1381 | if (!blk) { | 1828 | put_bits(&s->pb, 1, block->new_cpl_strategy); |
| 1382 | put_bits(&s->pb, 1, 1); /* coupling strategy present */ | 1829 | if (block->new_cpl_strategy) { |
| 1383 | put_bits(&s->pb, 1, 0); /* no coupling strategy */ | 1830 | put_bits(&s->pb, 1, block->cpl_in_use); |
| 1384 | } else { | 1831 | if (block->cpl_in_use) { |
| 1385 | put_bits(&s->pb, 1, 0); /* no new coupling strategy */ | 1832 | int start_sub, end_sub; |
| 1833 | for (ch = 1; ch <= s->fbw_channels; ch++) | ||
| 1834 | put_bits(&s->pb, 1, block->channel_in_cpl[ch]); | ||
| 1835 | if (s->channel_mode == AC3_CHMODE_STEREO) | ||
| 1836 | put_bits(&s->pb, 1, 0); /* phase flags in use */ | ||
| 1837 | start_sub = (s->start_freq[CPL_CH] - 37) / 12; | ||
| 1838 | end_sub = (s->cpl_end_freq - 37) / 12; | ||
| 1839 | put_bits(&s->pb, 4, start_sub); | ||
| 1840 | put_bits(&s->pb, 4, end_sub - 3); | ||
| 1841 | for (bnd = start_sub+1; bnd < end_sub; bnd++) | ||
| 1842 | put_bits(&s->pb, 1, ff_eac3_default_cpl_band_struct[bnd]); | ||
| 1843 | } | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | /* coupling coordinates */ | ||
| 1847 | if (block->cpl_in_use) { | ||
| 1848 | for (ch = 1; ch <= s->fbw_channels; ch++) { | ||
| 1849 | if (block->channel_in_cpl[ch]) { | ||
| 1850 | put_bits(&s->pb, 1, block->new_cpl_coords); | ||
| 1851 | if (block->new_cpl_coords) { | ||
| 1852 | put_bits(&s->pb, 2, block->cpl_master_exp[ch]); | ||
| 1853 | for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | ||
| 1854 | put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]); | ||
| 1855 | put_bits(&s->pb, 4, block->cpl_coord_mant[ch][bnd]); | ||
| 1856 | } | ||
| 1857 | } | ||
| 1858 | } | ||
| 1859 | } | ||
| 1386 | } | 1860 | } |
| 1387 | 1861 | ||
| 1388 | /* stereo rematrixing */ | 1862 | /* stereo rematrixing */ |
| @@ -1390,40 +1864,41 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 1 unmodified line | |||
| 1390 | put_bits(&s->pb, 1, block->new_rematrixing_strategy); | 1864 | put_bits(&s->pb, 1, block->new_rematrixing_strategy); |
| 1391 | if (block->new_rematrixing_strategy) { | 1865 | if (block->new_rematrixing_strategy) { |
| 1392 | /* rematrixing flags */ | 1866 | /* rematrixing flags */ |
| 1393 | for (rbnd = 0; rbnd < s->num_rematrixing_bands; rbnd++) | 1867 | for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) |
| 1394 | put_bits(&s->pb, 1, block->rematrixing_flags[rbnd]); | 1868 | put_bits(&s->pb, 1, block->rematrixing_flags[bnd]); |
| 1395 | } | 1869 | } |
| 1396 | } | 1870 | } |
| 1397 | 1871 | ||
| 1398 | /* exponent strategy */ | 1872 | /* exponent strategy */ |
| 1399 | for (ch = 0; ch < s->fbw_channels; ch++) | 1873 | for (ch = !block->cpl_in_use; ch <= s->fbw_channels; ch++) |
| 1400 | put_bits(&s->pb, 2, s->exp_strategy[ch][blk]); | 1874 | put_bits(&s->pb, 2, s->exp_strategy[ch][blk]); |
| 1401 | if (s->lfe_on) | 1875 | if (s->lfe_on) |
| 1402 | put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]); | 1876 | put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]); |
| 1403 | 1877 | ||
| 1404 | /* bandwidth */ | 1878 | /* bandwidth */ |
| 1405 | for (ch = 0; ch < s->fbw_channels; ch++) { | 1879 | for (ch = 1; ch <= s->fbw_channels; ch++) { |
| 1406 | if (s->exp_strategy[ch][blk] != EXP_REUSE) | 1880 | if (s->exp_strategy[ch][blk] != EXP_REUSE && !block->channel_in_cpl[ch]) |
| 1407 | put_bits(&s->pb, 6, s->bandwidth_code); | 1881 | put_bits(&s->pb, 6, s->bandwidth_code); |
| 1408 | } | 1882 | } |
| 1409 | 1883 | ||
| 1410 | /* exponents */ | 1884 | /* exponents */ |
| 1411 | for (ch = 0; ch < s->channels; ch++) { | 1885 | for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { |
| 1412 | int nb_groups; | 1886 | int nb_groups; |
| 1887 | int cpl = (ch == CPL_CH); | ||
| 1413 | 1888 | ||
| 1414 | if (s->exp_strategy[ch][blk] == EXP_REUSE) | 1889 | if (s->exp_strategy[ch][blk] == EXP_REUSE) |
| 1415 | continue; | 1890 | continue; |
| 1416 | 1891 | ||
| 1417 | /* DC exponent */ | 1892 | /* DC exponent */ |
| 1418 | put_bits(&s->pb, 4, block->grouped_exp[ch][0]); | 1893 | put_bits(&s->pb, 4, block->grouped_exp[ch][0] >> cpl); |
| 1419 | 1894 | ||
| 1420 | /* exponent groups */ | 1895 | /* exponent groups */ |
| 1421 | nb_groups = exponent_group_tab[s->exp_strategy[ch][blk]-1][s->nb_coefs[ch]]; | 1896 | nb_groups = exponent_group_tab[cpl][s->exp_strategy[ch][blk]-1][block->end_freq[ch]-s->start_freq[ch]]; |
| 1422 | for (i = 1; i <= nb_groups; i++) | 1897 | for (i = 1; i <= nb_groups; i++) |
| 1423 | put_bits(&s->pb, 7, block->grouped_exp[ch][i]); | 1898 | put_bits(&s->pb, 7, block->grouped_exp[ch][i]); |
| 1424 | 1899 | ||
| 1425 | /* gain range info */ | 1900 | /* gain range info */ |
| 1426 | if (ch != s->lfe_channel) | 1901 | if (ch != s->lfe_channel && !cpl) |
| 1427 | put_bits(&s->pb, 2, 0); | 1902 | put_bits(&s->pb, 2, 0); |
| 1428 | } | 1903 | } |
| 1429 | 1904 | ||
| @@ -1439,23 +1914,40 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 9 unmodified lines | |||
| 1439 | } | 1914 | } |
| 1440 | 1915 | ||
| 1441 | /* snr offset */ | 1916 | /* snr offset */ |
| 1442 | put_bits(&s->pb, 1, baie); | 1917 | put_bits(&s->pb, 1, block->new_snr_offsets); |
| 1443 | if (baie) { | 1918 | if (block->new_snr_offsets) { |
| 1444 | put_bits(&s->pb, 6, s->coarse_snr_offset); | 1919 | put_bits(&s->pb, 6, s->coarse_snr_offset); |
| 1445 | for (ch = 0; ch < s->channels; ch++) { | 1920 | for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { |
| 1446 | put_bits(&s->pb, 4, s->fine_snr_offset[ch]); | 1921 | put_bits(&s->pb, 4, s->fine_snr_offset[ch]); |
| 1447 | put_bits(&s->pb, 3, s->fast_gain_code[ch]); | 1922 | put_bits(&s->pb, 3, s->fast_gain_code[ch]); |
| 1448 | } | 1923 | } |
| 1449 | } | 1924 | } |
| 1450 | 1925 | ||
| 1926 | /* coupling leak */ | ||
| 1927 | if (block->cpl_in_use) { | ||
| 1928 | put_bits(&s->pb, 1, block->new_cpl_leak); | ||
| 1929 | if (block->new_cpl_leak) { | ||
| 1930 | put_bits(&s->pb, 3, s->bit_alloc.cpl_fast_leak); | ||
| 1931 | put_bits(&s->pb, 3, s->bit_alloc.cpl_slow_leak); | ||
| 1932 | } | ||
| 1933 | } | ||
| 1934 | |||
| 1451 | put_bits(&s->pb, 1, 0); /* no delta bit allocation */ | 1935 | put_bits(&s->pb, 1, 0); /* no delta bit allocation */ |
| 1452 | put_bits(&s->pb, 1, 0); /* no data to skip */ | 1936 | put_bits(&s->pb, 1, 0); /* no data to skip */ |
| 1453 | 1937 | ||
| 1454 | /* mantissas */ | 1938 | /* mantissas */ |
| 1455 | for (ch = 0; ch < s->channels; ch++) { | 1939 | got_cpl = !block->cpl_in_use; |
| 1940 | for (ch = 1; ch <= s->channels; ch++) { | ||
| 1456 | int b, q; | 1941 | int b, q; |
| 1457 | AC3Block *ref_block = block->exp_ref_block[ch]; | 1942 | AC3Block *ref_block; |
| 1458 | for (i = 0; i < s->nb_coefs[ch]; i++) { | 1943 | |
| 1944 | if (!got_cpl && ch > 1 && block->channel_in_cpl[ch-1]) { | ||
| 1945 | ch0 = ch - 1; | ||
| 1946 | ch = CPL_CH; | ||
| 1947 | got_cpl = 1; | ||
| 1948 | } | ||
| 1949 | ref_block = block->exp_ref_block[ch]; | ||
| 1950 | for (i = s->start_freq[ch]; i < block->end_freq[ch]; i++) { | ||
| 1459 | q = block->qmant[ch][i]; | 1951 | q = block->qmant[ch][i]; |
| 1460 | b = ref_block->bap[ch][i]; | 1952 | b = ref_block->bap[ch][i]; |
| 1461 | switch (b) { | 1953 | switch (b) { |
| @@ -1469,6 +1961,8 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 7 unmodified lines | |||
| 1469 | default: put_bits(&s->pb, b-1, q); break; | 1961 | default: put_bits(&s->pb, b-1, q); break; |
| 1470 | } | 1962 | } |
| 1471 | } | 1963 | } |
| 1964 | if (ch == CPL_CH) | ||
| 1965 | ch = ch0; | ||
| 1472 | } | 1966 | } |
| 1473 | } | 1967 | } |
| 1474 | 1968 | ||
| @@ -1854,6 +2348,12 @@ static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame, · 379 unmodified lines | |||
| 1854 | 2348 | ||
| 1855 | scale_coefficients(s); | 2349 | scale_coefficients(s); |
| 1856 | 2350 | ||
| 2351 | s->cpl_on = s->cpl_enabled; | ||
| 2352 | compute_coupling_strategy(s); | ||
| 2353 | |||
| 2354 | if (s->cpl_on) | ||
| 2355 | apply_channel_coupling(s); | ||
| 2356 | |||
| 1857 | compute_rematrixing_strategy(s); | 2357 | compute_rematrixing_strategy(s); |
| 1858 | 2358 | ||
| 1859 | apply_rematrixing(s); | 2359 | apply_rematrixing(s); |
| @@ -1934,7 +2434,7 @@ static av_cold int set_channel_info(AC3EncodeContext *s, int channels, · 74 unmodified lines | |||
| 1934 | s->lfe_on = !!(ch_layout & AV_CH_LOW_FREQUENCY); | 2434 | s->lfe_on = !!(ch_layout & AV_CH_LOW_FREQUENCY); |
| 1935 | s->channels = channels; | 2435 | s->channels = channels; |
| 1936 | s->fbw_channels = channels - s->lfe_on; | 2436 | s->fbw_channels = channels - s->lfe_on; |
| 1937 | s->lfe_channel = s->lfe_on ? s->fbw_channels : -1; | 2437 | s->lfe_channel = s->lfe_on ? s->fbw_channels + 1 : -1; |
| 1938 | if (s->lfe_on) | 2438 | if (s->lfe_on) |
| 1939 | ch_layout -= AV_CH_LOW_FREQUENCY; | 2439 | ch_layout -= AV_CH_LOW_FREQUENCY; |
| 1940 | 2440 | ||
| @@ -2033,6 +2533,10 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) · 92 unmodified lines | |||
| 2033 | s->rematrixing_enabled = s->options.stereo_rematrixing && | 2533 | s->rematrixing_enabled = s->options.stereo_rematrixing && |
| 2034 | (s->channel_mode == AC3_CHMODE_STEREO); | 2534 | (s->channel_mode == AC3_CHMODE_STEREO); |
| 2035 | 2535 | ||
| 2536 | s->cpl_enabled = s->options.channel_coupling && | ||
| 2537 | s->channel_mode >= AC3_CHMODE_STEREO && | ||
| 2538 | CONFIG_AC3ENC_FLOAT; | ||
| 2539 | |||
| 2036 | return 0; | 2540 | return 0; |
| 2037 | } | 2541 | } |
| 2038 | 2542 | ||
| @@ -2044,7 +2548,8 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) · 5 unmodified lines | |||
| 2044 | */ | 2548 | */ |
| 2045 | static av_cold void set_bandwidth(AC3EncodeContext *s) | 2549 | static av_cold void set_bandwidth(AC3EncodeContext *s) |
| 2046 | { | 2550 | { |
| 2047 | int ch; | 2551 | int blk, ch; |
| 2552 | int av_uninit(cpl_start); | ||
| 2048 | 2553 | ||
| 2049 | if (s->cutoff) { | 2554 | if (s->cutoff) { |
| 2050 | /* calculate bandwidth based on user-specified cutoff frequency */ | 2555 | /* calculate bandwidth based on user-specified cutoff frequency */ |
| @@ -2057,11 +2562,54 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) · 6 unmodified lines | |||
| 2057 | } | 2562 | } |
| 2058 | 2563 | ||
| 2059 | /* set number of coefficients for each channel */ | 2564 | /* set number of coefficients for each channel */ |
| 2060 | for (ch = 0; ch < s->fbw_channels; ch++) { | 2565 | for (ch = 1; ch <= s->fbw_channels; ch++) { |
| 2061 | s->nb_coefs[ch] = s->bandwidth_code * 3 + 73; | 2566 | s->start_freq[ch] = 0; |
| 2567 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) | ||
| 2568 | s->blocks[blk].end_freq[ch] = s->bandwidth_code * 3 + 73; | ||
| 2569 | } | ||
| 2570 | /* LFE channel always has 7 coefs */ | ||
| 2571 | if (s->lfe_on) { | ||
| 2572 | s->start_freq[s->lfe_channel] = 0; | ||
| 2573 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) | ||
| 2574 | s->blocks[blk].end_freq[ch] = 7; | ||
| 2575 | } | ||
| 2576 | |||
| 2577 | /* initialize coupling strategy */ | ||
| 2578 | if (s->cpl_enabled) { | ||
| 2579 | if (s->options.cpl_start >= 0) { | ||
| 2580 | cpl_start = s->options.cpl_start; | ||
| 2581 | } else { | ||
| 2582 | cpl_start = ac3_coupling_start_tab[s->channel_mode-2][s->bit_alloc.sr_code][s->frame_size_code/2]; | ||
| 2583 | if (cpl_start < 0) | ||
| 2584 | s->cpl_enabled = 0; | ||
| 2585 | } | ||
| 2586 | } | ||
| 2587 | if (s->cpl_enabled) { | ||
| 2588 | int i, cpl_start_band, cpl_end_band; | ||
| 2589 | uint8_t *cpl_band_sizes = s->cpl_band_sizes; | ||
| 2590 | |||
| 2591 | cpl_end_band = s->bandwidth_code / 4 + 3; | ||
| 2592 | cpl_start_band = av_clip(cpl_start, 0, FFMIN(cpl_end_band-1, 15)); | ||
| 2593 | |||
| 2594 | s->num_cpl_subbands = cpl_end_band - cpl_start_band; | ||
| 2595 | |||
| 2596 | s->num_cpl_bands = 1; | ||
| 2597 | *cpl_band_sizes = 12; | ||
| 2598 | for (i = cpl_start_band + 1; i < cpl_end_band; i++) { | ||
| 2599 | if (ff_eac3_default_cpl_band_struct[i]) { | ||
| 2600 | *cpl_band_sizes += 12; | ||
| 2601 | } else { | ||
| 2602 | s->num_cpl_bands++; | ||
| 2603 | cpl_band_sizes++; | ||
| 2604 | *cpl_band_sizes = 12; | ||
| 2605 | } | ||
| 2606 | } | ||
| 2607 | |||
| 2608 | s->start_freq[CPL_CH] = cpl_start_band * 12 + 37; | ||
| 2609 | s->cpl_end_freq = cpl_end_band * 12 + 37; | ||
| 2610 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) | ||
| 2611 | s->blocks[blk].end_freq[CPL_CH] = s->cpl_end_freq; | ||
| 2062 | } | 2612 | } |
| 2063 | if (s->lfe_on) | ||
| 2064 | s->nb_coefs[s->lfe_channel] = 7; /* LFE channel always has 7 coefs */ | ||
| 2065 | } | 2613 | } |
| 2066 | 2614 | ||
| 2067 | 2615 | ||
| @@ -2069,6 +2617,7 @@ static av_cold int allocate_buffers(AVCodecContext *avctx) · 1 unmodified line | |||
| 2069 | { | 2617 | { |
| 2070 | int blk, ch; | 2618 | int blk, ch; |
| 2071 | AC3EncodeContext *s = avctx->priv_data; | 2619 | AC3EncodeContext *s = avctx->priv_data; |
| 2620 | int channels = s->channels + 1; /* includes coupling channel */ | ||
| 2072 | 2621 | ||
| 2073 | FF_ALLOC_OR_GOTO(avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples), | 2622 | FF_ALLOC_OR_GOTO(avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples), |
| 2074 | alloc_fail); | 2623 | alloc_fail); |
| @@ -2077,74 +2626,90 @@ static av_cold int allocate_buffers(AVCodecContext *avctx) · 2 unmodified lines | |||
| 2077 | (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples), | 2626 | (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples), |
| 2078 | alloc_fail); | 2627 | alloc_fail); |
| 2079 | } | 2628 | } |
| 2080 | FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * s->channels * | 2629 | FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * channels * |
| 2081 | AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail); | 2630 | AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail); |
| 2082 | FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * s->channels * | 2631 | FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * channels * |
| 2083 | AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail); | 2632 | AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail); |
| 2084 | FF_ALLOC_OR_GOTO(avctx, s->mdct_coef_buffer, AC3_MAX_BLOCKS * s->channels * | 2633 | FF_ALLOC_OR_GOTO(avctx, s->mdct_coef_buffer, AC3_MAX_BLOCKS * channels * |
| 2085 | AC3_MAX_COEFS * sizeof(*s->mdct_coef_buffer), alloc_fail); | 2634 | AC3_MAX_COEFS * sizeof(*s->mdct_coef_buffer), alloc_fail); |
| 2086 | FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, AC3_MAX_BLOCKS * s->channels * | 2635 | FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, AC3_MAX_BLOCKS * channels * |
| 2087 | AC3_MAX_COEFS * sizeof(*s->exp_buffer), alloc_fail); | 2636 | AC3_MAX_COEFS * sizeof(*s->exp_buffer), alloc_fail); |
| 2088 | FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, AC3_MAX_BLOCKS * s->channels * | 2637 | FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, AC3_MAX_BLOCKS * channels * |
| 2089 | 128 * sizeof(*s->grouped_exp_buffer), alloc_fail); | 2638 | 128 * sizeof(*s->grouped_exp_buffer), alloc_fail); |
| 2090 | FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, AC3_MAX_BLOCKS * s->channels * | 2639 | FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, AC3_MAX_BLOCKS * channels * |
| 2091 | AC3_MAX_COEFS * sizeof(*s->psd_buffer), alloc_fail); | 2640 | AC3_MAX_COEFS * sizeof(*s->psd_buffer), alloc_fail); |
| 2092 | FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, AC3_MAX_BLOCKS * s->channels * | 2641 | FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, AC3_MAX_BLOCKS * channels * |
| 2093 | 64 * sizeof(*s->band_psd_buffer), alloc_fail); | 2642 | 64 * sizeof(*s->band_psd_buffer), alloc_fail); |
| 2094 | FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, AC3_MAX_BLOCKS * s->channels * | 2643 | FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, AC3_MAX_BLOCKS * channels * |
| 2095 | 64 * sizeof(*s->mask_buffer), alloc_fail); | 2644 | 64 * sizeof(*s->mask_buffer), alloc_fail); |
| 2096 | FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, AC3_MAX_BLOCKS * s->channels * | 2645 | FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, AC3_MAX_BLOCKS * channels * |
| 2097 | AC3_MAX_COEFS * sizeof(*s->qmant_buffer), alloc_fail); | 2646 | AC3_MAX_COEFS * sizeof(*s->qmant_buffer), alloc_fail); |
| 2647 | if (s->cpl_enabled) { | ||
| 2648 | FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_exp_buffer, AC3_MAX_BLOCKS * channels * | ||
| 2649 | 16 * sizeof(*s->cpl_coord_exp_buffer), alloc_fail); | ||
| 2650 | FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_mant_buffer, AC3_MAX_BLOCKS * channels * | ||
| 2651 | 16 * sizeof(*s->cpl_coord_mant_buffer), alloc_fail); | ||
| 2652 | } | ||
| 2098 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 2653 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 2099 | AC3Block *block = &s->blocks[blk]; | 2654 | AC3Block *block = &s->blocks[blk]; |
| 2100 | FF_ALLOC_OR_GOTO(avctx, block->bap, s->channels * sizeof(*block->bap), | 2655 | FF_ALLOC_OR_GOTO(avctx, block->bap, channels * sizeof(*block->bap), |
| 2101 | alloc_fail); | 2656 | alloc_fail); |
| 2102 | FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, s->channels * sizeof(*block->mdct_coef), | 2657 | FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, channels * sizeof(*block->mdct_coef), |
| 2103 | alloc_fail); | 2658 | alloc_fail); |
| 2104 | FF_ALLOCZ_OR_GOTO(avctx, block->exp, s->channels * sizeof(*block->exp), | 2659 | FF_ALLOCZ_OR_GOTO(avctx, block->exp, channels * sizeof(*block->exp), |
| 2105 | alloc_fail); | 2660 | alloc_fail); |
| 2106 | FF_ALLOCZ_OR_GOTO(avctx, block->grouped_exp, s->channels * sizeof(*block->grouped_exp), | 2661 | FF_ALLOCZ_OR_GOTO(avctx, block->grouped_exp, channels * sizeof(*block->grouped_exp), |
| 2107 | alloc_fail); | 2662 | alloc_fail); |
| 2108 | FF_ALLOCZ_OR_GOTO(avctx, block->psd, s->channels * sizeof(*block->psd), | 2663 | FF_ALLOCZ_OR_GOTO(avctx, block->psd, channels * sizeof(*block->psd), |
| 2109 | alloc_fail); | 2664 | alloc_fail); |
| 2110 | FF_ALLOCZ_OR_GOTO(avctx, block->band_psd, s->channels * sizeof(*block->band_psd), | 2665 | FF_ALLOCZ_OR_GOTO(avctx, block->band_psd, channels * sizeof(*block->band_psd), |
| 2111 | alloc_fail); | 2666 | alloc_fail); |
| 2112 | FF_ALLOCZ_OR_GOTO(avctx, block->mask, s->channels * sizeof(*block->mask), | 2667 | FF_ALLOCZ_OR_GOTO(avctx, block->mask, channels * sizeof(*block->mask), |
| 2113 | alloc_fail); | 2668 | alloc_fail); |
| 2114 | FF_ALLOCZ_OR_GOTO(avctx, block->qmant, s->channels * sizeof(*block->qmant), | 2669 | FF_ALLOCZ_OR_GOTO(avctx, block->qmant, channels * sizeof(*block->qmant), |
| 2115 | alloc_fail); | 2670 | alloc_fail); |
| 2671 | if (s->cpl_enabled) { | ||
| 2672 | FF_ALLOCZ_OR_GOTO(avctx, block->cpl_coord_exp, channels * sizeof(*block->cpl_coord_exp), | ||
| 2673 | alloc_fail); | ||
| 2674 | FF_ALLOCZ_OR_GOTO(avctx, block->cpl_coord_mant, channels * sizeof(*block->cpl_coord_mant), | ||
| 2675 | alloc_fail); | ||
| 2676 | } | ||
| 2116 | 2677 | ||
| 2117 | for (ch = 0; ch < s->channels; ch++) { | 2678 | for (ch = 0; ch < channels; ch++) { |
| 2118 | /* arrangement: block, channel, coeff */ | 2679 | /* arrangement: block, channel, coeff */ |
| 2119 | block->bap[ch] = &s->bap_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; | 2680 | block->bap[ch] = &s->bap_buffer [AC3_MAX_COEFS * (blk * channels + ch)]; |
| 2120 | block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; | 2681 | block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * channels + ch)]; |
| 2121 | block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * s->channels + ch)]; | 2682 | block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * channels + ch)]; |
| 2122 | block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; | 2683 | block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * channels + ch)]; |
| 2123 | block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * s->channels + ch)]; | 2684 | block->mask[ch] = &s->mask_buffer [64 * (blk * channels + ch)]; |
| 2124 | block->mask[ch] = &s->mask_buffer [64 * (blk * s->channels + ch)]; | 2685 | block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * channels + ch)]; |
| 2125 | block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; | 2686 | if (s->cpl_enabled) { |
| 2687 | block->cpl_coord_exp[ch] = &s->cpl_coord_exp_buffer [16 * (blk * channels + ch)]; | ||
| 2688 | block->cpl_coord_mant[ch] = &s->cpl_coord_mant_buffer[16 * (blk * channels + ch)]; | ||
| 2689 | } | ||
| 2126 | 2690 | ||
| 2127 | /* arrangement: channel, block, coeff */ | 2691 | /* arrangement: channel, block, coeff */ |
| 2128 | block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; | 2692 | block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; |
| 2693 | block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; | ||
| 2129 | } | 2694 | } |
| 2130 | } | 2695 | } |
| 2131 | 2696 | ||
| 2132 | if (CONFIG_AC3ENC_FLOAT) { | 2697 | if (CONFIG_AC3ENC_FLOAT) { |
| 2133 | FF_ALLOC_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * s->channels * | 2698 | FF_ALLOC_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * channels * |
| 2134 | AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail); | 2699 | AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail); |
| 2135 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 2700 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 2136 | AC3Block *block = &s->blocks[blk]; | 2701 | AC3Block *block = &s->blocks[blk]; |
| 2137 | FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels * | 2702 | FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels * |
| 2138 | sizeof(*block->fixed_coef), alloc_fail); | 2703 | sizeof(*block->fixed_coef), alloc_fail); |
| 2139 | for (ch = 0; ch < s->channels; ch++) | 2704 | for (ch = 0; ch < channels; ch++) |
| 2140 | block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)]; | 2705 | block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; |
| 2141 | } | 2706 | } |
| 2142 | } else { | 2707 | } else { |
| 2143 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 2708 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 2144 | AC3Block *block = &s->blocks[blk]; | 2709 | AC3Block *block = &s->blocks[blk]; |
| 2145 | FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels * | 2710 | FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels * |
| 2146 | sizeof(*block->fixed_coef), alloc_fail); | 2711 | sizeof(*block->fixed_coef), alloc_fail); |
| 2147 | for (ch = 0; ch < s->channels; ch++) | 2712 | for (ch = 0; ch < channels; ch++) |
| 2148 | block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch]; | 2713 | block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch]; |
| 2149 | } | 2714 | } |
| 2150 | } | 2715 | } |
| @@ -101,7 +101,7 @@ static void scale_coefficients(AC3EncodeContext *s) · 100 unmodified lines | |||
| 101 | 101 | ||
| 102 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | 102 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 103 | AC3Block *block = &s->blocks[blk]; | 103 | AC3Block *block = &s->blocks[blk]; |
| 104 | for (ch = 0; ch < s->channels; ch++) { | 104 | for (ch = 1; ch <= s->channels; ch++) { |
| 105 | s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS, | 105 | s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS, |
| 106 | block->coeff_shift[ch]); | 106 | block->coeff_shift[ch]); |
| 107 | } | 107 | } |
| @@ -93,8 +93,10 @@ static int normalize_samples(AC3EncodeContext *s) · 92 unmodified lines | |||
| 93 | */ | 93 | */ |
| 94 | static void scale_coefficients(AC3EncodeContext *s) | 94 | static void scale_coefficients(AC3EncodeContext *s) |
| 95 | { | 95 | { |
| 96 | s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer, s->mdct_coef_buffer, | 96 | int chan_size = AC3_MAX_COEFS * AC3_MAX_BLOCKS; |
| 97 | AC3_MAX_COEFS * AC3_MAX_BLOCKS * s->channels); | 97 | s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + chan_size, |
| 98 | s->mdct_coef_buffer + chan_size, | ||
| 99 | chan_size * s->channels); | ||
| 98 | } | 100 | } |
| 99 | 101 | ||
| 100 | 102 | ||
| @@ -138,6 +138,13 @@ const uint16_t ff_ac3_bitrate_tab[19] = { · 137 unmodified lines | |||
| 138 | */ | 138 | */ |
| 139 | const uint8_t ff_ac3_rematrix_band_tab[5] = { 13, 25, 37, 61, 253 }; | 139 | const uint8_t ff_ac3_rematrix_band_tab[5] = { 13, 25, 37, 61, 253 }; |
| 140 | 140 | ||
| 141 | /** | ||
| 142 | * Table E2.16 Default Coupling Banding Structure | ||
| 143 | */ | ||
| 144 | const uint8_t ff_eac3_default_cpl_band_struct[18] = { | ||
| 145 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 | ||
| 146 | }; | ||
| 147 | |||
| 141 | /* AC-3 MDCT window */ | 148 | /* AC-3 MDCT window */ |
| 142 | 149 | ||
| 143 | /* MDCT window */ | 150 | /* MDCT window */ |
| @@ -39,6 +39,7 @@ extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; · 38 unmodified lines | |||
| 39 | extern const uint16_t ff_ac3_sample_rate_tab[3]; | 39 | extern const uint16_t ff_ac3_sample_rate_tab[3]; |
| 40 | extern const uint16_t ff_ac3_bitrate_tab[19]; | 40 | extern const uint16_t ff_ac3_bitrate_tab[19]; |
| 41 | extern const uint8_t ff_ac3_rematrix_band_tab[5]; | 41 | extern const uint8_t ff_ac3_rematrix_band_tab[5]; |
| 42 | extern const uint8_t ff_eac3_default_cpl_band_struct[18]; | ||
| 42 | extern const int16_t ff_ac3_window[AC3_WINDOW_SIZE/2]; | 43 | extern const int16_t ff_ac3_window[AC3_WINDOW_SIZE/2]; |
| 43 | extern const uint8_t ff_ac3_log_add_tab[260]; | 44 | extern const uint8_t ff_ac3_log_add_tab[260]; |
| 44 | extern const uint16_t ff_ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3]; | 45 | extern const uint16_t ff_ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3]; |
| @@ -156,7 +156,7 @@ void avcodec_register_all(void) · 155 unmodified lines | |||
| 156 | REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau); | 156 | REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau); |
| 157 | REGISTER_DECODER (MPEG2_CRYSTALHD, mpeg2_crystalhd); | 157 | REGISTER_DECODER (MPEG2_CRYSTALHD, mpeg2_crystalhd); |
| 158 | REGISTER_DECODER (MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); | 158 | REGISTER_DECODER (MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); |
| 159 | REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1); | 159 | REGISTER_DECODER (MSMPEG4V1, msmpeg4v1); |
| 160 | REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); | 160 | REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); |
| 161 | REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); | 161 | REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); |
| 162 | REGISTER_DECODER (MSRLE, msrle); | 162 | REGISTER_DECODER (MSRLE, msrle); |
| @@ -628,13 +628,6 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){ · 627 unmodified lines | |||
| 628 | } | 628 | } |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | /** | ||
| 632 | * Empty mmx state. | ||
| 633 | * this must be called between any dsp function and float/double code. | ||
| 634 | * for example sin(); dsp->idct_put(); emms_c(); cos() | ||
| 635 | */ | ||
| 636 | #define emms_c() | ||
| 637 | |||
| 638 | void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); | 631 | void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); |
| 639 | void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); | 632 | void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); |
| 640 | void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); | 633 | void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); |
| @@ -652,22 +645,9 @@ void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx); · 11 unmodified lines | |||
| 652 | void ff_mlp_init(DSPContext* c, AVCodecContext *avctx); | 645 | void ff_mlp_init(DSPContext* c, AVCodecContext *avctx); |
| 653 | void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx); | 646 | void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx); |
| 654 | 647 | ||
| 655 | #if HAVE_MMX | ||
| 656 | |||
| 657 | #undef emms_c | ||
| 658 | 648 | ||
| 659 | static inline void emms(void) | 649 | #if ARCH_ARM |
| 660 | { | ||
| 661 | __asm__ volatile ("emms;":::"memory"); | ||
| 662 | } | ||
| 663 | |||
| 664 | #define emms_c() \ | ||
| 665 | {\ | ||
| 666 | if(av_get_cpu_flags() & AV_CPU_FLAG_MMX)\ | ||
| 667 | emms();\ | ||
| 668 | } | ||
| 669 | 650 | ||
| 670 | #elif ARCH_ARM | ||
| 671 | 651 | ||
| 672 | #if HAVE_NEON | 652 | #if HAVE_NEON |
| 673 | # define STRIDE_ALIGN 16 | 653 | # define STRIDE_ALIGN 16 |
| @@ -638,15 +638,6 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) · 637 unmodified lines | |||
| 638 | s->low_delay= s->max_b_frames ? 0 : 1; | 638 | s->low_delay= s->max_b_frames ? 0 : 1; |
| 639 | avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); | 639 | avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); |
| 640 | break; | 640 | break; |
| 641 | case CODEC_ID_MSMPEG4V1: | ||
| 642 | s->out_format = FMT_H263; | ||
| 643 | s->h263_msmpeg4 = 1; | ||
| 644 | s->h263_pred = 1; | ||
| 645 | s->unrestricted_mv = 1; | ||
| 646 | s->msmpeg4_version= 1; | ||
| 647 | avctx->delay=0; | ||
| 648 | s->low_delay=1; | ||
| 649 | break; | ||
| 650 | case CODEC_ID_MSMPEG4V2: | 641 | case CODEC_ID_MSMPEG4V2: |
| 651 | s->out_format = FMT_H263; | 642 | s->out_format = FMT_H263; |
| 652 | s->h263_msmpeg4 = 1; | 643 | s->h263_msmpeg4 = 1; |
| @@ -3807,18 +3798,6 @@ AVCodec ff_h263p_encoder = { · 3154 unmodified lines | |||
| 3807 | .long_name= NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"), | 3798 | .long_name= NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"), |
| 3808 | }; | 3799 | }; |
| 3809 | 3800 | ||
| 3810 | AVCodec ff_msmpeg4v1_encoder = { | ||
| 3811 | "msmpeg4v1", | ||
| 3812 | AVMEDIA_TYPE_VIDEO, | ||
| 3813 | CODEC_ID_MSMPEG4V1, | ||
| 3814 | sizeof(MpegEncContext), | ||
| 3815 | MPV_encode_init, | ||
| 3816 | MPV_encode_picture, | ||
| 3817 | MPV_encode_end, | ||
| 3818 | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||
| 3819 | .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"), | ||
| 3820 | }; | ||
| 3821 | |||
| 3822 | AVCodec ff_msmpeg4v2_encoder = { | 3801 | AVCodec ff_msmpeg4v2_encoder = { |
| 3823 | "msmpeg4v2", | 3802 | "msmpeg4v2", |
| 3824 | AVMEDIA_TYPE_VIDEO, | 3803 | AVMEDIA_TYPE_VIDEO, |
| @@ -846,22 +846,14 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr · 845 unmodified lines | |||
| 846 | int pred, extquant; | 846 | int pred, extquant; |
| 847 | int extrabits = 0; | 847 | int extrabits = 0; |
| 848 | 848 | ||
| 849 | if(s->msmpeg4_version==1){ | 849 | int16_t *dc_val; |
| 850 | int32_t *dc_val; | 850 | pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); |
| 851 | pred = msmpeg4v1_pred_dc(s, n, &dc_val); | ||
| 852 | |||
| 853 | /* update predictor */ | ||
| 854 | *dc_val= level; | ||
| 855 | }else{ | ||
| 856 | int16_t *dc_val; | ||
| 857 | pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); | ||
| 858 | 851 | ||
| 859 | /* update predictor */ | 852 | /* update predictor */ |
| 860 | if (n < 4) { | 853 | if (n < 4) { |
| 861 | *dc_val = level * s->y_dc_scale; | 854 | *dc_val = level * s->y_dc_scale; |
| 862 | } else { | 855 | } else { |
| 863 | *dc_val = level * s->c_dc_scale; | 856 | *dc_val = level * s->c_dc_scale; |
| 864 | } | ||
| 865 | } | 857 | } |
| 866 | 858 | ||
| 867 | /* do the prediction */ | 859 | /* do the prediction */ |
| @@ -54,8 +54,7 @@ int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); · 53 unmodified lines | |||
| 54 | CONFIG_MSMPEG4V3_DECODER || \ | 54 | CONFIG_MSMPEG4V3_DECODER || \ |
| 55 | CONFIG_WMV2_DECODER || \ | 55 | CONFIG_WMV2_DECODER || \ |
| 56 | CONFIG_VC1_DECODER) | 56 | CONFIG_VC1_DECODER) |
| 57 | #define CONFIG_MSMPEG4_ENCODER (CONFIG_MSMPEG4V1_ENCODER || \ | 57 | #define CONFIG_MSMPEG4_ENCODER (CONFIG_MSMPEG4V2_ENCODER || \ |
| 58 | CONFIG_MSMPEG4V2_ENCODER || \ | ||
| 59 | CONFIG_MSMPEG4V3_ENCODER || \ | 58 | CONFIG_MSMPEG4V3_ENCODER || \ |
| 60 | CONFIG_WMV2_ENCODER) | 59 | CONFIG_WMV2_ENCODER) |
| 61 | 60 | ||
| @@ -39,6 +39,8 @@ typedef struct TiffContext { · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | int width, height; | 40 | int width, height; |
| 41 | unsigned int bpp, bppcount; | 41 | unsigned int bpp, bppcount; |
| 42 | uint32_t palette[256]; | ||
| 43 | int palette_is_set; | ||
| 42 | int le; | 44 | int le; |
| 43 | enum TiffCompr compr; | 45 | enum TiffCompr compr; |
| 44 | int invert; | 46 | int invert; |
| @@ -255,11 +257,15 @@ static int init_image(TiffContext *s) · 210 unmodified lines | |||
| 255 | av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 257 | av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
| 256 | return ret; | 258 | return ret; |
| 257 | } | 259 | } |
| 258 | if (s->bpp == 8 && s->picture.data[1]){ | 260 | if (s->avctx->pix_fmt == PIX_FMT_PAL8) { |
| 259 | /* make default grayscale pal */ | 261 | if (s->palette_is_set) { |
| 260 | pal = (uint32_t *) s->picture.data[1]; | 262 | memcpy(s->picture.data[1], s->palette, sizeof(s->palette)); |
| 261 | for (i = 0; i < 256; i++) | 263 | } else { |
| 262 | pal[i] = i * 0x010101; | 264 | /* make default grayscale pal */ |
| 265 | pal = (uint32_t *) s->picture.data[1]; | ||
| 266 | for (i = 0; i < 256; i++) | ||
| 267 | pal[i] = i * 0x010101; | ||
| 268 | } | ||
| 263 | } | 269 | } |
| 264 | return 0; | 270 | return 0; |
| 265 | } | 271 | } |
| @@ -442,11 +448,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * · 176 unmodified lines | |||
| 442 | s->fill_order = value - 1; | 448 | s->fill_order = value - 1; |
| 443 | break; | 449 | break; |
| 444 | case TIFF_PAL: | 450 | case TIFF_PAL: |
| 445 | if(s->avctx->pix_fmt != PIX_FMT_PAL8){ | 451 | pal = (uint32_t *) s->palette; |
| 446 | av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n"); | ||
| 447 | return -1; | ||
| 448 | } | ||
| 449 | pal = (uint32_t *) s->picture.data[1]; | ||
| 450 | off = type_sizes[type]; | 452 | off = type_sizes[type]; |
| 451 | rp = buf; | 453 | rp = buf; |
| 452 | gp = buf + count / 3 * off; | 454 | gp = buf + count / 3 * off; |
| @@ -459,6 +461,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * · 6 unmodified lines | |||
| 459 | j |= tget(&bp, type, s->le) >> off; | 461 | j |= tget(&bp, type, s->le) >> off; |
| 460 | pal[i] = j; | 462 | pal[i] = j; |
| 461 | } | 463 | } |
| 464 | s->palette_is_set = 1; | ||
| 462 | break; | 465 | break; |
| 463 | case TIFF_PLANAR: | 466 | case TIFF_PLANAR: |
| 464 | if(value == 2){ | 467 | if(value == 2){ |
| @@ -287,13 +287,8 @@ zrmjpeg · 286 unmodified lines | |||
| 287 | CpuCaps gCpuCaps; //FIXME initialize this so optims work | 287 | CpuCaps gCpuCaps; //FIXME initialize this so optims work |
| 288 | 288 | ||
| 289 | 289 | ||
| 290 | //exact copy from vf_scale.c | ||
| 291 | int get_sws_cpuflags(void){ | 290 | int get_sws_cpuflags(void){ |
| 292 | return | 291 | return 0; |
| 293 | (gCpuCaps.hasMMX ? SWS_CPU_CAPS_MMX : 0) | ||
| 294 | | (gCpuCaps.hasMMX2 ? SWS_CPU_CAPS_MMX2 : 0) | ||
| 295 | | (gCpuCaps.has3DNow ? SWS_CPU_CAPS_3DNOW : 0) | ||
| 296 | | (gCpuCaps.hasAltiVec ? SWS_CPU_CAPS_ALTIVEC : 0); | ||
| 297 | } | 292 | } |
| 298 | 293 | ||
| 299 | static void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam) | 294 | static void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam) |
| @@ -348,7 +343,7 @@ struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, · 48 unmodified lines | |||
| 348 | if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = PIX_FMT_PAL8; | 343 | if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = PIX_FMT_PAL8; |
| 349 | sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam); | 344 | sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam); |
| 350 | 345 | ||
| 351 | return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags | get_sws_cpuflags(), srcFilterParam, dstFilterParam, NULL); | 346 | return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags , srcFilterParam, dstFilterParam, NULL); |
| 352 | } | 347 | } |
| 353 | 348 | ||
| 354 | typedef struct { | 349 | typedef struct { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | * memory buffer source API for video | 27 | * memory buffer source API for video |
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | |||
| 30 | #include "avfilter.h" | 31 | #include "avfilter.h" |
| 31 | 32 | ||
| 32 | /** | 33 | /** |
| @@ -276,7 +276,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) · 275 unmodified lines | |||
| 276 | ape->frames[0].nblocks = ape->blocksperframe; | 276 | ape->frames[0].nblocks = ape->blocksperframe; |
| 277 | ape->frames[0].skip = 0; | 277 | ape->frames[0].skip = 0; |
| 278 | for (i = 1; i < ape->totalframes; i++) { | 278 | for (i = 1; i < ape->totalframes; i++) { |
| 279 | ape->frames[i].pos = ape->seektable[i] + ape->junklength; //ape->frames[i-1].pos + ape->blocksperframe; | 279 | ape->frames[i].pos = ape->seektable[i] + ape->junklength; |
| 280 | ape->frames[i].nblocks = ape->blocksperframe; | 280 | ape->frames[i].nblocks = ape->blocksperframe; |
| 281 | ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; | 281 | ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; |
| 282 | ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; | 282 | ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #include "config.h" | 37 | #include "config.h" |
| 38 | #include "attributes.h" | 38 | #include "attributes.h" |
| 39 | #include "timer.h" | 39 | #include "timer.h" |
| 40 | #include "cpu.h" | ||
| 40 | 41 | ||
| 41 | #ifndef attribute_align_arg | 42 | #ifndef attribute_align_arg |
| 42 | #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2) | 43 | #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2) |
| @@ -222,4 +223,19 @@ · 179 unmodified lines | |||
| 222 | # define ONLY_IF_THREADS_ENABLED(x) NULL | 223 | # define ONLY_IF_THREADS_ENABLED(x) NULL |
| 223 | #endif | 224 | #endif |
| 224 | 225 | ||
| 226 | #if HAVE_MMX | ||
| 227 | /** | ||
| 228 | * Empty mmx state. | ||
| 229 | * this must be called between any dsp function and float/double code. | ||
| 230 | * for example sin(); dsp->idct_put(); emms_c(); cos() | ||
| 231 | */ | ||
| 232 | static av_always_inline void emms_c(void) | ||
| 233 | { | ||
| 234 | if(av_get_cpu_flags() & AV_CPU_FLAG_MMX) | ||
| 235 | __asm__ volatile ("emms" ::: "memory"); | ||
| 236 | } | ||
| 237 | #else /* HAVE_MMX */ | ||
| 238 | #define emms_c() | ||
| 239 | #endif /* HAVE_MMX */ | ||
| 240 | |||
| 225 | #endif /* AVUTIL_INTERNAL_H */ | 241 | #endif /* AVUTIL_INTERNAL_H */ |
| @@ -79,15 +79,13 @@ static int yuyvtoyv12_unscaled(SwsContext *c, uint8_t* src[], int srcStride[], i · 78 unmodified lines | |||
| 79 | void ff_bfin_get_unscaled_swscale(SwsContext *c) | 79 | void ff_bfin_get_unscaled_swscale(SwsContext *c) |
| 80 | { | 80 | { |
| 81 | SwsFunc swScale = c->swScale; | 81 | SwsFunc swScale = c->swScale; |
| 82 | if (c->flags & SWS_CPU_CAPS_BFIN) | 82 | |
| 83 | if (c->dstFormat == PIX_FMT_YUV420P) | 83 | if (c->dstFormat == PIX_FMT_YUV420P && c->srcFormat == PIX_FMT_UYVY422) { |
| 84 | if (c->srcFormat == PIX_FMT_UYVY422) { | 84 | av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized uyvytoyv12_unscaled\n"); |
| 85 | av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized uyvytoyv12_unscaled\n"); | 85 | c->swScale = uyvytoyv12_unscaled; |
| 86 | c->swScale = uyvytoyv12_unscaled; | 86 | } |
| 87 | } | 87 | if (c->dstFormat == PIX_FMT_YUV420P && c->srcFormat == PIX_FMT_YUYV422) { |
| 88 | if (c->dstFormat == PIX_FMT_YUV420P) | 88 | av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized yuyvtoyv12_unscaled\n"); |
| 89 | if (c->srcFormat == PIX_FMT_YUYV422) { | 89 | c->swScale = yuyvtoyv12_unscaled; |
| 90 | av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized yuyvtoyv12_unscaled\n"); | 90 | } |
| 91 | c->swScale = yuyvtoyv12_unscaled; | ||
| 92 | } | ||
| 93 | } | 91 | } |
| @@ -33,31 +33,6 @@ · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | #define FUNC(s,d,n) {s,d,#n,n} | 34 | #define FUNC(s,d,n) {s,d,#n,n} |
| 35 | 35 | ||
| 36 | static int cpu_caps; | ||
| 37 | |||
| 38 | static char *args_parse(int argc, char *argv[]) | ||
| 39 | { | ||
| 40 | int o; | ||
| 41 | |||
| 42 | while ((o = getopt(argc, argv, "m23")) != -1) { | ||
| 43 | switch (o) { | ||
| 44 | case 'm': | ||
| 45 | cpu_caps |= SWS_CPU_CAPS_MMX; | ||
| 46 | break; | ||
| 47 | case '2': | ||
| 48 | cpu_caps |= SWS_CPU_CAPS_MMX2; | ||
| 49 | break; | ||
| 50 | case '3': | ||
| 51 | cpu_caps |= SWS_CPU_CAPS_3DNOW; | ||
| 52 | break; | ||
| 53 | default: | ||
| 54 | av_log(NULL, AV_LOG_ERROR, "Unknown option %c\n", o); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | return argv[optind]; | ||
| 59 | } | ||
| 60 | |||
| 61 | int main(int argc, char **argv) | 36 | int main(int argc, char **argv) |
| 62 | { | 37 | { |
| 63 | int i, funcNum; | 38 | int i, funcNum; |
| @@ -70,9 +45,7 @@ int main(int argc, char **argv) · 6 unmodified lines | |||
| 70 | return -1; | 45 | return -1; |
| 71 | 46 | ||
| 72 | av_log(NULL, AV_LOG_INFO, "memory corruption test ...\n"); | 47 | av_log(NULL, AV_LOG_INFO, "memory corruption test ...\n"); |
| 73 | args_parse(argc, argv); | 48 | sws_rgb2rgb_init(); |
| 74 | av_log(NULL, AV_LOG_INFO, "CPU capabilities forced to %x\n", cpu_caps); | ||
| 75 | sws_rgb2rgb_init(cpu_caps); | ||
| 76 | 49 | ||
| 77 | for(funcNum=0; ; funcNum++) { | 50 | for(funcNum=0; ; funcNum++) { |
| 78 | struct func_info_s { | 51 | struct func_info_s { |
| @@ -48,12 +48,6 @@ static const AVOption options[] = { · 47 unmodified lines | |||
| 48 | { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_SPLINE }, INT_MIN, INT_MAX, VE, "sws_flags" }, | 48 | { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_SPLINE }, INT_MIN, INT_MAX, VE, "sws_flags" }, |
| 49 | { "print_info", "print info", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_PRINT_INFO }, INT_MIN, INT_MAX, VE, "sws_flags" }, | 49 | { "print_info", "print info", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_PRINT_INFO }, INT_MIN, INT_MAX, VE, "sws_flags" }, |
| 50 | { "accurate_rnd", "accurate rounding", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_ACCURATE_RND }, INT_MIN, INT_MAX, VE, "sws_flags" }, | 50 | { "accurate_rnd", "accurate rounding", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_ACCURATE_RND }, INT_MIN, INT_MAX, VE, "sws_flags" }, |
| 51 | { "mmx", "MMX SIMD acceleration", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_CPU_CAPS_MMX }, INT_MIN, INT_MAX, VE, "sws_flags" }, | ||
| 52 | { "mmx2", "MMX2 SIMD acceleration", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_CPU_CAPS_MMX2 }, INT_MIN, INT_MAX, VE, "sws_flags" }, | ||
| 53 | { "sse2", "SSE2 SIMD acceleration", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_CPU_CAPS_SSE2 }, INT_MIN, INT_MAX, VE, "sws_flags" }, | ||
| 54 | { "3dnow", "3DNOW SIMD acceleration", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_CPU_CAPS_3DNOW }, INT_MIN, INT_MAX, VE, "sws_flags" }, | ||
| 55 | { "altivec", "AltiVec SIMD acceleration", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_CPU_CAPS_ALTIVEC }, INT_MIN, INT_MAX, VE, "sws_flags" }, | ||
| 56 | { "bfin", "Blackfin SIMD acceleration", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_CPU_CAPS_BFIN }, INT_MIN, INT_MAX, VE, "sws_flags" }, | ||
| 57 | { "full_chroma_int", "full chroma interpolation", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INT }, INT_MIN, INT_MAX, VE, "sws_flags" }, | 51 | { "full_chroma_int", "full chroma interpolation", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INT }, INT_MIN, INT_MAX, VE, "sws_flags" }, |
| 58 | { "full_chroma_inp", "full chroma input", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INP }, INT_MIN, INT_MAX, VE, "sws_flags" }, | 52 | { "full_chroma_inp", "full chroma input", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INP }, INT_MIN, INT_MAX, VE, "sws_flags" }, |
| 59 | { "bitexact", "", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_BITEXACT }, INT_MIN, INT_MAX, VE, "sws_flags" }, | 53 | { "bitexact", "", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_BITEXACT }, INT_MIN, INT_MAX, VE, "sws_flags" }, |
| @@ -23,69 +23,16 @@ · 22 unmodified lines | |||
| 23 | #include "swscale_altivec_template.c" | 23 | #include "swscale_altivec_template.c" |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | #if COMPILE_TEMPLATE_ALTIVEC | ||
| 26 | static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, | 27 | static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, |
| 27 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc, | 28 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc, |
| 28 | uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW) | 29 | uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW) |
| 29 | { | 30 | { |
| 30 | #if COMPILE_TEMPLATE_ALTIVEC | ||
| 31 | yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize, | 31 | yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize, |
| 32 | chrFilter, chrSrc, chrFilterSize, | 32 | chrFilter, chrSrc, chrFilterSize, |
| 33 | dest, uDest, vDest, dstW, chrDstW); | 33 | dest, uDest, vDest, dstW, chrDstW); |
| 34 | #else //COMPILE_TEMPLATE_ALTIVEC | ||
| 35 | yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize, | ||
| 36 | chrFilter, chrSrc, chrFilterSize, | ||
| 37 | alpSrc, dest, uDest, vDest, aDest, dstW, chrDstW); | ||
| 38 | #endif //!COMPILE_TEMPLATE_ALTIVEC | ||
| 39 | } | ||
| 40 | |||
| 41 | static inline void RENAME(yuv2nv12X)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, | ||
| 42 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, | ||
| 43 | uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, enum PixelFormat dstFormat) | ||
| 44 | { | ||
| 45 | yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize, | ||
| 46 | chrFilter, chrSrc, chrFilterSize, | ||
| 47 | dest, uDest, dstW, chrDstW, dstFormat); | ||
| 48 | } | 34 | } |
| 49 | 35 | ||
| 50 | static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const int16_t *chrSrc, const int16_t *alpSrc, | ||
| 51 | uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW) | ||
| 52 | { | ||
| 53 | int i; | ||
| 54 | for (i=0; i<dstW; i++) { | ||
| 55 | int val= (lumSrc[i]+64)>>7; | ||
| 56 | |||
| 57 | if (val&256) { | ||
| 58 | if (val<0) val=0; | ||
| 59 | else val=255; | ||
| 60 | } | ||
| 61 | |||
| 62 | dest[i]= val; | ||
| 63 | } | ||
| 64 | |||
| 65 | if (uDest) | ||
| 66 | for (i=0; i<chrDstW; i++) { | ||
| 67 | int u=(chrSrc[i ]+64)>>7; | ||
| 68 | int v=(chrSrc[i + VOFW]+64)>>7; | ||
| 69 | |||
| 70 | if ((u|v)&256) { | ||
| 71 | if (u<0) u=0; | ||
| 72 | else if (u>255) u=255; | ||
| 73 | if (v<0) v=0; | ||
| 74 | else if (v>255) v=255; | ||
| 75 | } | ||
| 76 | |||
| 77 | uDest[i]= u; | ||
| 78 | vDest[i]= v; | ||
| 79 | } | ||
| 80 | |||
| 81 | if (CONFIG_SWSCALE_ALPHA && aDest) | ||
| 82 | for (i=0; i<dstW; i++) { | ||
| 83 | int val= (alpSrc[i]+64)>>7; | ||
| 84 | aDest[i]= av_clip_uint8(val); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | /** | 36 | /** |
| 90 | * vertical scale YV12 to RGB | 37 | * vertical scale YV12 to RGB |
| 91 | */ | 38 | */ |
| @@ -93,7 +40,6 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 1 unmodified line | |||
| 93 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, | 40 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, |
| 94 | const int16_t **alpSrc, uint8_t *dest, long dstW, long dstY) | 41 | const int16_t **alpSrc, uint8_t *dest, long dstW, long dstY) |
| 95 | { | 42 | { |
| 96 | #if COMPILE_TEMPLATE_ALTIVEC | ||
| 97 | /* The following list of supported dstFormat values should | 43 | /* The following list of supported dstFormat values should |
| 98 | match what's found in the body of ff_yuv2packedX_altivec() */ | 44 | match what's found in the body of ff_yuv2packedX_altivec() */ |
| 99 | if (!(c->flags & SWS_BITEXACT) && !c->alpPixBuf && | 45 | if (!(c->flags & SWS_BITEXACT) && !c->alpPixBuf && |
| @@ -104,815 +50,17 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 4 unmodified lines | |||
| 104 | chrFilter, chrSrc, chrFilterSize, | 50 | chrFilter, chrSrc, chrFilterSize, |
| 105 | dest, dstW, dstY); | 51 | dest, dstW, dstY); |
| 106 | else | 52 | else |
| 107 | #endif | ||
| 108 | yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize, | 53 | yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize, |
| 109 | chrFilter, chrSrc, chrFilterSize, | 54 | chrFilter, chrSrc, chrFilterSize, |
| 110 | alpSrc, dest, dstW, dstY); | 55 | alpSrc, dest, dstW, dstY); |
| 111 | } | 56 | } |
| 57 | #endif | ||
| 112 | 58 | ||
| 113 | /** | ||
| 114 | * vertical bilinear scale YV12 to RGB | ||
| 115 | */ | ||
| 116 | static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, const uint16_t *buf1, const uint16_t *uvbuf0, const uint16_t *uvbuf1, | ||
| 117 | const uint16_t *abuf0, const uint16_t *abuf1, uint8_t *dest, int dstW, int yalpha, int uvalpha, int y) | ||
| 118 | { | ||
| 119 | int yalpha1=4095- yalpha; | ||
| 120 | int uvalpha1=4095-uvalpha; | ||
| 121 | int i; | ||
| 122 | |||
| 123 | YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C(void,0), YSCALE_YUV_2_GRAY16_2_C, YSCALE_YUV_2_MONO2_C) | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * YV12 to RGB without scaling or interpolating | ||
| 128 | */ | ||
| 129 | static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, const uint16_t *uvbuf0, const uint16_t *uvbuf1, | ||
| 130 | const uint16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, enum PixelFormat dstFormat, int flags, int y) | ||
| 131 | { | ||
| 132 | const int yalpha1=0; | ||
| 133 | int i; | ||
| 134 | |||
| 135 | const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1 | ||
| 136 | const int yalpha= 4096; //FIXME ... | ||
| 137 | |||
| 138 | if (flags&SWS_FULL_CHR_H_INT) { | ||
| 139 | c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y); | ||
| 140 | return; | ||
| 141 | } | ||
| 142 | |||
| 143 | if (uvalpha < 2048) { | ||
| 144 | YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C, YSCALE_YUV_2_PACKED1_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C) | ||
| 145 | } else { | ||
| 146 | YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C, YSCALE_YUV_2_PACKED1B_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C) | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | //FIXME yuy2* can read up to 7 samples too much | ||
| 151 | |||
| 152 | static inline void RENAME(yuy2ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused) | ||
| 153 | { | ||
| 154 | int i; | ||
| 155 | for (i=0; i<width; i++) | ||
| 156 | dst[i]= src[2*i]; | ||
| 157 | } | ||
| 158 | |||
| 159 | static inline void RENAME(yuy2ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 160 | { | ||
| 161 | int i; | ||
| 162 | for (i=0; i<width; i++) { | ||
| 163 | dstU[i]= src1[4*i + 1]; | ||
| 164 | dstV[i]= src1[4*i + 3]; | ||
| 165 | } | ||
| 166 | assert(src1 == src2); | ||
| 167 | } | ||
| 168 | |||
| 169 | static inline void RENAME(LEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 170 | { | ||
| 171 | int i; | ||
| 172 | for (i=0; i<width; i++) { | ||
| 173 | dstU[i]= src1[2*i + 1]; | ||
| 174 | dstV[i]= src2[2*i + 1]; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | /* This is almost identical to the previous, end exists only because | ||
| 179 | * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */ | ||
| 180 | static inline void RENAME(uyvyToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused) | ||
| 181 | { | ||
| 182 | int i; | ||
| 183 | for (i=0; i<width; i++) | ||
| 184 | dst[i]= src[2*i+1]; | ||
| 185 | } | ||
| 186 | |||
| 187 | static inline void RENAME(uyvyToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 188 | { | ||
| 189 | int i; | ||
| 190 | for (i=0; i<width; i++) { | ||
| 191 | dstU[i]= src1[4*i + 0]; | ||
| 192 | dstV[i]= src1[4*i + 2]; | ||
| 193 | } | ||
| 194 | assert(src1 == src2); | ||
| 195 | } | ||
| 196 | |||
| 197 | static inline void RENAME(BEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 198 | { | ||
| 199 | int i; | ||
| 200 | for (i=0; i<width; i++) { | ||
| 201 | dstU[i]= src1[2*i]; | ||
| 202 | dstV[i]= src2[2*i]; | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | static inline void RENAME(nvXXtoUV)(uint8_t *dst1, uint8_t *dst2, | ||
| 207 | const uint8_t *src, long width) | ||
| 208 | { | ||
| 209 | int i; | ||
| 210 | for (i = 0; i < width; i++) { | ||
| 211 | dst1[i] = src[2*i+0]; | ||
| 212 | dst2[i] = src[2*i+1]; | ||
| 213 | } | ||
| 214 | } | ||
| 215 | |||
| 216 | static inline void RENAME(nv12ToUV)(uint8_t *dstU, uint8_t *dstV, | ||
| 217 | const uint8_t *src1, const uint8_t *src2, | ||
| 218 | long width, uint32_t *unused) | ||
| 219 | { | ||
| 220 | RENAME(nvXXtoUV)(dstU, dstV, src1, width); | ||
| 221 | } | ||
| 222 | |||
| 223 | static inline void RENAME(nv21ToUV)(uint8_t *dstU, uint8_t *dstV, | ||
| 224 | const uint8_t *src1, const uint8_t *src2, | ||
| 225 | long width, uint32_t *unused) | ||
| 226 | { | ||
| 227 | RENAME(nvXXtoUV)(dstV, dstU, src1, width); | ||
| 228 | } | ||
| 229 | |||
| 230 | |||
| 231 | static inline void RENAME(bgr24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused) | ||
| 232 | { | ||
| 233 | int i; | ||
| 234 | for (i=0; i<width; i++) { | ||
| 235 | int b= src[i*3+0]; | ||
| 236 | int g= src[i*3+1]; | ||
| 237 | int r= src[i*3+2]; | ||
| 238 | |||
| 239 | dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | static inline void RENAME(bgr24ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 244 | { | ||
| 245 | int i; | ||
| 246 | for (i=0; i<width; i++) { | ||
| 247 | int b= src1[3*i + 0]; | ||
| 248 | int g= src1[3*i + 1]; | ||
| 249 | int r= src1[3*i + 2]; | ||
| 250 | |||
| 251 | dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT; | ||
| 252 | dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT; | ||
| 253 | } | ||
| 254 | assert(src1 == src2); | ||
| 255 | } | ||
| 256 | |||
| 257 | static inline void RENAME(bgr24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 258 | { | ||
| 259 | int i; | ||
| 260 | for (i=0; i<width; i++) { | ||
| 261 | int b= src1[6*i + 0] + src1[6*i + 3]; | ||
| 262 | int g= src1[6*i + 1] + src1[6*i + 4]; | ||
| 263 | int r= src1[6*i + 2] + src1[6*i + 5]; | ||
| 264 | |||
| 265 | dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1); | ||
| 266 | dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1); | ||
| 267 | } | ||
| 268 | assert(src1 == src2); | ||
| 269 | } | ||
| 270 | |||
| 271 | static inline void RENAME(rgb24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused) | ||
| 272 | { | ||
| 273 | int i; | ||
| 274 | for (i=0; i<width; i++) { | ||
| 275 | int r= src[i*3+0]; | ||
| 276 | int g= src[i*3+1]; | ||
| 277 | int b= src[i*3+2]; | ||
| 278 | |||
| 279 | dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT); | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | static inline void RENAME(rgb24ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 284 | { | ||
| 285 | int i; | ||
| 286 | assert(src1==src2); | ||
| 287 | for (i=0; i<width; i++) { | ||
| 288 | int r= src1[3*i + 0]; | ||
| 289 | int g= src1[3*i + 1]; | ||
| 290 | int b= src1[3*i + 2]; | ||
| 291 | |||
| 292 | dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT; | ||
| 293 | dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | static inline void RENAME(rgb24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 298 | { | ||
| 299 | int i; | ||
| 300 | assert(src1==src2); | ||
| 301 | for (i=0; i<width; i++) { | ||
| 302 | int r= src1[6*i + 0] + src1[6*i + 3]; | ||
| 303 | int g= src1[6*i + 1] + src1[6*i + 4]; | ||
| 304 | int b= src1[6*i + 2] + src1[6*i + 5]; | ||
| 305 | |||
| 306 | dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1); | ||
| 307 | dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1); | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | |||
| 312 | // bilinear / bicubic scaling | ||
| 313 | static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW, int xInc, | ||
| 314 | const int16_t *filter, const int16_t *filterPos, long filterSize) | ||
| 315 | { | ||
| 316 | #if COMPILE_TEMPLATE_ALTIVEC | ||
| 317 | hScale_altivec_real(dst, dstW, src, srcW, xInc, filter, filterPos, filterSize); | ||
| 318 | #else | ||
| 319 | int i; | ||
| 320 | for (i=0; i<dstW; i++) { | ||
| 321 | int j; | ||
| 322 | int srcPos= filterPos[i]; | ||
| 323 | int val=0; | ||
| 324 | //printf("filterPos: %d\n", filterPos[i]); | ||
| 325 | for (j=0; j<filterSize; j++) { | ||
| 326 | //printf("filter: %d, src: %d\n", filter[i], src[srcPos + j]); | ||
| 327 | val += ((int)src[srcPos + j])*filter[filterSize*i + j]; | ||
| 328 | } | ||
| 329 | //filter += hFilterSize; | ||
| 330 | dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ... | ||
| 331 | //dst[i] = val>>7; | ||
| 332 | } | ||
| 333 | #endif /* COMPILE_TEMPLATE_ALTIVEC */ | ||
| 334 | } | ||
| 335 | |||
| 336 | //FIXME all pal and rgb srcFormats could do this convertion as well | ||
| 337 | //FIXME all scalers more complex than bilinear could do half of this transform | ||
| 338 | static void RENAME(chrRangeToJpeg)(uint16_t *dst, int width) | ||
| 339 | { | ||
| 340 | int i; | ||
| 341 | for (i = 0; i < width; i++) { | ||
| 342 | dst[i ] = (FFMIN(dst[i ],30775)*4663 - 9289992)>>12; //-264 | ||
| 343 | dst[i+VOFW] = (FFMIN(dst[i+VOFW],30775)*4663 - 9289992)>>12; //-264 | ||
| 344 | } | ||
| 345 | } | ||
| 346 | static void RENAME(chrRangeFromJpeg)(uint16_t *dst, int width) | ||
| 347 | { | ||
| 348 | int i; | ||
| 349 | for (i = 0; i < width; i++) { | ||
| 350 | dst[i ] = (dst[i ]*1799 + 4081085)>>11; //1469 | ||
| 351 | dst[i+VOFW] = (dst[i+VOFW]*1799 + 4081085)>>11; //1469 | ||
| 352 | } | ||
| 353 | } | ||
| 354 | static void RENAME(lumRangeToJpeg)(uint16_t *dst, int width) | ||
| 355 | { | ||
| 356 | int i; | ||
| 357 | for (i = 0; i < width; i++) | ||
| 358 | dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14; | ||
| 359 | } | ||
| 360 | static void RENAME(lumRangeFromJpeg)(uint16_t *dst, int width) | ||
| 361 | { | ||
| 362 | int i; | ||
| 363 | for (i = 0; i < width; i++) | ||
| 364 | dst[i] = (dst[i]*14071 + 33561947)>>14; | ||
| 365 | } | ||
| 366 | |||
| 367 | static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, | ||
| 368 | long dstWidth, const uint8_t *src, int srcW, | ||
| 369 | int xInc) | ||
| 370 | { | ||
| 371 | int i; | ||
| 372 | unsigned int xpos=0; | ||
| 373 | for (i=0;i<dstWidth;i++) { | ||
| 374 | register unsigned int xx=xpos>>16; | ||
| 375 | register unsigned int xalpha=(xpos&0xFFFF)>>9; | ||
| 376 | dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha; | ||
| 377 | xpos+=xInc; | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | // *** horizontal scale Y line to temp buffer | ||
| 382 | static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src, int srcW, int xInc, | ||
| 383 | const int16_t *hLumFilter, | ||
| 384 | const int16_t *hLumFilterPos, int hLumFilterSize, | ||
| 385 | uint8_t *formatConvBuffer, | ||
| 386 | uint32_t *pal, int isAlpha) | ||
| 387 | { | ||
| 388 | void (*toYV12)(uint8_t *, const uint8_t *, long, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12; | ||
| 389 | void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange; | ||
| 390 | |||
| 391 | src += isAlpha ? c->alpSrcOffset : c->lumSrcOffset; | ||
| 392 | |||
| 393 | if (toYV12) { | ||
| 394 | toYV12(formatConvBuffer, src, srcW, pal); | ||
| 395 | src= formatConvBuffer; | ||
| 396 | } | ||
| 397 | |||
| 398 | if (c->hScale16) { | ||
| 399 | c->hScale16(dst, dstWidth, (uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1); | ||
| 400 | } else if (!c->hyscale_fast) { | ||
| 401 | c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize); | ||
| 402 | } else { // fast bilinear upscale / crap downscale | ||
| 403 | c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc); | ||
| 404 | } | ||
| 405 | |||
| 406 | if (convertRange) | ||
| 407 | convertRange(dst, dstWidth); | ||
| 408 | } | ||
| 409 | |||
| 410 | static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, | ||
| 411 | long dstWidth, const uint8_t *src1, | ||
| 412 | const uint8_t *src2, int srcW, int xInc) | ||
| 413 | { | ||
| 414 | int i; | ||
| 415 | unsigned int xpos=0; | ||
| 416 | for (i=0;i<dstWidth;i++) { | ||
| 417 | register unsigned int xx=xpos>>16; | ||
| 418 | register unsigned int xalpha=(xpos&0xFFFF)>>9; | ||
| 419 | dst[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha); | ||
| 420 | dst[i+VOFW]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha); | ||
| 421 | /* slower | ||
| 422 | dst[i]= (src1[xx]<<7) + (src1[xx+1] - src1[xx])*xalpha; | ||
| 423 | dst[i+VOFW]=(src2[xx]<<7) + (src2[xx+1] - src2[xx])*xalpha; | ||
| 424 | */ | ||
| 425 | xpos+=xInc; | ||
| 426 | } | ||
| 427 | } | ||
| 428 | |||
| 429 | inline static void RENAME(hcscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src1, const uint8_t *src2, | ||
| 430 | int srcW, int xInc, const int16_t *hChrFilter, | ||
| 431 | const int16_t *hChrFilterPos, int hChrFilterSize, | ||
| 432 | uint8_t *formatConvBuffer, | ||
| 433 | uint32_t *pal) | ||
| 434 | { | ||
| 435 | |||
| 436 | src1 += c->chrSrcOffset; | ||
| 437 | src2 += c->chrSrcOffset; | ||
| 438 | |||
| 439 | if (c->chrToYV12) { | ||
| 440 | c->chrToYV12(formatConvBuffer, formatConvBuffer+VOFW, src1, src2, srcW, pal); | ||
| 441 | src1= formatConvBuffer; | ||
| 442 | src2= formatConvBuffer+VOFW; | ||
| 443 | } | ||
| 444 | |||
| 445 | if (c->hScale16) { | ||
| 446 | c->hScale16(dst , dstWidth, (uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1); | ||
| 447 | c->hScale16(dst+VOFW, dstWidth, (uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1); | ||
| 448 | } else if (!c->hcscale_fast) { | ||
| 449 | c->hScale(dst , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize); | ||
| 450 | c->hScale(dst+VOFW, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize); | ||
| 451 | } else { // fast bilinear upscale / crap downscale | ||
| 452 | c->hcscale_fast(c, dst, dstWidth, src1, src2, srcW, xInc); | ||
| 453 | } | ||
| 454 | |||
| 455 | if (c->chrConvertRange) | ||
| 456 | c->chrConvertRange(dst, dstWidth); | ||
| 457 | } | ||
| 458 | |||
| 459 | #define DEBUG_SWSCALE_BUFFERS 0 | ||
| 460 | #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__) | ||
| 461 | |||
| 462 | static int RENAME(swScale)(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | ||
| 463 | int srcSliceH, uint8_t* dst[], int dstStride[]) | ||
| 464 | { | ||
| 465 | /* load a few things into local vars to make the code more readable? and faster */ | ||
| 466 | const int srcW= c->srcW; | ||
| 467 | const int dstW= c->dstW; | ||
| 468 | const int dstH= c->dstH; | ||
| 469 | const int chrDstW= c->chrDstW; | ||
| 470 | const int chrSrcW= c->chrSrcW; | ||
| 471 | const int lumXInc= c->lumXInc; | ||
| 472 | const int chrXInc= c->chrXInc; | ||
| 473 | const enum PixelFormat dstFormat= c->dstFormat; | ||
| 474 | const int flags= c->flags; | ||
| 475 | int16_t *vLumFilterPos= c->vLumFilterPos; | ||
| 476 | int16_t *vChrFilterPos= c->vChrFilterPos; | ||
| 477 | int16_t *hLumFilterPos= c->hLumFilterPos; | ||
| 478 | int16_t *hChrFilterPos= c->hChrFilterPos; | ||
| 479 | int16_t *vLumFilter= c->vLumFilter; | ||
| 480 | int16_t *vChrFilter= c->vChrFilter; | ||
| 481 | int16_t *hLumFilter= c->hLumFilter; | ||
| 482 | int16_t *hChrFilter= c->hChrFilter; | ||
| 483 | int32_t *lumMmxFilter= c->lumMmxFilter; | ||
| 484 | int32_t *chrMmxFilter= c->chrMmxFilter; | ||
| 485 | int32_t av_unused *alpMmxFilter= c->alpMmxFilter; | ||
| 486 | const int vLumFilterSize= c->vLumFilterSize; | ||
| 487 | const int vChrFilterSize= c->vChrFilterSize; | ||
| 488 | const int hLumFilterSize= c->hLumFilterSize; | ||
| 489 | const int hChrFilterSize= c->hChrFilterSize; | ||
| 490 | int16_t **lumPixBuf= c->lumPixBuf; | ||
| 491 | int16_t **chrPixBuf= c->chrPixBuf; | ||
| 492 | int16_t **alpPixBuf= c->alpPixBuf; | ||
| 493 | const int vLumBufSize= c->vLumBufSize; | ||
| 494 | const int vChrBufSize= c->vChrBufSize; | ||
| 495 | uint8_t *formatConvBuffer= c->formatConvBuffer; | ||
| 496 | const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample; | ||
| 497 | const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample); | ||
| 498 | int lastDstY; | ||
| 499 | uint32_t *pal=c->pal_yuv; | ||
| 500 | |||
| 501 | /* vars which will change and which we need to store back in the context */ | ||
| 502 | int dstY= c->dstY; | ||
| 503 | int lumBufIndex= c->lumBufIndex; | ||
| 504 | int chrBufIndex= c->chrBufIndex; | ||
| 505 | int lastInLumBuf= c->lastInLumBuf; | ||
| 506 | int lastInChrBuf= c->lastInChrBuf; | ||
| 507 | |||
| 508 | if (isPacked(c->srcFormat)) { | ||
| 509 | src[0]= | ||
| 510 | src[1]= | ||
| 511 | src[2]= | ||
| 512 | src[3]= src[0]; | ||
| 513 | srcStride[0]= | ||
| 514 | srcStride[1]= | ||
| 515 | srcStride[2]= | ||
| 516 | srcStride[3]= srcStride[0]; | ||
| 517 | } | ||
| 518 | srcStride[1]<<= c->vChrDrop; | ||
| 519 | srcStride[2]<<= c->vChrDrop; | ||
| 520 | |||
| 521 | DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n", | ||
| 522 | src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3], | ||
| 523 | dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]); | ||
| 524 | DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n", | ||
| 525 | srcSliceY, srcSliceH, dstY, dstH); | ||
| 526 | DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n", | ||
| 527 | vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize); | ||
| 528 | |||
| 529 | if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) { | ||
| 530 | static int warnedAlready=0; //FIXME move this into the context perhaps | ||
| 531 | if (flags & SWS_PRINT_INFO && !warnedAlready) { | ||
| 532 | av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n" | ||
| 533 | " ->cannot do aligned memory accesses anymore\n"); | ||
| 534 | warnedAlready=1; | ||
| 535 | } | ||
| 536 | } | ||
| 537 | |||
| 538 | /* Note the user might start scaling the picture in the middle so this | ||
| 539 | will not get executed. This is not really intended but works | ||
| 540 | currently, so people might do it. */ | ||
| 541 | if (srcSliceY ==0) { | ||
| 542 | lumBufIndex=-1; | ||
| 543 | chrBufIndex=-1; | ||
| 544 | dstY=0; | ||
| 545 | lastInLumBuf= -1; | ||
| 546 | lastInChrBuf= -1; | ||
| 547 | } | ||
| 548 | |||
| 549 | lastDstY= dstY; | ||
| 550 | |||
| 551 | for (;dstY < dstH; dstY++) { | ||
| 552 | unsigned char *dest =dst[0]+dstStride[0]*dstY; | ||
| 553 | const int chrDstY= dstY>>c->chrDstVSubSample; | ||
| 554 | unsigned char *uDest=dst[1]+dstStride[1]*chrDstY; | ||
| 555 | unsigned char *vDest=dst[2]+dstStride[2]*chrDstY; | ||
| 556 | unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL; | ||
| 557 | |||
| 558 | const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input | ||
| 559 | const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)]; | ||
| 560 | const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input | ||
| 561 | int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input | ||
| 562 | int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input | ||
| 563 | int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input | ||
| 564 | int enough_lines; | ||
| 565 | |||
| 566 | //handle holes (FAST_BILINEAR & weird filters) | ||
| 567 | if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1; | ||
| 568 | if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1; | ||
| 569 | assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1); | ||
| 570 | assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1); | ||
| 571 | |||
| 572 | DEBUG_BUFFERS("dstY: %d\n", dstY); | ||
| 573 | DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n", | ||
| 574 | firstLumSrcY, lastLumSrcY, lastInLumBuf); | ||
| 575 | DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n", | ||
| 576 | firstChrSrcY, lastChrSrcY, lastInChrBuf); | ||
| 577 | |||
| 578 | // Do we have enough lines in this slice to output the dstY line | ||
| 579 | enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample); | ||
| 580 | |||
| 581 | if (!enough_lines) { | ||
| 582 | lastLumSrcY = srcSliceY + srcSliceH - 1; | ||
| 583 | lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1; | ||
| 584 | DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n", | ||
| 585 | lastLumSrcY, lastChrSrcY); | ||
| 586 | } | ||
| 587 | |||
| 588 | //Do horizontal scaling | ||
| 589 | while(lastInLumBuf < lastLumSrcY) { | ||
| 590 | const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0]; | ||
| 591 | const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3]; | ||
| 592 | lumBufIndex++; | ||
| 593 | assert(lumBufIndex < 2*vLumBufSize); | ||
| 594 | assert(lastInLumBuf + 1 - srcSliceY < srcSliceH); | ||
| 595 | assert(lastInLumBuf + 1 - srcSliceY >= 0); | ||
| 596 | RENAME(hyscale)(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc, | ||
| 597 | hLumFilter, hLumFilterPos, hLumFilterSize, | ||
| 598 | formatConvBuffer, | ||
| 599 | pal, 0); | ||
| 600 | if (CONFIG_SWSCALE_ALPHA && alpPixBuf) | ||
| 601 | RENAME(hyscale)(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW, lumXInc, | ||
| 602 | hLumFilter, hLumFilterPos, hLumFilterSize, | ||
| 603 | formatConvBuffer, | ||
| 604 | pal, 1); | ||
| 605 | lastInLumBuf++; | ||
| 606 | DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n", | ||
| 607 | lumBufIndex, lastInLumBuf); | ||
| 608 | } | ||
| 609 | while(lastInChrBuf < lastChrSrcY) { | ||
| 610 | const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1]; | ||
| 611 | const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2]; | ||
| 612 | chrBufIndex++; | ||
| 613 | assert(chrBufIndex < 2*vChrBufSize); | ||
| 614 | assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH)); | ||
| 615 | assert(lastInChrBuf + 1 - chrSrcSliceY >= 0); | ||
| 616 | //FIXME replace parameters through context struct (some at least) | ||
| 617 | |||
| 618 | if (c->needs_hcscale) | ||
| 619 | RENAME(hcscale)(c, chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc, | ||
| 620 | hChrFilter, hChrFilterPos, hChrFilterSize, | ||
| 621 | formatConvBuffer, | ||
| 622 | pal); | ||
| 623 | lastInChrBuf++; | ||
| 624 | DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n", | ||
| 625 | chrBufIndex, lastInChrBuf); | ||
| 626 | } | ||
| 627 | //wrap buf index around to stay inside the ring buffer | ||
| 628 | if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize; | ||
| 629 | if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize; | ||
| 630 | if (!enough_lines) | ||
| 631 | break; //we can't output a dstY line so let's try with the next slice | ||
| 632 | |||
| 633 | if (dstY < dstH-2) { | ||
| 634 | const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; | ||
| 635 | const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; | ||
| 636 | const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; | ||
| 637 | if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) { | ||
| 638 | const int chrSkipMask= (1<<c->chrDstVSubSample)-1; | ||
| 639 | if (dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi | ||
| 640 | c->yuv2nv12X(c, | ||
| 641 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 642 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 643 | dest, uDest, dstW, chrDstW, dstFormat); | ||
| 644 | } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like | ||
| 645 | const int chrSkipMask= (1<<c->chrDstVSubSample)-1; | ||
| 646 | if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi | ||
| 647 | if (is16BPS(dstFormat) || isNBPS(dstFormat)) { | ||
| 648 | yuv2yuvX16inC( | ||
| 649 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 650 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 651 | alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW, | ||
| 652 | dstFormat); | ||
| 653 | } else if (vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12 | ||
| 654 | const int16_t *lumBuf = lumSrcPtr[0]; | ||
| 655 | const int16_t *chrBuf= chrSrcPtr[0]; | ||
| 656 | const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL; | ||
| 657 | c->yuv2yuv1(c, lumBuf, chrBuf, alpBuf, dest, uDest, vDest, aDest, dstW, chrDstW); | ||
| 658 | } else { //General YV12 | ||
| 659 | c->yuv2yuvX(c, | ||
| 660 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 661 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 662 | alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW); | ||
| 663 | } | ||
| 664 | } else { | ||
| 665 | assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); | ||
| 666 | assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); | ||
| 667 | if (vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB | ||
| 668 | int chrAlpha= vChrFilter[2*dstY+1]; | ||
| 669 | if(flags & SWS_FULL_CHR_H_INT) { | ||
| 670 | yuv2rgbXinC_full(c, //FIXME write a packed1_full function | ||
| 671 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 672 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 673 | alpSrcPtr, dest, dstW, dstY); | ||
| 674 | } else { | ||
| 675 | c->yuv2packed1(c, *lumSrcPtr, *chrSrcPtr, *(chrSrcPtr+1), | ||
| 676 | alpPixBuf ? *alpSrcPtr : NULL, | ||
| 677 | dest, dstW, chrAlpha, dstFormat, flags, dstY); | ||
| 678 | } | ||
| 679 | } else if (vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB | ||
| 680 | int lumAlpha= vLumFilter[2*dstY+1]; | ||
| 681 | int chrAlpha= vChrFilter[2*dstY+1]; | ||
| 682 | lumMmxFilter[2]= | ||
| 683 | lumMmxFilter[3]= vLumFilter[2*dstY ]*0x10001; | ||
| 684 | chrMmxFilter[2]= | ||
| 685 | chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001; | ||
| 686 | if(flags & SWS_FULL_CHR_H_INT) { | ||
| 687 | yuv2rgbXinC_full(c, //FIXME write a packed2_full function | ||
| 688 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 689 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 690 | alpSrcPtr, dest, dstW, dstY); | ||
| 691 | } else { | ||
| 692 | c->yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrSrcPtr, *(chrSrcPtr+1), | ||
| 693 | alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL, | ||
| 694 | dest, dstW, lumAlpha, chrAlpha, dstY); | ||
| 695 | } | ||
| 696 | } else { //general RGB | ||
| 697 | if(flags & SWS_FULL_CHR_H_INT) { | ||
| 698 | yuv2rgbXinC_full(c, | ||
| 699 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 700 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 701 | alpSrcPtr, dest, dstW, dstY); | ||
| 702 | } else { | ||
| 703 | c->yuv2packedX(c, | ||
| 704 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 705 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 706 | alpSrcPtr, dest, dstW, dstY); | ||
| 707 | } | ||
| 708 | } | ||
| 709 | } | ||
| 710 | } else { // hmm looks like we can't use MMX here without overwriting this array's tail | ||
| 711 | const int16_t **lumSrcPtr= (const int16_t **)lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; | ||
| 712 | const int16_t **chrSrcPtr= (const int16_t **)chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; | ||
| 713 | const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **)alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; | ||
| 714 | if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) { | ||
| 715 | const int chrSkipMask= (1<<c->chrDstVSubSample)-1; | ||
| 716 | if (dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi | ||
| 717 | yuv2nv12XinC( | ||
| 718 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 719 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 720 | dest, uDest, dstW, chrDstW, dstFormat); | ||
| 721 | } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 | ||
| 722 | const int chrSkipMask= (1<<c->chrDstVSubSample)-1; | ||
| 723 | if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi | ||
| 724 | if (is16BPS(dstFormat) || isNBPS(dstFormat)) { | ||
| 725 | yuv2yuvX16inC( | ||
| 726 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 727 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 728 | alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW, | ||
| 729 | dstFormat); | ||
| 730 | } else { | ||
| 731 | yuv2yuvXinC( | ||
| 732 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 733 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 734 | alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW); | ||
| 735 | } | ||
| 736 | } else { | ||
| 737 | assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); | ||
| 738 | assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); | ||
| 739 | if(flags & SWS_FULL_CHR_H_INT) { | ||
| 740 | yuv2rgbXinC_full(c, | ||
| 741 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 742 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 743 | alpSrcPtr, dest, dstW, dstY); | ||
| 744 | } else { | ||
| 745 | yuv2packedXinC(c, | ||
| 746 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 747 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 748 | alpSrcPtr, dest, dstW, dstY); | ||
| 749 | } | ||
| 750 | } | ||
| 751 | } | ||
| 752 | } | ||
| 753 | |||
| 754 | if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf) | ||
| 755 | fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255); | ||
| 756 | |||
| 757 | /* store changed local vars back in the context */ | ||
| 758 | c->dstY= dstY; | ||
| 759 | c->lumBufIndex= lumBufIndex; | ||
| 760 | c->chrBufIndex= chrBufIndex; | ||
| 761 | c->lastInLumBuf= lastInLumBuf; | ||
| 762 | c->lastInChrBuf= lastInChrBuf; | ||
| 763 | |||
| 764 | return dstY - lastDstY; | ||
| 765 | } | ||
| 766 | 59 | ||
| 767 | static void RENAME(sws_init_swScale)(SwsContext *c) | 60 | static void RENAME(sws_init_swScale)(SwsContext *c) |
| 768 | { | 61 | { |
| 769 | enum PixelFormat srcFormat = c->srcFormat; | 62 | enum PixelFormat srcFormat = c->srcFormat; |
| 770 | 63 | ||
| 771 | c->yuv2nv12X = RENAME(yuv2nv12X ); | ||
| 772 | c->yuv2yuv1 = RENAME(yuv2yuv1 ); | ||
| 773 | c->yuv2yuvX = RENAME(yuv2yuvX ); | 64 | c->yuv2yuvX = RENAME(yuv2yuvX ); |
| 774 | c->yuv2packed1 = RENAME(yuv2packed1 ); | ||
| 775 | c->yuv2packed2 = RENAME(yuv2packed2 ); | ||
| 776 | c->yuv2packedX = RENAME(yuv2packedX ); | 65 | c->yuv2packedX = RENAME(yuv2packedX ); |
| 777 | |||
| 778 | c->hScale = RENAME(hScale ); | ||
| 779 | |||
| 780 | if (c->flags & SWS_FAST_BILINEAR) | ||
| 781 | { | ||
| 782 | c->hyscale_fast = RENAME(hyscale_fast); | ||
| 783 | c->hcscale_fast = RENAME(hcscale_fast); | ||
| 784 | } | ||
| 785 | |||
| 786 | c->chrToYV12 = NULL; | ||
| 787 | switch(srcFormat) { | ||
| 788 | case PIX_FMT_YUYV422 : c->chrToYV12 = RENAME(yuy2ToUV); break; | ||
| 789 | case PIX_FMT_UYVY422 : c->chrToYV12 = RENAME(uyvyToUV); break; | ||
| 790 | case PIX_FMT_NV12 : c->chrToYV12 = RENAME(nv12ToUV); break; | ||
| 791 | case PIX_FMT_NV21 : c->chrToYV12 = RENAME(nv21ToUV); break; | ||
| 792 | case PIX_FMT_RGB8 : | ||
| 793 | case PIX_FMT_BGR8 : | ||
| 794 | case PIX_FMT_PAL8 : | ||
| 795 | case PIX_FMT_BGR4_BYTE: | ||
| 796 | case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV; break; | ||
| 797 | case PIX_FMT_GRAY16BE : | ||
| 798 | case PIX_FMT_YUV420P9BE: | ||
| 799 | case PIX_FMT_YUV422P10BE: | ||
| 800 | case PIX_FMT_YUV420P10BE: | ||
| 801 | case PIX_FMT_YUV420P16BE: | ||
| 802 | case PIX_FMT_YUV422P16BE: | ||
| 803 | case PIX_FMT_YUV444P16BE: c->hScale16= HAVE_BIGENDIAN ? RENAME(hScale16) : RENAME(hScale16X); break; | ||
| 804 | case PIX_FMT_GRAY16LE : | ||
| 805 | case PIX_FMT_YUV420P9LE: | ||
| 806 | case PIX_FMT_YUV422P10LE: | ||
| 807 | case PIX_FMT_YUV420P10LE: | ||
| 808 | case PIX_FMT_YUV420P16LE: | ||
| 809 | case PIX_FMT_YUV422P16LE: | ||
| 810 | case PIX_FMT_YUV444P16LE: c->hScale16= HAVE_BIGENDIAN ? RENAME(hScale16X) : RENAME(hScale16); break; | ||
| 811 | } | ||
| 812 | if (c->chrSrcHSubSample) { | ||
| 813 | switch(srcFormat) { | ||
| 814 | case PIX_FMT_RGB48BE: | ||
| 815 | case PIX_FMT_RGB48LE: c->chrToYV12 = rgb48ToUV_half; break; | ||
| 816 | case PIX_FMT_BGR48BE: | ||
| 817 | case PIX_FMT_BGR48LE: c->chrToYV12 = bgr48ToUV_half; break; | ||
| 818 | case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV_half; break; | ||
| 819 | case PIX_FMT_RGB32_1: c->chrToYV12 = bgr321ToUV_half; break; | ||
| 820 | case PIX_FMT_BGR24 : c->chrToYV12 = RENAME(bgr24ToUV_half); break; | ||
| 821 | case PIX_FMT_BGR565 : c->chrToYV12 = bgr16ToUV_half; break; | ||
| 822 | case PIX_FMT_BGR555 : c->chrToYV12 = bgr15ToUV_half; break; | ||
| 823 | case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV_half; break; | ||
| 824 | case PIX_FMT_BGR32_1: c->chrToYV12 = rgb321ToUV_half; break; | ||
| 825 | case PIX_FMT_RGB24 : c->chrToYV12 = RENAME(rgb24ToUV_half); break; | ||
| 826 | case PIX_FMT_RGB565 : c->chrToYV12 = rgb16ToUV_half; break; | ||
| 827 | case PIX_FMT_RGB555 : c->chrToYV12 = rgb15ToUV_half; break; | ||
| 828 | } | ||
| 829 | } else { | ||
| 830 | switch(srcFormat) { | ||
| 831 | case PIX_FMT_RGB48BE: | ||
| 832 | case PIX_FMT_RGB48LE: c->chrToYV12 = rgb48ToUV; break; | ||
| 833 | case PIX_FMT_BGR48BE: | ||
| 834 | case PIX_FMT_BGR48LE: c->chrToYV12 = bgr48ToUV; break; | ||
| 835 | case PIX_FMT_RGB32 : c->chrToYV12 = bgr32ToUV; break; | ||
| 836 | case PIX_FMT_RGB32_1: c->chrToYV12 = bgr321ToUV; break; | ||
| 837 | case PIX_FMT_BGR24 : c->chrToYV12 = RENAME(bgr24ToUV); break; | ||
| 838 | case PIX_FMT_BGR565 : c->chrToYV12 = bgr16ToUV; break; | ||
| 839 | case PIX_FMT_BGR555 : c->chrToYV12 = bgr15ToUV; break; | ||
| 840 | case PIX_FMT_BGR32 : c->chrToYV12 = rgb32ToUV; break; | ||
| 841 | case PIX_FMT_BGR32_1: c->chrToYV12 = rgb321ToUV; break; | ||
| 842 | case PIX_FMT_RGB24 : c->chrToYV12 = RENAME(rgb24ToUV); break; | ||
| 843 | case PIX_FMT_RGB565 : c->chrToYV12 = rgb16ToUV; break; | ||
| 844 | case PIX_FMT_RGB555 : c->chrToYV12 = rgb15ToUV; break; | ||
| 845 | } | ||
| 846 | } | ||
| 847 | |||
| 848 | c->lumToYV12 = NULL; | ||
| 849 | c->alpToYV12 = NULL; | ||
| 850 | switch (srcFormat) { | ||
| 851 | case PIX_FMT_YUYV422 : | ||
| 852 | case PIX_FMT_GRAY8A : | ||
| 853 | c->lumToYV12 = RENAME(yuy2ToY); break; | ||
| 854 | case PIX_FMT_UYVY422 : | ||
| 855 | c->lumToYV12 = RENAME(uyvyToY); break; | ||
| 856 | case PIX_FMT_BGR24 : c->lumToYV12 = RENAME(bgr24ToY); break; | ||
| 857 | case PIX_FMT_BGR565 : c->lumToYV12 = bgr16ToY; break; | ||
| 858 | case PIX_FMT_BGR555 : c->lumToYV12 = bgr15ToY; break; | ||
| 859 | case PIX_FMT_RGB24 : c->lumToYV12 = RENAME(rgb24ToY); break; | ||
| 860 | case PIX_FMT_RGB565 : c->lumToYV12 = rgb16ToY; break; | ||
| 861 | case PIX_FMT_RGB555 : c->lumToYV12 = rgb15ToY; break; | ||
| 862 | case PIX_FMT_RGB8 : | ||
| 863 | case PIX_FMT_BGR8 : | ||
| 864 | case PIX_FMT_PAL8 : | ||
| 865 | case PIX_FMT_BGR4_BYTE: | ||
| 866 | case PIX_FMT_RGB4_BYTE: c->lumToYV12 = palToY; break; | ||
| 867 | case PIX_FMT_MONOBLACK: c->lumToYV12 = monoblack2Y; break; | ||
| 868 | case PIX_FMT_MONOWHITE: c->lumToYV12 = monowhite2Y; break; | ||
| 869 | case PIX_FMT_RGB32 : c->lumToYV12 = bgr32ToY; break; | ||
| 870 | case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY; break; | ||
| 871 | case PIX_FMT_BGR32 : c->lumToYV12 = rgb32ToY; break; | ||
| 872 | case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY; break; | ||
| 873 | case PIX_FMT_RGB48BE: | ||
| 874 | case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48ToY; break; | ||
| 875 | case PIX_FMT_BGR48BE: | ||
| 876 | case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48ToY; break; | ||
| 877 | } | ||
| 878 | if (c->alpPixBuf) { | ||
| 879 | switch (srcFormat) { | ||
| 880 | case PIX_FMT_RGB32 : | ||
| 881 | case PIX_FMT_RGB32_1: | ||
| 882 | case PIX_FMT_BGR32 : | ||
| 883 | case PIX_FMT_BGR32_1: c->alpToYV12 = abgrToA; break; | ||
| 884 | case PIX_FMT_GRAY8A : c->alpToYV12 = RENAME(yuy2ToY); break; | ||
| 885 | case PIX_FMT_PAL8 : c->alpToYV12 = palToA; break; | ||
| 886 | } | ||
| 887 | } | ||
| 888 | |||
| 889 | switch (srcFormat) { | ||
| 890 | case PIX_FMT_GRAY8A : | ||
| 891 | c->alpSrcOffset = 1; | ||
| 892 | break; | ||
| 893 | case PIX_FMT_RGB32 : | ||
| 894 | case PIX_FMT_BGR32 : | ||
| 895 | c->alpSrcOffset = 3; | ||
| 896 | break; | ||
| 897 | case PIX_FMT_RGB48LE: | ||
| 898 | case PIX_FMT_BGR48LE: | ||
| 899 | c->lumSrcOffset = 1; | ||
| 900 | c->chrSrcOffset = 1; | ||
| 901 | c->alpSrcOffset = 1; | ||
| 902 | break; | ||
| 903 | } | ||
| 904 | |||
| 905 | if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) { | ||
| 906 | if (c->srcRange) { | ||
| 907 | c->lumConvertRange = RENAME(lumRangeFromJpeg); | ||
| 908 | c->chrConvertRange = RENAME(chrRangeFromJpeg); | ||
| 909 | } else { | ||
| 910 | c->lumConvertRange = RENAME(lumRangeToJpeg); | ||
| 911 | c->chrConvertRange = RENAME(chrRangeToJpeg); | ||
| 912 | } | ||
| 913 | } | ||
| 914 | |||
| 915 | if (!(isGray(srcFormat) || isGray(c->dstFormat) || | ||
| 916 | srcFormat == PIX_FMT_MONOBLACK || srcFormat == PIX_FMT_MONOWHITE)) | ||
| 917 | c->needs_hcscale = 1; | ||
| 918 | } | 66 | } |
| @@ -94,6 +94,7 @@ adjustment. · 93 unmodified lines | |||
| 94 | #include "libswscale/rgb2rgb.h" | 94 | #include "libswscale/rgb2rgb.h" |
| 95 | #include "libswscale/swscale.h" | 95 | #include "libswscale/swscale.h" |
| 96 | #include "libswscale/swscale_internal.h" | 96 | #include "libswscale/swscale_internal.h" |
| 97 | #include "libavutil/cpu.h" | ||
| 97 | 98 | ||
| 98 | #undef PROFILE_THE_BEAST | 99 | #undef PROFILE_THE_BEAST |
| 99 | #undef INC_SCALING | 100 | #undef INC_SCALING |
| @@ -692,7 +693,7 @@ static int altivec_uyvy_rgb32 (SwsContext *c, · 592 unmodified lines | |||
| 692 | */ | 693 | */ |
| 693 | SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c) | 694 | SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c) |
| 694 | { | 695 | { |
| 695 | if (!(c->flags & SWS_CPU_CAPS_ALTIVEC)) | 696 | if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) |
| 696 | return NULL; | 697 | return NULL; |
| 697 | 698 | ||
| 698 | /* | 699 | /* |
| @@ -116,12 +116,11 @@ void (*yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t · 115 unmodified lines | |||
| 116 | 32-bit C version, and and&add trick by Michael Niedermayer | 116 | 32-bit C version, and and&add trick by Michael Niedermayer |
| 117 | */ | 117 | */ |
| 118 | 118 | ||
| 119 | void sws_rgb2rgb_init(int flags) | 119 | void sws_rgb2rgb_init(void) |
| 120 | { | 120 | { |
| 121 | rgb2rgb_init_c(); | 121 | rgb2rgb_init_c(); |
| 122 | #if HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX | 122 | if (HAVE_MMX) |
| 123 | rgb2rgb_init_x86(flags); | 123 | rgb2rgb_init_x86(); |
| 124 | #endif /* HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX */ | ||
| 125 | } | 124 | } |
| 126 | 125 | ||
| 127 | #if LIBSWSCALE_VERSION_MAJOR < 1 | 126 | #if LIBSWSCALE_VERSION_MAJOR < 1 |
| @@ -166,8 +166,8 @@ extern void (*yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const u · 165 unmodified lines | |||
| 166 | long width, long height, | 166 | long width, long height, |
| 167 | long lumStride, long chromStride, long srcStride); | 167 | long lumStride, long chromStride, long srcStride); |
| 168 | 168 | ||
| 169 | void sws_rgb2rgb_init(int flags); | 169 | void sws_rgb2rgb_init(void); |
| 170 | 170 | ||
| 171 | void rgb2rgb_init_x86(int flags); | 171 | void rgb2rgb_init_x86(void); |
| 172 | 172 | ||
| 173 | #endif /* SWSCALE_RGB2RGB_H */ | 173 | #endif /* SWSCALE_RGB2RGB_H */ |
| @@ -278,25 +278,6 @@ static inline void rgb16tobgr24_c(const uint8_t *src, uint8_t *dst, long src_siz · 277 unmodified lines | |||
| 278 | } | 278 | } |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | /* | ||
| 282 | * mm0 = 00 B3 00 B2 00 B1 00 B0 | ||
| 283 | * mm1 = 00 G3 00 G2 00 G1 00 G0 | ||
| 284 | * mm2 = 00 R3 00 R2 00 R1 00 R0 | ||
| 285 | * mm6 = FF FF FF FF FF FF FF FF | ||
| 286 | * mm7 = 00 00 00 00 00 00 00 00 | ||
| 287 | */ | ||
| 288 | #define PACK_RGB32 \ | ||
| 289 | "packuswb %%mm7, %%mm0 \n\t" /* 00 00 00 00 B3 B2 B1 B0 */ \ | ||
| 290 | "packuswb %%mm7, %%mm1 \n\t" /* 00 00 00 00 G3 G2 G1 G0 */ \ | ||
| 291 | "packuswb %%mm7, %%mm2 \n\t" /* 00 00 00 00 R3 R2 R1 R0 */ \ | ||
| 292 | "punpcklbw %%mm1, %%mm0 \n\t" /* G3 B3 G2 B2 G1 B1 G0 B0 */ \ | ||
| 293 | "punpcklbw %%mm6, %%mm2 \n\t" /* FF R3 FF R2 FF R1 FF R0 */ \ | ||
| 294 | "movq %%mm0, %%mm3 \n\t" \ | ||
| 295 | "punpcklwd %%mm2, %%mm0 \n\t" /* FF R1 G1 B1 FF R0 G0 B0 */ \ | ||
| 296 | "punpckhwd %%mm2, %%mm3 \n\t" /* FF R3 G3 B3 FF R2 G2 B2 */ \ | ||
| 297 | MOVNTQ" %%mm0, %0 \n\t" \ | ||
| 298 | MOVNTQ" %%mm3, 8%0 \n\t" \ | ||
| 299 | |||
| 300 | static inline void rgb15to32_c(const uint8_t *src, uint8_t *dst, long src_size) | 281 | static inline void rgb15to32_c(const uint8_t *src, uint8_t *dst, long src_size) |
| 301 | { | 282 | { |
| 302 | const uint16_t *end; | 283 | const uint16_t *end; |
| @@ -63,6 +63,7 @@ untested special converters · 62 unmodified lines | |||
| 63 | #include "libavutil/avassert.h" | 63 | #include "libavutil/avassert.h" |
| 64 | #include "libavutil/intreadwrite.h" | 64 | #include "libavutil/intreadwrite.h" |
| 65 | #include "libavutil/x86_cpu.h" | 65 | #include "libavutil/x86_cpu.h" |
| 66 | #include "libavutil/cpu.h" | ||
| 66 | #include "libavutil/avutil.h" | 67 | #include "libavutil/avutil.h" |
| 67 | #include "libavutil/mathematics.h" | 68 | #include "libavutil/mathematics.h" |
| 68 | #include "libavutil/bswap.h" | 69 | #include "libavutil/bswap.h" |
| @@ -71,10 +72,6 @@ untested special converters · 2 unmodified lines | |||
| 71 | #undef MOVNTQ | 72 | #undef MOVNTQ |
| 72 | #undef PAVGB | 73 | #undef PAVGB |
| 73 | 74 | ||
| 74 | //#undef HAVE_MMX2 | ||
| 75 | //#define HAVE_AMD3DNOW | ||
| 76 | //#undef HAVE_MMX | ||
| 77 | //#undef ARCH_X86 | ||
| 78 | #define DITHER1XBPP | 75 | #define DITHER1XBPP |
| 79 | 76 | ||
| 80 | #define isPacked(x) ( \ | 77 | #define isPacked(x) ( \ |
| @@ -1262,57 +1259,13 @@ static inline void monoblack2Y(uint8_t *dst, const uint8_t *src, long width, uin · 1181 unmodified lines | |||
| 1262 | 1259 | ||
| 1263 | //Note: we have C, MMX, MMX2, 3DNOW versions, there is no 3DNOW+MMX2 one | 1260 | //Note: we have C, MMX, MMX2, 3DNOW versions, there is no 3DNOW+MMX2 one |
| 1264 | //Plain C versions | 1261 | //Plain C versions |
| 1265 | #if CONFIG_RUNTIME_CPUDETECT | ||
| 1266 | # define COMPILE_C 1 | ||
| 1267 | # if ARCH_X86 | ||
| 1268 | # define COMPILE_MMX 1 | ||
| 1269 | # define COMPILE_MMX2 1 | ||
| 1270 | # define COMPILE_3DNOW 1 | ||
| 1271 | # elif ARCH_PPC | ||
| 1272 | # define COMPILE_ALTIVEC HAVE_ALTIVEC | ||
| 1273 | # endif | ||
| 1274 | #else /* CONFIG_RUNTIME_CPUDETECT */ | ||
| 1275 | # if ARCH_X86 | ||
| 1276 | # if HAVE_MMX2 | ||
| 1277 | # define COMPILE_MMX2 1 | ||
| 1278 | # elif HAVE_AMD3DNOW | ||
| 1279 | # define COMPILE_3DNOW 1 | ||
| 1280 | # elif HAVE_MMX | ||
| 1281 | # define COMPILE_MMX 1 | ||
| 1282 | # else | ||
| 1283 | # define COMPILE_C 1 | ||
| 1284 | # endif | ||
| 1285 | # elif ARCH_PPC && HAVE_ALTIVEC | ||
| 1286 | # define COMPILE_ALTIVEC 1 | ||
| 1287 | # else | ||
| 1288 | # define COMPILE_C 1 | ||
| 1289 | # endif | ||
| 1290 | #endif | ||
| 1291 | |||
| 1292 | #ifndef COMPILE_C | ||
| 1293 | # define COMPILE_C 0 | ||
| 1294 | #endif | ||
| 1295 | #ifndef COMPILE_MMX | ||
| 1296 | # define COMPILE_MMX 0 | ||
| 1297 | #endif | ||
| 1298 | #ifndef COMPILE_MMX2 | ||
| 1299 | # define COMPILE_MMX2 0 | ||
| 1300 | #endif | ||
| 1301 | #ifndef COMPILE_3DNOW | ||
| 1302 | # define COMPILE_3DNOW 0 | ||
| 1303 | #endif | ||
| 1304 | #ifndef COMPILE_ALTIVEC | ||
| 1305 | # define COMPILE_ALTIVEC 0 | ||
| 1306 | #endif | ||
| 1307 | 1262 | ||
| 1308 | #define COMPILE_TEMPLATE_MMX 0 | ||
| 1309 | #define COMPILE_TEMPLATE_MMX2 0 | 1263 | #define COMPILE_TEMPLATE_MMX2 0 |
| 1310 | #define COMPILE_TEMPLATE_AMD3DNOW 0 | ||
| 1311 | #define COMPILE_TEMPLATE_ALTIVEC 0 | 1264 | #define COMPILE_TEMPLATE_ALTIVEC 0 |
| 1312 | 1265 | ||
| 1313 | #include "swscale_template.c" | 1266 | #include "swscale_template.c" |
| 1314 | 1267 | ||
| 1315 | #if COMPILE_ALTIVEC | 1268 | #if HAVE_ALTIVEC |
| 1316 | #undef RENAME | 1269 | #undef RENAME |
| 1317 | #undef COMPILE_TEMPLATE_ALTIVEC | 1270 | #undef COMPILE_TEMPLATE_ALTIVEC |
| 1318 | #define COMPILE_TEMPLATE_ALTIVEC 1 | 1271 | #define COMPILE_TEMPLATE_ALTIVEC 1 |
| @@ -1320,90 +1273,42 @@ static inline void monoblack2Y(uint8_t *dst, const uint8_t *src, long width, uin · 1 unmodified line | |||
| 1320 | #include "ppc/swscale_template.c" | 1273 | #include "ppc/swscale_template.c" |
| 1321 | #endif | 1274 | #endif |
| 1322 | 1275 | ||
| 1323 | #if ARCH_X86 | ||
| 1324 | |||
| 1325 | //MMX versions | 1276 | //MMX versions |
| 1326 | #if COMPILE_MMX | 1277 | #if HAVE_MMX |
| 1327 | #undef RENAME | 1278 | #undef RENAME |
| 1328 | #undef COMPILE_TEMPLATE_MMX | ||
| 1329 | #undef COMPILE_TEMPLATE_MMX2 | 1279 | #undef COMPILE_TEMPLATE_MMX2 |
| 1330 | #undef COMPILE_TEMPLATE_AMD3DNOW | ||
| 1331 | #define COMPILE_TEMPLATE_MMX 1 | ||
| 1332 | #define COMPILE_TEMPLATE_MMX2 0 | 1280 | #define COMPILE_TEMPLATE_MMX2 0 |
| 1333 | #define COMPILE_TEMPLATE_AMD3DNOW 0 | ||
| 1334 | #define RENAME(a) a ## _MMX | 1281 | #define RENAME(a) a ## _MMX |
| 1335 | #include "x86/swscale_template.c" | 1282 | #include "x86/swscale_template.c" |
| 1336 | #endif | 1283 | #endif |
| 1337 | 1284 | ||
| 1338 | //MMX2 versions | 1285 | //MMX2 versions |
| 1339 | #if COMPILE_MMX2 | 1286 | #if HAVE_MMX2 |
| 1340 | #undef RENAME | 1287 | #undef RENAME |
| 1341 | #undef COMPILE_TEMPLATE_MMX | ||
| 1342 | #undef COMPILE_TEMPLATE_MMX2 | 1288 | #undef COMPILE_TEMPLATE_MMX2 |
| 1343 | #undef COMPILE_TEMPLATE_AMD3DNOW | ||
| 1344 | #define COMPILE_TEMPLATE_MMX 1 | ||
| 1345 | #define COMPILE_TEMPLATE_MMX2 1 | 1289 | #define COMPILE_TEMPLATE_MMX2 1 |
| 1346 | #define COMPILE_TEMPLATE_AMD3DNOW 0 | ||
| 1347 | #define RENAME(a) a ## _MMX2 | 1290 | #define RENAME(a) a ## _MMX2 |
| 1348 | #include "x86/swscale_template.c" | 1291 | #include "x86/swscale_template.c" |
| 1349 | #endif | 1292 | #endif |
| 1350 | 1293 | ||
| 1351 | //3DNOW versions | ||
| 1352 | #if COMPILE_3DNOW | ||
| 1353 | #undef RENAME | ||
| 1354 | #undef COMPILE_TEMPLATE_MMX | ||
| 1355 | #undef COMPILE_TEMPLATE_MMX2 | ||
| 1356 | #undef COMPILE_TEMPLATE_AMD3DNOW | ||
| 1357 | #define COMPILE_TEMPLATE_MMX 1 | ||
| 1358 | #define COMPILE_TEMPLATE_MMX2 0 | ||
| 1359 | #define COMPILE_TEMPLATE_AMD3DNOW 1 | ||
| 1360 | #define RENAME(a) a ## _3DNow | ||
| 1361 | #include "x86/swscale_template.c" | ||
| 1362 | #endif | ||
| 1363 | |||
| 1364 | #endif //ARCH_X86 | ||
| 1365 | |||
| 1366 | SwsFunc ff_getSwsFunc(SwsContext *c) | 1294 | SwsFunc ff_getSwsFunc(SwsContext *c) |
| 1367 | { | 1295 | { |
| 1296 | int cpu_flags = av_get_cpu_flags(); | ||
| 1297 | |||
| 1368 | sws_init_swScale_c(c); | 1298 | sws_init_swScale_c(c); |
| 1369 | 1299 | ||
| 1370 | #if CONFIG_RUNTIME_CPUDETECT | 1300 | #if HAVE_MMX |
| 1371 | #if ARCH_X86 | 1301 | if (cpu_flags & AV_CPU_FLAG_MMX) |
| 1372 | // ordered per speed fastest first | ||
| 1373 | if (c->flags & SWS_CPU_CAPS_MMX2) { | ||
| 1374 | sws_init_swScale_MMX2(c); | ||
| 1375 | return swScale_MMX2; | ||
| 1376 | } else if (c->flags & SWS_CPU_CAPS_3DNOW) { | ||
| 1377 | sws_init_swScale_3DNow(c); | ||
| 1378 | return swScale_3DNow; | ||
| 1379 | } else if (c->flags & SWS_CPU_CAPS_MMX) { | ||
| 1380 | sws_init_swScale_MMX(c); | 1302 | sws_init_swScale_MMX(c); |
| 1381 | return swScale_MMX; | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | #else | ||
| 1385 | #if COMPILE_ALTIVEC | ||
| 1386 | if (c->flags & SWS_CPU_CAPS_ALTIVEC) { | ||
| 1387 | sws_init_swScale_altivec(c); | ||
| 1388 | return swScale_altivec; | ||
| 1389 | } | ||
| 1390 | #endif | 1303 | #endif |
| 1391 | #endif /* ARCH_X86 */ | 1304 | #if HAVE_MMX2 |
| 1392 | #else //CONFIG_RUNTIME_CPUDETECT | 1305 | if (cpu_flags & AV_CPU_FLAG_MMX2) |
| 1393 | #if COMPILE_TEMPLATE_MMX2 | 1306 | sws_init_swScale_MMX2(c); |
| 1394 | sws_init_swScale_MMX2(c); | 1307 | #endif |
| 1395 | return swScale_MMX2; | 1308 | #if HAVE_ALTIVEC |
| 1396 | #elif COMPILE_TEMPLATE_AMD3DNOW | 1309 | if (cpu_flags & AV_CPU_FLAG_ALTIVEC) |
| 1397 | sws_init_swScale_3DNow(c); | 1310 | sws_init_swScale_altivec(c); |
| 1398 | return swScale_3DNow; | ||
| 1399 | #elif COMPILE_TEMPLATE_MMX | ||
| 1400 | sws_init_swScale_MMX(c); | ||
| 1401 | return swScale_MMX; | ||
| 1402 | #elif COMPILE_TEMPLATE_ALTIVEC | ||
| 1403 | sws_init_swScale_altivec(c); | ||
| 1404 | return swScale_altivec; | ||
| 1405 | #endif | 1311 | #endif |
| 1406 | #endif //!CONFIG_RUNTIME_CPUDETECT | ||
| 1407 | 1312 | ||
| 1408 | return swScale_c; | 1313 | return swScale_c; |
| 1409 | } | 1314 | } |
| @@ -1900,23 +1805,6 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[ · 490 unmodified lines | |||
| 1900 | return srcSliceH; | 1805 | return srcSliceH; |
| 1901 | } | 1806 | } |
| 1902 | 1807 | ||
| 1903 | int ff_hardcodedcpuflags(void) | ||
| 1904 | { | ||
| 1905 | int flags = 0; | ||
| 1906 | #if COMPILE_TEMPLATE_MMX2 | ||
| 1907 | flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2; | ||
| 1908 | #elif COMPILE_TEMPLATE_AMD3DNOW | ||
| 1909 | flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_3DNOW; | ||
| 1910 | #elif COMPILE_TEMPLATE_MMX | ||
| 1911 | flags |= SWS_CPU_CAPS_MMX; | ||
| 1912 | #elif COMPILE_TEMPLATE_ALTIVEC | ||
| 1913 | flags |= SWS_CPU_CAPS_ALTIVEC; | ||
| 1914 | #elif ARCH_BFIN | ||
| 1915 | flags |= SWS_CPU_CAPS_BFIN; | ||
| 1916 | #endif | ||
| 1917 | return flags; | ||
| 1918 | } | ||
| 1919 | |||
| 1920 | void ff_get_unscaled_swscale(SwsContext *c) | 1808 | void ff_get_unscaled_swscale(SwsContext *c) |
| 1921 | { | 1809 | { |
| 1922 | const enum PixelFormat srcFormat = c->srcFormat; | 1810 | const enum PixelFormat srcFormat = c->srcFormat; |
| @@ -2000,8 +1888,8 @@ void ff_get_unscaled_swscale(SwsContext *c) · 77 unmodified lines | |||
| 2000 | if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P) | 1888 | if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P) |
| 2001 | c->swScale= uyvyToYuv422Wrapper; | 1889 | c->swScale= uyvyToYuv422Wrapper; |
| 2002 | 1890 | ||
| 2003 | #if COMPILE_ALTIVEC | 1891 | #if HAVE_ALTIVEC |
| 2004 | if ((c->flags & SWS_CPU_CAPS_ALTIVEC) && | 1892 | if ((av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) && |
| 2005 | !(c->flags & SWS_BITEXACT) && | 1893 | !(c->flags & SWS_BITEXACT) && |
| 2006 | srcFormat == PIX_FMT_YUV420P) { | 1894 | srcFormat == PIX_FMT_YUV420P) { |
| 2007 | // unscaled YV12 -> packed YUV, we want speed | 1895 | // unscaled YV12 -> packed YUV, we want speed |
| @@ -2031,8 +1919,7 @@ void ff_get_unscaled_swscale(SwsContext *c) · 23 unmodified lines | |||
| 2031 | c->swScale= planarCopyWrapper; | 1919 | c->swScale= planarCopyWrapper; |
| 2032 | } | 1920 | } |
| 2033 | #if ARCH_BFIN | 1921 | #if ARCH_BFIN |
| 2034 | if (flags & SWS_CPU_CAPS_BFIN) | 1922 | ff_bfin_get_unscaled_swscale (c); |
| 2035 | ff_bfin_get_unscaled_swscale (c); | ||
| 2036 | #endif | 1923 | #endif |
| 2037 | } | 1924 | } |
| 2038 | 1925 | ||
| @@ -95,13 +95,6 @@ const char *swscale_license(void); · 94 unmodified lines | |||
| 95 | #define SWS_ACCURATE_RND 0x40000 | 95 | #define SWS_ACCURATE_RND 0x40000 |
| 96 | #define SWS_BITEXACT 0x80000 | 96 | #define SWS_BITEXACT 0x80000 |
| 97 | 97 | ||
| 98 | #define SWS_CPU_CAPS_MMX 0x80000000 | ||
| 99 | #define SWS_CPU_CAPS_MMX2 0x20000000 | ||
| 100 | #define SWS_CPU_CAPS_3DNOW 0x40000000 | ||
| 101 | #define SWS_CPU_CAPS_ALTIVEC 0x10000000 | ||
| 102 | #define SWS_CPU_CAPS_BFIN 0x01000000 | ||
| 103 | #define SWS_CPU_CAPS_SSE2 0x02000000 | ||
| 104 | |||
| 105 | #define SWS_MAX_REDUCE_CUTOFF 0.002 | 98 | #define SWS_MAX_REDUCE_CUTOFF 0.002 |
| 106 | 99 | ||
| 107 | #define SWS_CS_ITU709 1 | 100 | #define SWS_CS_ITU709 1 |
| @@ -481,11 +481,6 @@ extern const AVClass sws_context_class; · 480 unmodified lines | |||
| 481 | */ | 481 | */ |
| 482 | void ff_get_unscaled_swscale(SwsContext *c); | 482 | void ff_get_unscaled_swscale(SwsContext *c); |
| 483 | 483 | ||
| 484 | /** | ||
| 485 | * Returns the SWS_CPU_CAPS for the optimized code compiled into swscale. | ||
| 486 | */ | ||
| 487 | int ff_hardcodedcpuflags(void); | ||
| 488 | |||
| 489 | /** | 484 | /** |
| 490 | * Returns function pointer to fastest main scaler path function depending | 485 | * Returns function pointer to fastest main scaler path function depending |
| 491 | * on architecture and available optimizations. | 486 | * on architecture and available optimizations. |
| @@ -363,153 +363,11 @@ static inline void hScale_c(int16_t *dst, int dstW, const uint8_t *src, · 362 unmodified lines | |||
| 363 | } | 363 | } |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | static inline void RENAME(hScale16)(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc, | 366 | static inline void hScale16_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc, |
| 367 | const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) | 367 | const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) |
| 368 | { | 368 | { |
| 369 | int i, j; | 369 | int i, j; |
| 370 | #if COMPILE_TEMPLATE_MMX | 370 | |
| 371 | assert(filterSize % 4 == 0 && filterSize>0); | ||
| 372 | if (filterSize==4 && shift<15) { // Always true for upscaling, sometimes for down, too. | ||
| 373 | x86_reg counter= -2*dstW; | ||
| 374 | filter-= counter*2; | ||
| 375 | filterPos-= counter/2; | ||
| 376 | dst-= counter/2; | ||
| 377 | __asm__ volatile( | ||
| 378 | "movd %5, %%mm7 \n\t" | ||
| 379 | #if defined(PIC) | ||
| 380 | "push %%"REG_b" \n\t" | ||
| 381 | #endif | ||
| 382 | "push %%"REG_BP" \n\t" // we use 7 regs here ... | ||
| 383 | "mov %%"REG_a", %%"REG_BP" \n\t" | ||
| 384 | ".p2align 4 \n\t" | ||
| 385 | "1: \n\t" | ||
| 386 | "movzwl (%2, %%"REG_BP"), %%eax \n\t" | ||
| 387 | "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t" | ||
| 388 | "movq (%1, %%"REG_BP", 4), %%mm1 \n\t" | ||
| 389 | "movq 8(%1, %%"REG_BP", 4), %%mm3 \n\t" | ||
| 390 | "movq (%3, %%"REG_a", 2), %%mm0 \n\t" | ||
| 391 | "movq (%3, %%"REG_b", 2), %%mm2 \n\t" | ||
| 392 | "pmaddwd %%mm1, %%mm0 \n\t" | ||
| 393 | "pmaddwd %%mm2, %%mm3 \n\t" | ||
| 394 | "movq %%mm0, %%mm4 \n\t" | ||
| 395 | "punpckldq %%mm3, %%mm0 \n\t" | ||
| 396 | "punpckhdq %%mm3, %%mm4 \n\t" | ||
| 397 | "paddd %%mm4, %%mm0 \n\t" | ||
| 398 | "psrad %%mm7, %%mm0 \n\t" | ||
| 399 | "packssdw %%mm0, %%mm0 \n\t" | ||
| 400 | "movd %%mm0, (%4, %%"REG_BP") \n\t" | ||
| 401 | "add $4, %%"REG_BP" \n\t" | ||
| 402 | " jnc 1b \n\t" | ||
| 403 | |||
| 404 | "pop %%"REG_BP" \n\t" | ||
| 405 | #if defined(PIC) | ||
| 406 | "pop %%"REG_b" \n\t" | ||
| 407 | #endif | ||
| 408 | : "+a" (counter) | ||
| 409 | : "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift) | ||
| 410 | #if !defined(PIC) | ||
| 411 | : "%"REG_b | ||
| 412 | #endif | ||
| 413 | ); | ||
| 414 | } else if (filterSize==8 && shift<15) { | ||
| 415 | x86_reg counter= -2*dstW; | ||
| 416 | filter-= counter*4; | ||
| 417 | filterPos-= counter/2; | ||
| 418 | dst-= counter/2; | ||
| 419 | __asm__ volatile( | ||
| 420 | "movd %5, %%mm7 \n\t" | ||
| 421 | #if defined(PIC) | ||
| 422 | "push %%"REG_b" \n\t" | ||
| 423 | #endif | ||
| 424 | "push %%"REG_BP" \n\t" // we use 7 regs here ... | ||
| 425 | "mov %%"REG_a", %%"REG_BP" \n\t" | ||
| 426 | ".p2align 4 \n\t" | ||
| 427 | "1: \n\t" | ||
| 428 | "movzwl (%2, %%"REG_BP"), %%eax \n\t" | ||
| 429 | "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t" | ||
| 430 | "movq (%1, %%"REG_BP", 8), %%mm1 \n\t" | ||
| 431 | "movq 16(%1, %%"REG_BP", 8), %%mm3 \n\t" | ||
| 432 | "movq (%3, %%"REG_a", 2), %%mm0 \n\t" | ||
| 433 | "movq (%3, %%"REG_b", 2), %%mm2 \n\t" | ||
| 434 | "pmaddwd %%mm1, %%mm0 \n\t" | ||
| 435 | "pmaddwd %%mm2, %%mm3 \n\t" | ||
| 436 | |||
| 437 | "movq 8(%1, %%"REG_BP", 8), %%mm1 \n\t" | ||
| 438 | "movq 24(%1, %%"REG_BP", 8), %%mm5 \n\t" | ||
| 439 | "movq 8(%3, %%"REG_a", 2), %%mm4 \n\t" | ||
| 440 | "movq 8(%3, %%"REG_b", 2), %%mm2 \n\t" | ||
| 441 | "pmaddwd %%mm1, %%mm4 \n\t" | ||
| 442 | "pmaddwd %%mm2, %%mm5 \n\t" | ||
| 443 | "paddd %%mm4, %%mm0 \n\t" | ||
| 444 | "paddd %%mm5, %%mm3 \n\t" | ||
| 445 | "movq %%mm0, %%mm4 \n\t" | ||
| 446 | "punpckldq %%mm3, %%mm0 \n\t" | ||
| 447 | "punpckhdq %%mm3, %%mm4 \n\t" | ||
| 448 | "paddd %%mm4, %%mm0 \n\t" | ||
| 449 | "psrad %%mm7, %%mm0 \n\t" | ||
| 450 | "packssdw %%mm0, %%mm0 \n\t" | ||
| 451 | "movd %%mm0, (%4, %%"REG_BP") \n\t" | ||
| 452 | "add $4, %%"REG_BP" \n\t" | ||
| 453 | " jnc 1b \n\t" | ||
| 454 | |||
| 455 | "pop %%"REG_BP" \n\t" | ||
| 456 | #if defined(PIC) | ||
| 457 | "pop %%"REG_b" \n\t" | ||
| 458 | #endif | ||
| 459 | : "+a" (counter) | ||
| 460 | : "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift) | ||
| 461 | #if !defined(PIC) | ||
| 462 | : "%"REG_b | ||
| 463 | #endif | ||
| 464 | ); | ||
| 465 | } else if (shift<15){ | ||
| 466 | const uint16_t *offset = src+filterSize; | ||
| 467 | x86_reg counter= -2*dstW; | ||
| 468 | //filter-= counter*filterSize/2; | ||
| 469 | filterPos-= counter/2; | ||
| 470 | dst-= counter/2; | ||
| 471 | __asm__ volatile( | ||
| 472 | "movd %7, %%mm7 \n\t" | ||
| 473 | ".p2align 4 \n\t" | ||
| 474 | "1: \n\t" | ||
| 475 | "mov %2, %%"REG_c" \n\t" | ||
| 476 | "movzwl (%%"REG_c", %0), %%eax \n\t" | ||
| 477 | "movzwl 2(%%"REG_c", %0), %%edx \n\t" | ||
| 478 | "mov %5, %%"REG_c" \n\t" | ||
| 479 | "pxor %%mm4, %%mm4 \n\t" | ||
| 480 | "pxor %%mm5, %%mm5 \n\t" | ||
| 481 | "2: \n\t" | ||
| 482 | "movq (%1), %%mm1 \n\t" | ||
| 483 | "movq (%1, %6), %%mm3 \n\t" | ||
| 484 | "movq (%%"REG_c", %%"REG_a", 2), %%mm0 \n\t" | ||
| 485 | "movq (%%"REG_c", %%"REG_d", 2), %%mm2 \n\t" | ||
| 486 | "pmaddwd %%mm1, %%mm0 \n\t" | ||
| 487 | "pmaddwd %%mm2, %%mm3 \n\t" | ||
| 488 | "paddd %%mm3, %%mm5 \n\t" | ||
| 489 | "paddd %%mm0, %%mm4 \n\t" | ||
| 490 | "add $8, %1 \n\t" | ||
| 491 | "add $8, %%"REG_c" \n\t" | ||
| 492 | "cmp %4, %%"REG_c" \n\t" | ||
| 493 | " jb 2b \n\t" | ||
| 494 | "add %6, %1 \n\t" | ||
| 495 | "movq %%mm4, %%mm0 \n\t" | ||
| 496 | "punpckldq %%mm5, %%mm4 \n\t" | ||
| 497 | "punpckhdq %%mm5, %%mm0 \n\t" | ||
| 498 | "paddd %%mm0, %%mm4 \n\t" | ||
| 499 | "psrad %%mm7, %%mm4 \n\t" | ||
| 500 | "packssdw %%mm4, %%mm4 \n\t" | ||
| 501 | "mov %3, %%"REG_a" \n\t" | ||
| 502 | "movd %%mm4, (%%"REG_a", %0) \n\t" | ||
| 503 | "add $4, %0 \n\t" | ||
| 504 | " jnc 1b \n\t" | ||
| 505 | |||
| 506 | : "+r" (counter), "+r" (filter) | ||
| 507 | : "m" (filterPos), "m" (dst), "m"(offset), | ||
| 508 | "m" (src), "r" ((x86_reg)filterSize*2), "m"(shift) | ||
| 509 | : "%"REG_a, "%"REG_c, "%"REG_d | ||
| 510 | ); | ||
| 511 | } else | ||
| 512 | #endif | ||
| 513 | for (i=0; i<dstW; i++) { | 371 | for (i=0; i<dstW; i++) { |
| 514 | int srcPos= filterPos[i]; | 372 | int srcPos= filterPos[i]; |
| 515 | int val=0; | 373 | int val=0; |
| @@ -520,7 +378,7 @@ static inline void RENAME(hScale16)(int16_t *dst, int dstW, const uint16_t *src, · 4 unmodified lines | |||
| 520 | } | 378 | } |
| 521 | } | 379 | } |
| 522 | 380 | ||
| 523 | static inline void RENAME(hScale16X)(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc, | 381 | static inline void hScale16X_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc, |
| 524 | const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) | 382 | const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) |
| 525 | { | 383 | { |
| 526 | int i, j; | 384 | int i, j; |
| @@ -660,6 +518,11 @@ inline static void hcscale_c(SwsContext *c, uint16_t *dst, long dstWidth, · 133 unmodified lines | |||
| 660 | #define DEBUG_SWSCALE_BUFFERS 0 | 518 | #define DEBUG_SWSCALE_BUFFERS 0 |
| 661 | #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__) | 519 | #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__) |
| 662 | 520 | ||
| 521 | #if HAVE_MMX | ||
| 522 | static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, | ||
| 523 | int lastInLumBuf, int lastInChrBuf); | ||
| 524 | #endif | ||
| 525 | |||
| 663 | static int swScale_c(SwsContext *c, const uint8_t* src[], int srcStride[], | 526 | static int swScale_c(SwsContext *c, const uint8_t* src[], int srcStride[], |
| 664 | int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]) | 527 | int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]) |
| 665 | { | 528 | { |
| @@ -831,6 +694,9 @@ static int swScale_c(SwsContext *c, const uint8_t* src[], int srcStride[], · 165 unmodified lines | |||
| 831 | if (!enough_lines) | 694 | if (!enough_lines) |
| 832 | break; //we can't output a dstY line so let's try with the next slice | 695 | break; //we can't output a dstY line so let's try with the next slice |
| 833 | 696 | ||
| 697 | #if HAVE_MMX | ||
| 698 | updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf); | ||
| 699 | #endif | ||
| 834 | if (dstY < dstH-2) { | 700 | if (dstY < dstH-2) { |
| 835 | const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; | 701 | const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; |
| 836 | const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; | 702 | const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; |
| @@ -955,6 +821,12 @@ static int swScale_c(SwsContext *c, const uint8_t* src[], int srcStride[], · 118 unmodified lines | |||
| 955 | if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf) | 821 | if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf) |
| 956 | fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255); | 822 | fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255); |
| 957 | 823 | ||
| 824 | #if HAVE_MMX2 | ||
| 825 | if (av_get_cpu_flags() & AV_CPU_FLAG_MMX2) | ||
| 826 | __asm__ volatile("sfence":::"memory"); | ||
| 827 | #endif | ||
| 828 | emms_c(); | ||
| 829 | |||
| 958 | /* store changed local vars back in the context */ | 830 | /* store changed local vars back in the context */ |
| 959 | c->dstY= dstY; | 831 | c->dstY= dstY; |
| 960 | c->lumBufIndex= lumBufIndex; | 832 | c->lumBufIndex= lumBufIndex; |
| @@ -1001,14 +873,14 @@ static void sws_init_swScale_c(SwsContext *c) · 40 unmodified lines | |||
| 1001 | case PIX_FMT_YUV420P10BE: | 873 | case PIX_FMT_YUV420P10BE: |
| 1002 | case PIX_FMT_YUV420P16BE: | 874 | case PIX_FMT_YUV420P16BE: |
| 1003 | case PIX_FMT_YUV422P16BE: | 875 | case PIX_FMT_YUV422P16BE: |
| 1004 | case PIX_FMT_YUV444P16BE: c->hScale16= HAVE_BIGENDIAN ? RENAME(hScale16) : RENAME(hScale16X); break; | 876 | case PIX_FMT_YUV444P16BE: c->hScale16= HAVE_BIGENDIAN ? hScale16_c : hScale16X_c; break; |
| 1005 | case PIX_FMT_GRAY16LE : | 877 | case PIX_FMT_GRAY16LE : |
| 1006 | case PIX_FMT_YUV420P9LE: | 878 | case PIX_FMT_YUV420P9LE: |
| 1007 | case PIX_FMT_YUV422P10LE: | 879 | case PIX_FMT_YUV422P10LE: |
| 1008 | case PIX_FMT_YUV420P10LE: | 880 | case PIX_FMT_YUV420P10LE: |
| 1009 | case PIX_FMT_YUV420P16LE: | 881 | case PIX_FMT_YUV420P16LE: |
| 1010 | case PIX_FMT_YUV422P16LE: | 882 | case PIX_FMT_YUV422P16LE: |
| 1011 | case PIX_FMT_YUV444P16LE: c->hScale16= HAVE_BIGENDIAN ? RENAME(hScale16X) : RENAME(hScale16); break; | 883 | case PIX_FMT_YUV444P16LE: c->hScale16= HAVE_BIGENDIAN ? hScale16X_c : hScale16_c; break; |
| 1012 | } | 884 | } |
| 1013 | if (c->chrSrcHSubSample) { | 885 | if (c->chrSrcHSubSample) { |
| 1014 | switch(srcFormat) { | 886 | switch(srcFormat) { |
| @@ -185,7 +185,7 @@ static double getSplineCoeff(double a, double b, double c, double d, double dist · 184 unmodified lines | |||
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc, | 187 | static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc, |
| 188 | int srcW, int dstW, int filterAlign, int one, int flags, | 188 | int srcW, int dstW, int filterAlign, int one, int flags, int cpu_flags, |
| 189 | SwsVector *srcFilter, SwsVector *dstFilter, double param[2]) | 189 | SwsVector *srcFilter, SwsVector *dstFilter, double param[2]) |
| 190 | { | 190 | { |
| 191 | int i; | 191 | int i; |
| @@ -196,10 +196,8 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi · 4 unmodified lines | |||
| 196 | int64_t *filter2=NULL; | 196 | int64_t *filter2=NULL; |
| 197 | const int64_t fone= 1LL<<54; | 197 | const int64_t fone= 1LL<<54; |
| 198 | int ret= -1; | 198 | int ret= -1; |
| 199 | #if ARCH_X86 | 199 | |
| 200 | if (flags & SWS_CPU_CAPS_MMX) | 200 | emms_c(); //FIXME this should not be required but it IS (even for non-MMX versions) |
| 201 | __asm__ volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions) | ||
| 202 | #endif | ||
| 203 | 201 | ||
| 204 | // NOTE: the +1 is for the MMX scaler which reads over the end | 202 | // NOTE: the +1 is for the MMX scaler which reads over the end |
| 205 | FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+1)*sizeof(int16_t), fail); | 203 | FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+1)*sizeof(int16_t), fail); |
| @@ -416,7 +414,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi · 210 unmodified lines | |||
| 416 | if (min>minFilterSize) minFilterSize= min; | 414 | if (min>minFilterSize) minFilterSize= min; |
| 417 | } | 415 | } |
| 418 | 416 | ||
| 419 | if (flags & SWS_CPU_CAPS_ALTIVEC) { | 417 | if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) { |
| 420 | // we can handle the special case 4, | 418 | // we can handle the special case 4, |
| 421 | // so we don't want to go to the full 8 | 419 | // so we don't want to go to the full 8 |
| 422 | if (minFilterSize < 5) | 420 | if (minFilterSize < 5) |
| @@ -431,7 +429,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi · 8 unmodified lines | |||
| 431 | filterAlign = 1; | 429 | filterAlign = 1; |
| 432 | } | 430 | } |
| 433 | 431 | ||
| 434 | if (flags & SWS_CPU_CAPS_MMX) { | 432 | if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) { |
| 435 | // special case for unscaled vertical filtering | 433 | // special case for unscaled vertical filtering |
| 436 | if (minFilterSize == 1 && filterAlign == 2) | 434 | if (minFilterSize == 1 && filterAlign == 2) |
| 437 | filterAlign= 1; | 435 | filterAlign= 1; |
| @@ -521,7 +519,7 @@ fail: · 83 unmodified lines | |||
| 521 | return ret; | 519 | return ret; |
| 522 | } | 520 | } |
| 523 | 521 | ||
| 524 | #if ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) | 522 | #if HAVE_MMX2 |
| 525 | static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *filter, int32_t *filterPos, int numSplits) | 523 | static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *filter, int32_t *filterPos, int numSplits) |
| 526 | { | 524 | { |
| 527 | uint8_t *fragmentA; | 525 | uint8_t *fragmentA; |
| @@ -679,7 +677,7 @@ static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *fil · 151 unmodified lines | |||
| 679 | 677 | ||
| 680 | return fragmentPos + 1; | 678 | return fragmentPos + 1; |
| 681 | } | 679 | } |
| 682 | #endif /* ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) */ | 680 | #endif /* HAVE_MMX2 */ |
| 683 | 681 | ||
| 684 | static void getSubSampleFactors(int *h, int *v, enum PixelFormat format) | 682 | static void getSubSampleFactors(int *h, int *v, enum PixelFormat format) |
| 685 | { | 683 | { |
| @@ -687,8 +685,6 @@ static void getSubSampleFactors(int *h, int *v, enum PixelFormat format) · 1 unmodified line | |||
| 687 | *v = av_pix_fmt_descriptors[format].log2_chroma_h; | 685 | *v = av_pix_fmt_descriptors[format].log2_chroma_h; |
| 688 | } | 686 | } |
| 689 | 687 | ||
| 690 | static int update_flags_cpu(int flags); | ||
| 691 | |||
| 692 | int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation) | 688 | int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation) |
| 693 | { | 689 | { |
| 694 | memcpy(c->srcColorspaceTable, inv_table, sizeof(int)*4); | 690 | memcpy(c->srcColorspaceTable, inv_table, sizeof(int)*4); |
| @@ -703,15 +699,12 @@ int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange · 8 unmodified lines | |||
| 703 | 699 | ||
| 704 | c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->dstFormat]); | 700 | c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->dstFormat]); |
| 705 | c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->srcFormat]); | 701 | c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->srcFormat]); |
| 706 | c->flags = update_flags_cpu(c->flags); | ||
| 707 | 702 | ||
| 708 | ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation); | 703 | ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation); |
| 709 | //FIXME factorize | 704 | //FIXME factorize |
| 710 | 705 | ||
| 711 | #if HAVE_ALTIVEC | 706 | if (HAVE_ALTIVEC && av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) |
| 712 | if (c->flags & SWS_CPU_CAPS_ALTIVEC) | ||
| 713 | ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness, contrast, saturation); | 707 | ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness, contrast, saturation); |
| 714 | #endif | ||
| 715 | return 0; | 708 | return 0; |
| 716 | } | 709 | } |
| 717 | 710 | ||
| @@ -741,27 +734,6 @@ static int handle_jpeg(enum PixelFormat *format) · 23 unmodified lines | |||
| 741 | } | 734 | } |
| 742 | } | 735 | } |
| 743 | 736 | ||
| 744 | static int update_flags_cpu(int flags) | ||
| 745 | { | ||
| 746 | #if !CONFIG_RUNTIME_CPUDETECT //ensure that the flags match the compiled variant if cpudetect is off | ||
| 747 | flags &= ~( SWS_CPU_CAPS_MMX | ||
| 748 | |SWS_CPU_CAPS_MMX2 | ||
| 749 | |SWS_CPU_CAPS_3DNOW | ||
| 750 | |SWS_CPU_CAPS_SSE2 | ||
| 751 | |SWS_CPU_CAPS_ALTIVEC | ||
| 752 | |SWS_CPU_CAPS_BFIN); | ||
| 753 | flags |= ff_hardcodedcpuflags(); | ||
| 754 | #else /* !CONFIG_RUNTIME_CPUDETECT */ | ||
| 755 | int cpuflags = av_get_cpu_flags(); | ||
| 756 | |||
| 757 | flags |= (cpuflags & AV_CPU_FLAG_SSE2 ? SWS_CPU_CAPS_SSE2 : 0); | ||
| 758 | flags |= (cpuflags & AV_CPU_FLAG_MMX ? SWS_CPU_CAPS_MMX : 0); | ||
| 759 | flags |= (cpuflags & AV_CPU_FLAG_MMX2 ? SWS_CPU_CAPS_MMX2 : 0); | ||
| 760 | flags |= (cpuflags & AV_CPU_FLAG_3DNOW ? SWS_CPU_CAPS_3DNOW : 0); | ||
| 761 | #endif /* CONFIG_RUNTIME_CPUDETECT */ | ||
| 762 | return flags; | ||
| 763 | } | ||
| 764 | |||
| 765 | SwsContext *sws_alloc_context(void) | 737 | SwsContext *sws_alloc_context(void) |
| 766 | { | 738 | { |
| 767 | SwsContext *c= av_mallocz(sizeof(SwsContext)); | 739 | SwsContext *c= av_mallocz(sizeof(SwsContext)); |
| @@ -782,16 +754,14 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 14 unmodified lines | |||
| 782 | int srcH= c->srcH; | 754 | int srcH= c->srcH; |
| 783 | int dstW= c->dstW; | 755 | int dstW= c->dstW; |
| 784 | int dstH= c->dstH; | 756 | int dstH= c->dstH; |
| 785 | int flags; | 757 | int flags, cpu_flags; |
| 786 | enum PixelFormat srcFormat= c->srcFormat; | 758 | enum PixelFormat srcFormat= c->srcFormat; |
| 787 | enum PixelFormat dstFormat= c->dstFormat; | 759 | enum PixelFormat dstFormat= c->dstFormat; |
| 788 | 760 | ||
| 789 | flags= c->flags = update_flags_cpu(c->flags); | 761 | cpu_flags = av_get_cpu_flags(); |
| 790 | #if ARCH_X86 | 762 | flags = c->flags; |
| 791 | if (flags & SWS_CPU_CAPS_MMX) | 763 | emms_c(); |
| 792 | __asm__ volatile("emms\n\t"::: "memory"); | 764 | if (!rgb15to16) sws_rgb2rgb_init(); |
| 793 | #endif | ||
| 794 | if (!rgb15to16) sws_rgb2rgb_init(flags); | ||
| 795 | 765 | ||
| 796 | unscaled = (srcW == dstW && srcH == dstH); | 766 | unscaled = (srcW == dstW && srcH == dstH); |
| 797 | 767 | ||
| @@ -884,7 +854,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 86 unmodified lines | |||
| 884 | } | 854 | } |
| 885 | } | 855 | } |
| 886 | 856 | ||
| 887 | if (flags & SWS_CPU_CAPS_MMX2) { | 857 | if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) { |
| 888 | c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0; | 858 | c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0; |
| 889 | if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR)) { | 859 | if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR)) { |
| 890 | if (flags&SWS_PRINT_INFO) | 860 | if (flags&SWS_PRINT_INFO) |
| @@ -910,7 +880,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 19 unmodified lines | |||
| 910 | c->chrXInc+= 20; | 880 | c->chrXInc+= 20; |
| 911 | } | 881 | } |
| 912 | //we don't use the x86 asm scaler if MMX is available | 882 | //we don't use the x86 asm scaler if MMX is available |
| 913 | else if (flags & SWS_CPU_CAPS_MMX) { | 883 | else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) { |
| 914 | c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20; | 884 | c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20; |
| 915 | c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20; | 885 | c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20; |
| 916 | } | 886 | } |
| @@ -918,7 +888,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 1 unmodified line | |||
| 918 | 888 | ||
| 919 | /* precalculate horizontal scaler filter coefficients */ | 889 | /* precalculate horizontal scaler filter coefficients */ |
| 920 | { | 890 | { |
| 921 | #if ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) | 891 | #if HAVE_MMX2 |
| 922 | // can't downscale !!! | 892 | // can't downscale !!! |
| 923 | if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR)) { | 893 | if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR)) { |
| 924 | c->lumMmx2FilterCodeSize = initMMX2HScaler( dstW, c->lumXInc, NULL, NULL, NULL, 8); | 894 | c->lumMmx2FilterCodeSize = initMMX2HScaler( dstW, c->lumXInc, NULL, NULL, NULL, 8); |
| @@ -954,21 +924,21 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 29 unmodified lines | |||
| 954 | mprotect(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, PROT_EXEC | PROT_READ); | 924 | mprotect(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, PROT_EXEC | PROT_READ); |
| 955 | #endif | 925 | #endif |
| 956 | } else | 926 | } else |
| 957 | #endif /* ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) */ | 927 | #endif /* HAVE_MMX2 */ |
| 958 | { | 928 | { |
| 959 | const int filterAlign= | 929 | const int filterAlign= |
| 960 | (flags & SWS_CPU_CAPS_MMX) ? 4 : | 930 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 4 : |
| 961 | (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 : | 931 | (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 : |
| 962 | 1; | 932 | 1; |
| 963 | 933 | ||
| 964 | if (initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc, | 934 | if (initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc, |
| 965 | srcW , dstW, filterAlign, 1<<14, | 935 | srcW , dstW, filterAlign, 1<<14, |
| 966 | (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, | 936 | (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, cpu_flags, |
| 967 | srcFilter->lumH, dstFilter->lumH, c->param) < 0) | 937 | srcFilter->lumH, dstFilter->lumH, c->param) < 0) |
| 968 | goto fail; | 938 | goto fail; |
| 969 | if (initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc, | 939 | if (initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc, |
| 970 | c->chrSrcW, c->chrDstW, filterAlign, 1<<14, | 940 | c->chrSrcW, c->chrDstW, filterAlign, 1<<14, |
| 971 | (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags, | 941 | (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags, cpu_flags, |
| 972 | srcFilter->chrH, dstFilter->chrH, c->param) < 0) | 942 | srcFilter->chrH, dstFilter->chrH, c->param) < 0) |
| 973 | goto fail; | 943 | goto fail; |
| 974 | } | 944 | } |
| @@ -977,18 +947,18 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 2 unmodified lines | |||
| 977 | /* precalculate vertical scaler filter coefficients */ | 947 | /* precalculate vertical scaler filter coefficients */ |
| 978 | { | 948 | { |
| 979 | const int filterAlign= | 949 | const int filterAlign= |
| 980 | (flags & SWS_CPU_CAPS_MMX) && (flags & SWS_ACCURATE_RND) ? 2 : | 950 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) && (flags & SWS_ACCURATE_RND) ? 2 : |
| 981 | (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 : | 951 | (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 : |
| 982 | 1; | 952 | 1; |
| 983 | 953 | ||
| 984 | if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc, | 954 | if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc, |
| 985 | srcH , dstH, filterAlign, (1<<12), | 955 | srcH , dstH, filterAlign, (1<<12), |
| 986 | (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, | 956 | (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, cpu_flags, |
| 987 | srcFilter->lumV, dstFilter->lumV, c->param) < 0) | 957 | srcFilter->lumV, dstFilter->lumV, c->param) < 0) |
| 988 | goto fail; | 958 | goto fail; |
| 989 | if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc, | 959 | if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc, |
| 990 | c->chrSrcH, c->chrDstH, filterAlign, (1<<12), | 960 | c->chrSrcH, c->chrDstH, filterAlign, (1<<12), |
| 991 | (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags, | 961 | (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags, cpu_flags, |
| 992 | srcFilter->chrV, dstFilter->chrV, c->param) < 0) | 962 | srcFilter->chrV, dstFilter->chrV, c->param) < 0) |
| 993 | goto fail; | 963 | goto fail; |
| 994 | 964 | ||
| @@ -1082,13 +1052,13 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 87 unmodified lines | |||
| 1082 | #endif | 1052 | #endif |
| 1083 | sws_format_name(dstFormat)); | 1053 | sws_format_name(dstFormat)); |
| 1084 | 1054 | ||
| 1085 | if (flags & SWS_CPU_CAPS_MMX2) av_log(c, AV_LOG_INFO, "using MMX2\n"); | 1055 | if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) av_log(c, AV_LOG_INFO, "using MMX2\n"); |
| 1086 | else if (flags & SWS_CPU_CAPS_3DNOW) av_log(c, AV_LOG_INFO, "using 3DNOW\n"); | 1056 | else if (HAVE_AMD3DNOW && cpu_flags & AV_CPU_FLAG_3DNOW) av_log(c, AV_LOG_INFO, "using 3DNOW\n"); |
| 1087 | else if (flags & SWS_CPU_CAPS_MMX) av_log(c, AV_LOG_INFO, "using MMX\n"); | 1057 | else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) av_log(c, AV_LOG_INFO, "using MMX\n"); |
| 1088 | else if (flags & SWS_CPU_CAPS_ALTIVEC) av_log(c, AV_LOG_INFO, "using AltiVec\n"); | 1058 | else if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) av_log(c, AV_LOG_INFO, "using AltiVec\n"); |
| 1089 | else av_log(c, AV_LOG_INFO, "using C\n"); | 1059 | else av_log(c, AV_LOG_INFO, "using C\n"); |
| 1090 | 1060 | ||
| 1091 | if (flags & SWS_CPU_CAPS_MMX) { | 1061 | if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) { |
| 1092 | if (c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR)) | 1062 | if (c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR)) |
| 1093 | av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR MMX2 scaler for horizontal scaling\n"); | 1063 | av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR MMX2 scaler for horizontal scaling\n"); |
| 1094 | else { | 1064 | else { |
| @@ -1107,7 +1077,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 12 unmodified lines | |||
| 1107 | av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal chrominance scaling\n"); | 1077 | av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal chrominance scaling\n"); |
| 1108 | } | 1078 | } |
| 1109 | } else { | 1079 | } else { |
| 1110 | #if ARCH_X86 | 1080 | #if HAVE_MMX |
| 1111 | av_log(c, AV_LOG_VERBOSE, "using x86 asm scaler for horizontal scaling\n"); | 1081 | av_log(c, AV_LOG_VERBOSE, "using x86 asm scaler for horizontal scaling\n"); |
| 1112 | #else | 1082 | #else |
| 1113 | if (flags & SWS_FAST_BILINEAR) | 1083 | if (flags & SWS_FAST_BILINEAR) |
| @@ -1118,31 +1088,41 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 4 unmodified lines | |||
| 1118 | } | 1088 | } |
| 1119 | if (isPlanarYUV(dstFormat)) { | 1089 | if (isPlanarYUV(dstFormat)) { |
| 1120 | if (c->vLumFilterSize==1) | 1090 | if (c->vLumFilterSize==1) |
| 1121 | av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical scaling (YV12 like)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1091 | av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical scaling (YV12 like)\n", |
| 1092 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1122 | else | 1093 | else |
| 1123 | av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (YV12 like)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1094 | av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (YV12 like)\n", |
| 1095 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1124 | } else { | 1096 | } else { |
| 1125 | if (c->vLumFilterSize==1 && c->vChrFilterSize==2) | 1097 | if (c->vLumFilterSize==1 && c->vChrFilterSize==2) |
| 1126 | av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical luminance scaling (BGR)\n" | 1098 | av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical luminance scaling (BGR)\n" |
| 1127 | " 2-tap scaler for vertical chrominance scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1099 | " 2-tap scaler for vertical chrominance scaling (BGR)\n", |
| 1100 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1128 | else if (c->vLumFilterSize==2 && c->vChrFilterSize==2) | 1101 | else if (c->vLumFilterSize==2 && c->vChrFilterSize==2) |
| 1129 | av_log(c, AV_LOG_VERBOSE, "using 2-tap linear %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1102 | av_log(c, AV_LOG_VERBOSE, "using 2-tap linear %s scaler for vertical scaling (BGR)\n", |
| 1103 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1130 | else | 1104 | else |
| 1131 | av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1105 | av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (BGR)\n", |
| 1106 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1132 | } | 1107 | } |
| 1133 | 1108 | ||
| 1134 | if (dstFormat==PIX_FMT_BGR24) | 1109 | if (dstFormat==PIX_FMT_BGR24) |
| 1135 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR24 converter\n", | 1110 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR24 converter\n", |
| 1136 | (flags & SWS_CPU_CAPS_MMX2) ? "MMX2" : ((flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C")); | 1111 | (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) ? "MMX2" : |
| 1112 | ((HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C")); | ||
| 1137 | else if (dstFormat==PIX_FMT_RGB32) | 1113 | else if (dstFormat==PIX_FMT_RGB32) |
| 1138 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR32 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1114 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR32 converter\n", |
| 1115 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1139 | else if (dstFormat==PIX_FMT_BGR565) | 1116 | else if (dstFormat==PIX_FMT_BGR565) |
| 1140 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR16 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1117 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR16 converter\n", |
| 1118 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1141 | else if (dstFormat==PIX_FMT_BGR555) | 1119 | else if (dstFormat==PIX_FMT_BGR555) |
| 1142 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR15 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1120 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR15 converter\n", |
| 1121 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1143 | else if (dstFormat == PIX_FMT_RGB444BE || dstFormat == PIX_FMT_RGB444LE || | 1122 | else if (dstFormat == PIX_FMT_RGB444BE || dstFormat == PIX_FMT_RGB444LE || |
| 1144 | dstFormat == PIX_FMT_BGR444BE || dstFormat == PIX_FMT_BGR444LE) | 1123 | dstFormat == PIX_FMT_BGR444BE || dstFormat == PIX_FMT_BGR444LE) |
| 1145 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR12 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"); | 1124 | av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR12 converter\n", |
| 1125 | (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? "MMX" : "C"); | ||
| 1146 | 1126 | ||
| 1147 | av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH); | 1127 | av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH); |
| 1148 | av_log(c, AV_LOG_DEBUG, "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n", | 1128 | av_log(c, AV_LOG_DEBUG, "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n", |
| @@ -1527,7 +1507,7 @@ void sws_freeContext(SwsContext *c) · 378 unmodified lines | |||
| 1527 | av_freep(&c->hLumFilterPos); | 1507 | av_freep(&c->hLumFilterPos); |
| 1528 | av_freep(&c->hChrFilterPos); | 1508 | av_freep(&c->hChrFilterPos); |
| 1529 | 1509 | ||
| 1530 | #if ARCH_X86 | 1510 | #if HAVE_MMX |
| 1531 | #ifdef MAP_ANONYMOUS | 1511 | #ifdef MAP_ANONYMOUS |
| 1532 | if (c->lumMmx2FilterCode) munmap(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize); | 1512 | if (c->lumMmx2FilterCode) munmap(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize); |
| 1533 | if (c->chrMmx2FilterCode) munmap(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize); | 1513 | if (c->chrMmx2FilterCode) munmap(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize); |
| @@ -1540,7 +1520,7 @@ void sws_freeContext(SwsContext *c) · 6 unmodified lines | |||
| 1540 | #endif | 1520 | #endif |
| 1541 | c->lumMmx2FilterCode=NULL; | 1521 | c->lumMmx2FilterCode=NULL; |
| 1542 | c->chrMmx2FilterCode=NULL; | 1522 | c->chrMmx2FilterCode=NULL; |
| 1543 | #endif /* ARCH_X86 */ | 1523 | #endif /* HAVE_MMX */ |
| 1544 | 1524 | ||
| 1545 | av_freep(&c->yuvTable); | 1525 | av_freep(&c->yuvTable); |
| 1546 | 1526 | ||
| @@ -1557,8 +1537,6 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context, · 10 unmodified lines | |||
| 1557 | if (!param) | 1537 | if (!param) |
| 1558 | param = default_param; | 1538 | param = default_param; |
| 1559 | 1539 | ||
| 1560 | flags = update_flags_cpu(flags); | ||
| 1561 | |||
| 1562 | if (context && | 1540 | if (context && |
| 1563 | (context->srcW != srcW || | 1541 | (context->srcW != srcW || |
| 1564 | context->srcH != srcH || | 1542 | context->srcH != srcH || |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | #include "config.h" | 28 | #include "config.h" |
| 29 | #include "libavutil/x86_cpu.h" | 29 | #include "libavutil/x86_cpu.h" |
| 30 | #include "libavutil/cpu.h" | ||
| 30 | #include "libavutil/bswap.h" | 31 | #include "libavutil/bswap.h" |
| 31 | #include "libswscale/rgb2rgb.h" | 32 | #include "libswscale/rgb2rgb.h" |
| 32 | #include "libswscale/swscale.h" | 33 | #include "libswscale/swscale.h" |
| @@ -122,16 +123,16 @@ DECLARE_ASM_CONST(8, uint64_t, blue_15mask) = 0x0000001f0000001fULL; · 89 unmodified lines | |||
| 122 | 32-bit C version, and and&add trick by Michael Niedermayer | 123 | 32-bit C version, and and&add trick by Michael Niedermayer |
| 123 | */ | 124 | */ |
| 124 | 125 | ||
| 125 | void rgb2rgb_init_x86(int flags) | 126 | void rgb2rgb_init_x86(void) |
| 126 | { | 127 | { |
| 127 | #if HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX | 128 | int cpu_flags = av_get_cpu_flags(); |
| 128 | if (flags & SWS_CPU_CAPS_SSE2) | 129 | |
| 129 | rgb2rgb_init_SSE2(); | 130 | if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) |
| 130 | else if (flags & SWS_CPU_CAPS_MMX2) | ||
| 131 | rgb2rgb_init_MMX2(); | ||
| 132 | else if (flags & SWS_CPU_CAPS_3DNOW) | ||
| 133 | rgb2rgb_init_3DNOW(); | ||
| 134 | else if (flags & SWS_CPU_CAPS_MMX) | ||
| 135 | rgb2rgb_init_MMX(); | 131 | rgb2rgb_init_MMX(); |
| 136 | #endif /* HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX */ | 132 | if (HAVE_AMD3DNOW && cpu_flags & AV_CPU_FLAG_3DNOW) |
| 133 | rgb2rgb_init_3DNOW(); | ||
| 134 | if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) | ||
| 135 | rgb2rgb_init_MMX2(); | ||
| 136 | if (HAVE_SSE && cpu_flags & AV_CPU_FLAG_SSE2) | ||
| 137 | rgb2rgb_init_SSE2(); | ||
| 137 | } | 138 | } |
| @@ -22,23 +22,14 @@ · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | #undef REAL_MOVNTQ | 23 | #undef REAL_MOVNTQ |
| 24 | #undef MOVNTQ | 24 | #undef MOVNTQ |
| 25 | #undef PAVGB | ||
| 26 | #undef PREFETCH | 25 | #undef PREFETCH |
| 27 | 26 | ||
| 28 | #if COMPILE_TEMPLATE_AMD3DNOW | 27 | #if COMPILE_TEMPLATE_MMX2 |
| 29 | #define PREFETCH "prefetch" | ||
| 30 | #elif COMPILE_TEMPLATE_MMX2 | ||
| 31 | #define PREFETCH "prefetchnta" | 28 | #define PREFETCH "prefetchnta" |
| 32 | #else | 29 | #else |
| 33 | #define PREFETCH " # nop" | 30 | #define PREFETCH " # nop" |
| 34 | #endif | 31 | #endif |
| 35 | 32 | ||
| 36 | #if COMPILE_TEMPLATE_MMX2 | ||
| 37 | #define PAVGB(a,b) "pavgb " #a ", " #b " \n\t" | ||
| 38 | #elif COMPILE_TEMPLATE_AMD3DNOW | ||
| 39 | #define PAVGB(a,b) "pavgusb " #a ", " #b " \n\t" | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #if COMPILE_TEMPLATE_MMX2 | 33 | #if COMPILE_TEMPLATE_MMX2 |
| 43 | #define REAL_MOVNTQ(a,b) "movntq " #a ", " #b " \n\t" | 34 | #define REAL_MOVNTQ(a,b) "movntq " #a ", " #b " \n\t" |
| 44 | #else | 35 | #else |
| @@ -709,62 +700,6 @@ · 664 unmodified lines | |||
| 709 | " jb 1b \n\t" | 700 | " jb 1b \n\t" |
| 710 | #define WRITERGB15(dst, dstw, index) REAL_WRITERGB15(dst, dstw, index) | 701 | #define WRITERGB15(dst, dstw, index) REAL_WRITERGB15(dst, dstw, index) |
| 711 | 702 | ||
| 712 | #define WRITEBGR24OLD(dst, dstw, index) \ | ||
| 713 | /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\ | ||
| 714 | "movq %%mm2, %%mm1 \n\t" /* B */\ | ||
| 715 | "movq %%mm5, %%mm6 \n\t" /* R */\ | ||
| 716 | "punpcklbw %%mm4, %%mm2 \n\t" /* GBGBGBGB 0 */\ | ||
| 717 | "punpcklbw %%mm7, %%mm5 \n\t" /* 0R0R0R0R 0 */\ | ||
| 718 | "punpckhbw %%mm4, %%mm1 \n\t" /* GBGBGBGB 2 */\ | ||
| 719 | "punpckhbw %%mm7, %%mm6 \n\t" /* 0R0R0R0R 2 */\ | ||
| 720 | "movq %%mm2, %%mm0 \n\t" /* GBGBGBGB 0 */\ | ||
| 721 | "movq %%mm1, %%mm3 \n\t" /* GBGBGBGB 2 */\ | ||
| 722 | "punpcklwd %%mm5, %%mm0 \n\t" /* 0RGB0RGB 0 */\ | ||
| 723 | "punpckhwd %%mm5, %%mm2 \n\t" /* 0RGB0RGB 1 */\ | ||
| 724 | "punpcklwd %%mm6, %%mm1 \n\t" /* 0RGB0RGB 2 */\ | ||
| 725 | "punpckhwd %%mm6, %%mm3 \n\t" /* 0RGB0RGB 3 */\ | ||
| 726 | \ | ||
| 727 | "movq %%mm0, %%mm4 \n\t" /* 0RGB0RGB 0 */\ | ||
| 728 | "psrlq $8, %%mm0 \n\t" /* 00RGB0RG 0 */\ | ||
| 729 | "pand "MANGLE(bm00000111)", %%mm4 \n\t" /* 00000RGB 0 */\ | ||
| 730 | "pand "MANGLE(bm11111000)", %%mm0 \n\t" /* 00RGB000 0.5 */\ | ||
| 731 | "por %%mm4, %%mm0 \n\t" /* 00RGBRGB 0 */\ | ||
| 732 | "movq %%mm2, %%mm4 \n\t" /* 0RGB0RGB 1 */\ | ||
| 733 | "psllq $48, %%mm2 \n\t" /* GB000000 1 */\ | ||
| 734 | "por %%mm2, %%mm0 \n\t" /* GBRGBRGB 0 */\ | ||
| 735 | \ | ||
| 736 | "movq %%mm4, %%mm2 \n\t" /* 0RGB0RGB 1 */\ | ||
| 737 | "psrld $16, %%mm4 \n\t" /* 000R000R 1 */\ | ||
| 738 | "psrlq $24, %%mm2 \n\t" /* 0000RGB0 1.5 */\ | ||
| 739 | "por %%mm4, %%mm2 \n\t" /* 000RRGBR 1 */\ | ||
| 740 | "pand "MANGLE(bm00001111)", %%mm2 \n\t" /* 0000RGBR 1 */\ | ||
| 741 | "movq %%mm1, %%mm4 \n\t" /* 0RGB0RGB 2 */\ | ||
| 742 | "psrlq $8, %%mm1 \n\t" /* 00RGB0RG 2 */\ | ||
| 743 | "pand "MANGLE(bm00000111)", %%mm4 \n\t" /* 00000RGB 2 */\ | ||
| 744 | "pand "MANGLE(bm11111000)", %%mm1 \n\t" /* 00RGB000 2.5 */\ | ||
| 745 | "por %%mm4, %%mm1 \n\t" /* 00RGBRGB 2 */\ | ||
| 746 | "movq %%mm1, %%mm4 \n\t" /* 00RGBRGB 2 */\ | ||
| 747 | "psllq $32, %%mm1 \n\t" /* BRGB0000 2 */\ | ||
| 748 | "por %%mm1, %%mm2 \n\t" /* BRGBRGBR 1 */\ | ||
| 749 | \ | ||
| 750 | "psrlq $32, %%mm4 \n\t" /* 000000RG 2.5 */\ | ||
| 751 | "movq %%mm3, %%mm5 \n\t" /* 0RGB0RGB 3 */\ | ||
| 752 | "psrlq $8, %%mm3 \n\t" /* 00RGB0RG 3 */\ | ||
| 753 | "pand "MANGLE(bm00000111)", %%mm5 \n\t" /* 00000RGB 3 */\ | ||
| 754 | "pand "MANGLE(bm11111000)", %%mm3 \n\t" /* 00RGB000 3.5 */\ | ||
| 755 | "por %%mm5, %%mm3 \n\t" /* 00RGBRGB 3 */\ | ||
| 756 | "psllq $16, %%mm3 \n\t" /* RGBRGB00 3 */\ | ||
| 757 | "por %%mm4, %%mm3 \n\t" /* RGBRGBRG 2.5 */\ | ||
| 758 | \ | ||
| 759 | MOVNTQ(%%mm0, (dst))\ | ||
| 760 | MOVNTQ(%%mm2, 8(dst))\ | ||
| 761 | MOVNTQ(%%mm3, 16(dst))\ | ||
| 762 | "add $24, "#dst" \n\t"\ | ||
| 763 | \ | ||
| 764 | "add $8, "#index" \n\t"\ | ||
| 765 | "cmp "#dstw", "#index" \n\t"\ | ||
| 766 | " jb 1b \n\t" | ||
| 767 | |||
| 768 | #define WRITEBGR24MMX(dst, dstw, index) \ | 703 | #define WRITEBGR24MMX(dst, dstw, index) \ |
| 769 | /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\ | 704 | /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\ |
| 770 | "movq %%mm2, %%mm1 \n\t" /* B */\ | 705 | "movq %%mm2, %%mm1 \n\t" /* B */\ |
| @@ -896,7 +831,6 @@ static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter, con · 125 unmodified lines | |||
| 896 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc, | 831 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc, |
| 897 | uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW) | 832 | uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW) |
| 898 | { | 833 | { |
| 899 | if(!(c->flags & SWS_BITEXACT)) { | ||
| 900 | if (c->flags & SWS_ACCURATE_RND) { | 834 | if (c->flags & SWS_ACCURATE_RND) { |
| 901 | if (uDest) { | 835 | if (uDest) { |
| 902 | YSCALEYUV2YV12X_ACCURATE( "0", CHR_MMX_FILTER_OFFSET, uDest, chrDstW) | 836 | YSCALEYUV2YV12X_ACCURATE( "0", CHR_MMX_FILTER_OFFSET, uDest, chrDstW) |
| @@ -918,27 +852,11 @@ static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter, con · 15 unmodified lines | |||
| 918 | 852 | ||
| 919 | YSCALEYUV2YV12X("0", LUM_MMX_FILTER_OFFSET, dest, dstW) | 853 | YSCALEYUV2YV12X("0", LUM_MMX_FILTER_OFFSET, dest, dstW) |
| 920 | } | 854 | } |
| 921 | return; | ||
| 922 | } | ||
| 923 | yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize, | ||
| 924 | chrFilter, chrSrc, chrFilterSize, | ||
| 925 | alpSrc, dest, uDest, vDest, aDest, dstW, chrDstW); | ||
| 926 | } | ||
| 927 | |||
| 928 | static inline void RENAME(yuv2nv12X)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, | ||
| 929 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, | ||
| 930 | uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, enum PixelFormat dstFormat) | ||
| 931 | { | ||
| 932 | yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize, | ||
| 933 | chrFilter, chrSrc, chrFilterSize, | ||
| 934 | dest, uDest, dstW, chrDstW, dstFormat); | ||
| 935 | } | 855 | } |
| 936 | 856 | ||
| 937 | static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const int16_t *chrSrc, const int16_t *alpSrc, | 857 | static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const int16_t *chrSrc, const int16_t *alpSrc, |
| 938 | uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW) | 858 | uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW) |
| 939 | { | 859 | { |
| 940 | int i; | ||
| 941 | if(!(c->flags & SWS_BITEXACT)) { | ||
| 942 | long p= 4; | 860 | long p= 4; |
| 943 | const int16_t *src[4]= {alpSrc + dstW, lumSrc + dstW, chrSrc + chrDstW, chrSrc + VOFW + chrDstW}; | 861 | const int16_t *src[4]= {alpSrc + dstW, lumSrc + dstW, chrSrc + chrDstW, chrSrc + VOFW + chrDstW}; |
| 944 | uint8_t *dst[4]= {aDest, dest, uDest, vDest}; | 862 | uint8_t *dst[4]= {aDest, dest, uDest, vDest}; |
| @@ -967,40 +885,6 @@ static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const · 22 unmodified lines | |||
| 967 | } | 885 | } |
| 968 | } | 886 | } |
| 969 | } | 887 | } |
| 970 | return; | ||
| 971 | } | ||
| 972 | for (i=0; i<dstW; i++) { | ||
| 973 | int val= (lumSrc[i]+64)>>7; | ||
| 974 | |||
| 975 | if (val&256) { | ||
| 976 | if (val<0) val=0; | ||
| 977 | else val=255; | ||
| 978 | } | ||
| 979 | |||
| 980 | dest[i]= val; | ||
| 981 | } | ||
| 982 | |||
| 983 | if (uDest) | ||
| 984 | for (i=0; i<chrDstW; i++) { | ||
| 985 | int u=(chrSrc[i ]+64)>>7; | ||
| 986 | int v=(chrSrc[i + VOFW]+64)>>7; | ||
| 987 | |||
| 988 | if ((u|v)&256) { | ||
| 989 | if (u<0) u=0; | ||
| 990 | else if (u>255) u=255; | ||
| 991 | if (v<0) v=0; | ||
| 992 | else if (v>255) v=255; | ||
| 993 | } | ||
| 994 | |||
| 995 | uDest[i]= u; | ||
| 996 | vDest[i]= v; | ||
| 997 | } | ||
| 998 | |||
| 999 | if (CONFIG_SWSCALE_ALPHA && aDest) | ||
| 1000 | for (i=0; i<dstW; i++) { | ||
| 1001 | int val= (alpSrc[i]+64)>>7; | ||
| 1002 | aDest[i]= av_clip_uint8(val); | ||
| 1003 | } | ||
| 1004 | } | 888 | } |
| 1005 | 889 | ||
| 1006 | 890 | ||
| @@ -1013,7 +897,7 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 6 unmodified lines | |||
| 1013 | { | 897 | { |
| 1014 | x86_reg dummy=0; | 898 | x86_reg dummy=0; |
| 1015 | x86_reg dstW_reg = dstW; | 899 | x86_reg dstW_reg = dstW; |
| 1016 | if(!(c->flags & SWS_BITEXACT)) { | 900 | |
| 1017 | if (c->flags & SWS_ACCURATE_RND) { | 901 | if (c->flags & SWS_ACCURATE_RND) { |
| 1018 | switch(c->dstFormat) { | 902 | switch(c->dstFormat) { |
| 1019 | case PIX_FMT_RGB32: | 903 | case PIX_FMT_RGB32: |
| @@ -1170,7 +1054,7 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 150 unmodified lines | |||
| 1170 | return; | 1054 | return; |
| 1171 | } | 1055 | } |
| 1172 | } | 1056 | } |
| 1173 | } | 1057 | |
| 1174 | yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize, | 1058 | yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize, |
| 1175 | chrFilter, chrSrc, chrFilterSize, | 1059 | chrFilter, chrSrc, chrFilterSize, |
| 1176 | alpSrc, dest, dstW, dstY); | 1060 | alpSrc, dest, dstW, dstY); |
| @@ -1182,11 +1066,6 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 5 unmodified lines | |||
| 1182 | static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, const uint16_t *buf1, const uint16_t *uvbuf0, const uint16_t *uvbuf1, | 1066 | static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, const uint16_t *buf1, const uint16_t *uvbuf0, const uint16_t *uvbuf1, |
| 1183 | const uint16_t *abuf0, const uint16_t *abuf1, uint8_t *dest, int dstW, int yalpha, int uvalpha, int y) | 1067 | const uint16_t *abuf0, const uint16_t *abuf1, uint8_t *dest, int dstW, int yalpha, int uvalpha, int y) |
| 1184 | { | 1068 | { |
| 1185 | int yalpha1=4095- yalpha; | ||
| 1186 | int uvalpha1=4095-uvalpha; | ||
| 1187 | int i; | ||
| 1188 | |||
| 1189 | if(!(c->flags & SWS_BITEXACT)) { | ||
| 1190 | switch(c->dstFormat) { | 1069 | switch(c->dstFormat) { |
| 1191 | //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( | 1070 | //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( |
| 1192 | case PIX_FMT_RGB32: | 1071 | case PIX_FMT_RGB32: |
| @@ -1317,10 +1196,10 @@ static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, cons · 124 unmodified lines | |||
| 1317 | "a" (&c->redDither) | 1196 | "a" (&c->redDither) |
| 1318 | ); | 1197 | ); |
| 1319 | return; | 1198 | return; |
| 1320 | default: break; | ||
| 1321 | } | 1199 | } |
| 1322 | } | 1200 | |
| 1323 | YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C(void,0), YSCALE_YUV_2_GRAY16_2_C, YSCALE_YUV_2_MONO2_C) | 1201 | yuv2packed2_c(c, buf0, buf1, uvbuf0, uvbuf1, abuf0, abuf1, |
| 1202 | dest, dstW, yalpha, uvalpha, y); | ||
| 1324 | } | 1203 | } |
| 1325 | 1204 | ||
| 1326 | /** | 1205 | /** |
| @@ -1329,18 +1208,13 @@ static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, cons · 2 unmodified lines | |||
| 1329 | static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, const uint16_t *uvbuf0, const uint16_t *uvbuf1, | 1208 | static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, const uint16_t *uvbuf0, const uint16_t *uvbuf1, |
| 1330 | const uint16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, enum PixelFormat dstFormat, int flags, int y) | 1209 | const uint16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, enum PixelFormat dstFormat, int flags, int y) |
| 1331 | { | 1210 | { |
| 1332 | const int yalpha1=0; | 1211 | const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1 |
| 1333 | int i; | ||
| 1334 | |||
| 1335 | const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1 | ||
| 1336 | const int yalpha= 4096; //FIXME ... | ||
| 1337 | 1212 | ||
| 1338 | if (flags&SWS_FULL_CHR_H_INT) { | 1213 | if (flags&SWS_FULL_CHR_H_INT) { |
| 1339 | c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y); | 1214 | c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y); |
| 1340 | return; | 1215 | return; |
| 1341 | } | 1216 | } |
| 1342 | 1217 | ||
| 1343 | if(!(flags & SWS_BITEXACT)) { | ||
| 1344 | if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster | 1218 | if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster |
| 1345 | switch(dstFormat) { | 1219 | switch(dstFormat) { |
| 1346 | case PIX_FMT_RGB32: | 1220 | case PIX_FMT_RGB32: |
| @@ -1554,12 +1428,9 @@ static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, cons · 207 unmodified lines | |||
| 1554 | return; | 1428 | return; |
| 1555 | } | 1429 | } |
| 1556 | } | 1430 | } |
| 1557 | } | 1431 | |
| 1558 | if (uvalpha < 2048) { | 1432 | yuv2packed1_c(c, buf0, uvbuf0, uvbuf1, abuf0, dest, |
| 1559 | YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C, YSCALE_YUV_2_PACKED1_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C) | 1433 | dstW, uvalpha, dstFormat, flags, y); |
| 1560 | } else { | ||
| 1561 | YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C, YSCALE_YUV_2_PACKED1B_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C) | ||
| 1562 | } | ||
| 1563 | } | 1434 | } |
| 1564 | 1435 | ||
| 1565 | //FIXME yuy2* can read up to 7 samples too much | 1436 | //FIXME yuy2* can read up to 7 samples too much |
| @@ -1866,20 +1737,6 @@ static inline void RENAME(bgr24ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t · 300 unmodified lines | |||
| 1866 | assert(src1 == src2); | 1737 | assert(src1 == src2); |
| 1867 | } | 1738 | } |
| 1868 | 1739 | ||
| 1869 | static inline void RENAME(bgr24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 1870 | { | ||
| 1871 | int i; | ||
| 1872 | for (i=0; i<width; i++) { | ||
| 1873 | int b= src1[6*i + 0] + src1[6*i + 3]; | ||
| 1874 | int g= src1[6*i + 1] + src1[6*i + 4]; | ||
| 1875 | int r= src1[6*i + 2] + src1[6*i + 5]; | ||
| 1876 | |||
| 1877 | dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1); | ||
| 1878 | dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1); | ||
| 1879 | } | ||
| 1880 | assert(src1 == src2); | ||
| 1881 | } | ||
| 1882 | |||
| 1883 | static inline void RENAME(rgb24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused) | 1740 | static inline void RENAME(rgb24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused) |
| 1884 | { | 1741 | { |
| 1885 | RENAME(bgr24ToY_mmx)(dst, src, width, PIX_FMT_RGB24); | 1742 | RENAME(bgr24ToY_mmx)(dst, src, width, PIX_FMT_RGB24); |
| @@ -1891,20 +1748,6 @@ static inline void RENAME(rgb24ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t · 5 unmodified lines | |||
| 1891 | RENAME(bgr24ToUV_mmx)(dstU, dstV, src1, width, PIX_FMT_RGB24); | 1748 | RENAME(bgr24ToUV_mmx)(dstU, dstV, src1, width, PIX_FMT_RGB24); |
| 1892 | } | 1749 | } |
| 1893 | 1750 | ||
| 1894 | static inline void RENAME(rgb24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) | ||
| 1895 | { | ||
| 1896 | int i; | ||
| 1897 | assert(src1==src2); | ||
| 1898 | for (i=0; i<width; i++) { | ||
| 1899 | int r= src1[6*i + 0] + src1[6*i + 3]; | ||
| 1900 | int g= src1[6*i + 1] + src1[6*i + 4]; | ||
| 1901 | int b= src1[6*i + 2] + src1[6*i + 5]; | ||
| 1902 | |||
| 1903 | dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1); | ||
| 1904 | dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1); | ||
| 1905 | } | ||
| 1906 | } | ||
| 1907 | |||
| 1908 | 1751 | ||
| 1909 | // bilinear / bicubic scaling | 1752 | // bilinear / bicubic scaling |
| 1910 | static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW, int xInc, | 1753 | static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW, int xInc, |
| @@ -2061,50 +1904,168 @@ static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, in · 150 unmodified lines | |||
| 2061 | } | 1904 | } |
| 2062 | } | 1905 | } |
| 2063 | 1906 | ||
| 2064 | //FIXME all pal and rgb srcFormats could do this convertion as well | 1907 | static inline void RENAME(hScale16)(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc, |
| 2065 | //FIXME all scalers more complex than bilinear could do half of this transform | 1908 | const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) |
| 2066 | static void RENAME(chrRangeToJpeg)(int16_t *dst, int width) | ||
| 2067 | { | 1909 | { |
| 2068 | int i; | 1910 | int i, j; |
| 2069 | for (i = 0; i < width; i++) { | 1911 | |
| 2070 | dst[i ] = (FFMIN(dst[i ],30775)*4663 - 9289992)>>12; //-264 | 1912 | assert(filterSize % 4 == 0 && filterSize>0); |
| 2071 | dst[i+VOFW] = (FFMIN(dst[i+VOFW],30775)*4663 - 9289992)>>12; //-264 | 1913 | if (filterSize==4 && shift<15) { // Always true for upscaling, sometimes for down, too. |
| 2072 | } | 1914 | x86_reg counter= -2*dstW; |
| 2073 | } | 1915 | filter-= counter*2; |
| 2074 | static void RENAME(chrRangeFromJpeg)(int16_t *dst, int width) | 1916 | filterPos-= counter/2; |
| 2075 | { | 1917 | dst-= counter/2; |
| 2076 | int i; | 1918 | __asm__ volatile( |
| 2077 | for (i = 0; i < width; i++) { | 1919 | "movd %5, %%mm7 \n\t" |
| 2078 | dst[i ] = (dst[i ]*1799 + 4081085)>>11; //1469 | 1920 | #if defined(PIC) |
| 2079 | dst[i+VOFW] = (dst[i+VOFW]*1799 + 4081085)>>11; //1469 | 1921 | "push %%"REG_b" \n\t" |
| 1922 | #endif | ||
| 1923 | "push %%"REG_BP" \n\t" // we use 7 regs here ... | ||
| 1924 | "mov %%"REG_a", %%"REG_BP" \n\t" | ||
| 1925 | ".p2align 4 \n\t" | ||
| 1926 | "1: \n\t" | ||
| 1927 | "movzwl (%2, %%"REG_BP"), %%eax \n\t" | ||
| 1928 | "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t" | ||
| 1929 | "movq (%1, %%"REG_BP", 4), %%mm1 \n\t" | ||
| 1930 | "movq 8(%1, %%"REG_BP", 4), %%mm3 \n\t" | ||
| 1931 | "movq (%3, %%"REG_a", 2), %%mm0 \n\t" | ||
| 1932 | "movq (%3, %%"REG_b", 2), %%mm2 \n\t" | ||
| 1933 | "pmaddwd %%mm1, %%mm0 \n\t" | ||
| 1934 | "pmaddwd %%mm2, %%mm3 \n\t" | ||
| 1935 | "movq %%mm0, %%mm4 \n\t" | ||
| 1936 | "punpckldq %%mm3, %%mm0 \n\t" | ||
| 1937 | "punpckhdq %%mm3, %%mm4 \n\t" | ||
| 1938 | "paddd %%mm4, %%mm0 \n\t" | ||
| 1939 | "psrad %%mm7, %%mm0 \n\t" | ||
| 1940 | "packssdw %%mm0, %%mm0 \n\t" | ||
| 1941 | "movd %%mm0, (%4, %%"REG_BP") \n\t" | ||
| 1942 | "add $4, %%"REG_BP" \n\t" | ||
| 1943 | " jnc 1b \n\t" | ||
| 1944 | |||
| 1945 | "pop %%"REG_BP" \n\t" | ||
| 1946 | #if defined(PIC) | ||
| 1947 | "pop %%"REG_b" \n\t" | ||
| 1948 | #endif | ||
| 1949 | : "+a" (counter) | ||
| 1950 | : "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift) | ||
| 1951 | #if !defined(PIC) | ||
| 1952 | : "%"REG_b | ||
| 1953 | #endif | ||
| 1954 | ); | ||
| 1955 | } else if (filterSize==8 && shift<15) { | ||
| 1956 | x86_reg counter= -2*dstW; | ||
| 1957 | filter-= counter*4; | ||
| 1958 | filterPos-= counter/2; | ||
| 1959 | dst-= counter/2; | ||
| 1960 | __asm__ volatile( | ||
| 1961 | "movd %5, %%mm7 \n\t" | ||
| 1962 | #if defined(PIC) | ||
| 1963 | "push %%"REG_b" \n\t" | ||
| 1964 | #endif | ||
| 1965 | "push %%"REG_BP" \n\t" // we use 7 regs here ... | ||
| 1966 | "mov %%"REG_a", %%"REG_BP" \n\t" | ||
| 1967 | ".p2align 4 \n\t" | ||
| 1968 | "1: \n\t" | ||
| 1969 | "movzwl (%2, %%"REG_BP"), %%eax \n\t" | ||
| 1970 | "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t" | ||
| 1971 | "movq (%1, %%"REG_BP", 8), %%mm1 \n\t" | ||
| 1972 | "movq 16(%1, %%"REG_BP", 8), %%mm3 \n\t" | ||
| 1973 | "movq (%3, %%"REG_a", 2), %%mm0 \n\t" | ||
| 1974 | "movq (%3, %%"REG_b", 2), %%mm2 \n\t" | ||
| 1975 | "pmaddwd %%mm1, %%mm0 \n\t" | ||
| 1976 | "pmaddwd %%mm2, %%mm3 \n\t" | ||
| 1977 | |||
| 1978 | "movq 8(%1, %%"REG_BP", 8), %%mm1 \n\t" | ||
| 1979 | "movq 24(%1, %%"REG_BP", 8), %%mm5 \n\t" | ||
| 1980 | "movq 8(%3, %%"REG_a", 2), %%mm4 \n\t" | ||
| 1981 | "movq 8(%3, %%"REG_b", 2), %%mm2 \n\t" | ||
| 1982 | "pmaddwd %%mm1, %%mm4 \n\t" | ||
| 1983 | "pmaddwd %%mm2, %%mm5 \n\t" | ||
| 1984 | "paddd %%mm4, %%mm0 \n\t" | ||
| 1985 | "paddd %%mm5, %%mm3 \n\t" | ||
| 1986 | "movq %%mm0, %%mm4 \n\t" | ||
| 1987 | "punpckldq %%mm3, %%mm0 \n\t" | ||
| 1988 | "punpckhdq %%mm3, %%mm4 \n\t" | ||
| 1989 | "paddd %%mm4, %%mm0 \n\t" | ||
| 1990 | "psrad %%mm7, %%mm0 \n\t" | ||
| 1991 | "packssdw %%mm0, %%mm0 \n\t" | ||
| 1992 | "movd %%mm0, (%4, %%"REG_BP") \n\t" | ||
| 1993 | "add $4, %%"REG_BP" \n\t" | ||
| 1994 | " jnc 1b \n\t" | ||
| 1995 | |||
| 1996 | "pop %%"REG_BP" \n\t" | ||
| 1997 | #if defined(PIC) | ||
| 1998 | "pop %%"REG_b" \n\t" | ||
| 1999 | #endif | ||
| 2000 | : "+a" (counter) | ||
| 2001 | : "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift) | ||
| 2002 | #if !defined(PIC) | ||
| 2003 | : "%"REG_b | ||
| 2004 | #endif | ||
| 2005 | ); | ||
| 2006 | } else if (shift<15){ | ||
| 2007 | const uint16_t *offset = src+filterSize; | ||
| 2008 | x86_reg counter= -2*dstW; | ||
| 2009 | //filter-= counter*filterSize/2; | ||
| 2010 | filterPos-= counter/2; | ||
| 2011 | dst-= counter/2; | ||
| 2012 | __asm__ volatile( | ||
| 2013 | "movd %7, %%mm7 \n\t" | ||
| 2014 | ".p2align 4 \n\t" | ||
| 2015 | "1: \n\t" | ||
| 2016 | "mov %2, %%"REG_c" \n\t" | ||
| 2017 | "movzwl (%%"REG_c", %0), %%eax \n\t" | ||
| 2018 | "movzwl 2(%%"REG_c", %0), %%edx \n\t" | ||
| 2019 | "mov %5, %%"REG_c" \n\t" | ||
| 2020 | "pxor %%mm4, %%mm4 \n\t" | ||
| 2021 | "pxor %%mm5, %%mm5 \n\t" | ||
| 2022 | "2: \n\t" | ||
| 2023 | "movq (%1), %%mm1 \n\t" | ||
| 2024 | "movq (%1, %6), %%mm3 \n\t" | ||
| 2025 | "movq (%%"REG_c", %%"REG_a", 2), %%mm0 \n\t" | ||
| 2026 | "movq (%%"REG_c", %%"REG_d", 2), %%mm2 \n\t" | ||
| 2027 | "pmaddwd %%mm1, %%mm0 \n\t" | ||
| 2028 | "pmaddwd %%mm2, %%mm3 \n\t" | ||
| 2029 | "paddd %%mm3, %%mm5 \n\t" | ||
| 2030 | "paddd %%mm0, %%mm4 \n\t" | ||
| 2031 | "add $8, %1 \n\t" | ||
| 2032 | "add $8, %%"REG_c" \n\t" | ||
| 2033 | "cmp %4, %%"REG_c" \n\t" | ||
| 2034 | " jb 2b \n\t" | ||
| 2035 | "add %6, %1 \n\t" | ||
| 2036 | "movq %%mm4, %%mm0 \n\t" | ||
| 2037 | "punpckldq %%mm5, %%mm4 \n\t" | ||
| 2038 | "punpckhdq %%mm5, %%mm0 \n\t" | ||
| 2039 | "paddd %%mm0, %%mm4 \n\t" | ||
| 2040 | "psrad %%mm7, %%mm4 \n\t" | ||
| 2041 | "packssdw %%mm4, %%mm4 \n\t" | ||
| 2042 | "mov %3, %%"REG_a" \n\t" | ||
| 2043 | "movd %%mm4, (%%"REG_a", %0) \n\t" | ||
| 2044 | "add $4, %0 \n\t" | ||
| 2045 | " jnc 1b \n\t" | ||
| 2046 | |||
| 2047 | : "+r" (counter), "+r" (filter) | ||
| 2048 | : "m" (filterPos), "m" (dst), "m"(offset), | ||
| 2049 | "m" (src), "r" ((x86_reg)filterSize*2), "m"(shift) | ||
| 2050 | : "%"REG_a, "%"REG_c, "%"REG_d | ||
| 2051 | ); | ||
| 2052 | } else | ||
| 2053 | for (i=0; i<dstW; i++) { | ||
| 2054 | int srcPos= filterPos[i]; | ||
| 2055 | int val=0; | ||
| 2056 | for (j=0; j<filterSize; j++) { | ||
| 2057 | val += ((int)src[srcPos + j])*filter[filterSize*i + j]; | ||
| 2058 | } | ||
| 2059 | dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ... | ||
| 2080 | } | 2060 | } |
| 2081 | } | 2061 | } |
| 2082 | static void RENAME(lumRangeToJpeg)(int16_t *dst, int width) | ||
| 2083 | { | ||
| 2084 | int i; | ||
| 2085 | for (i = 0; i < width; i++) | ||
| 2086 | dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14; | ||
| 2087 | } | ||
| 2088 | static void RENAME(lumRangeFromJpeg)(int16_t *dst, int width) | ||
| 2089 | { | ||
| 2090 | int i; | ||
| 2091 | for (i = 0; i < width; i++) | ||
| 2092 | dst[i] = (dst[i]*14071 + 33561947)>>14; | ||
| 2093 | } | ||
| 2094 | 2062 | ||
| 2095 | #define FAST_BILINEAR_X86 \ | ||
| 2096 | "subl %%edi, %%esi \n\t" /* src[xx+1] - src[xx] */ \ | ||
| 2097 | "imull %%ecx, %%esi \n\t" /* (src[xx+1] - src[xx])*xalpha */ \ | ||
| 2098 | "shll $16, %%edi \n\t" \ | ||
| 2099 | "addl %%edi, %%esi \n\t" /* src[xx+1]*xalpha + src[xx]*(1-xalpha) */ \ | ||
| 2100 | "mov %1, %%"REG_D"\n\t" \ | ||
| 2101 | "shrl $9, %%esi \n\t" \ | ||
| 2102 | 2063 | ||
| 2064 | #if COMPILE_TEMPLATE_MMX2 | ||
| 2103 | static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, | 2065 | static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, |
| 2104 | long dstWidth, const uint8_t *src, int srcW, | 2066 | long dstWidth, const uint8_t *src, int srcW, |
| 2105 | int xInc) | 2067 | int xInc) |
| 2106 | { | 2068 | { |
| 2107 | #if COMPILE_TEMPLATE_MMX2 | ||
| 2108 | int32_t *filterPos = c->hLumFilterPos; | 2069 | int32_t *filterPos = c->hLumFilterPos; |
| 2109 | int16_t *filter = c->hLumFilter; | 2070 | int16_t *filter = c->hLumFilter; |
| 2110 | int canMMX2BeUsed = c->canMMX2BeUsed; | 2071 | int canMMX2BeUsed = c->canMMX2BeUsed; |
| @@ -2113,7 +2074,7 @@ static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, · 2 unmodified lines | |||
| 2113 | #if defined(PIC) | 2074 | #if defined(PIC) |
| 2114 | DECLARE_ALIGNED(8, uint64_t, ebxsave); | 2075 | DECLARE_ALIGNED(8, uint64_t, ebxsave); |
| 2115 | #endif | 2076 | #endif |
| 2116 | if (canMMX2BeUsed) { | 2077 | |
| 2117 | __asm__ volatile( | 2078 | __asm__ volatile( |
| 2118 | #if defined(PIC) | 2079 | #if defined(PIC) |
| 2119 | "mov %%"REG_b", %5 \n\t" | 2080 | "mov %%"REG_b", %5 \n\t" |
| @@ -2172,80 +2133,12 @@ static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, · 52 unmodified lines | |||
| 2172 | #endif | 2133 | #endif |
| 2173 | ); | 2134 | ); |
| 2174 | for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128; | 2135 | for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128; |
| 2175 | } else { | ||
| 2176 | #endif /* COMPILE_TEMPLATE_MMX2 */ | ||
| 2177 | x86_reg xInc_shr16 = xInc >> 16; | ||
| 2178 | uint16_t xInc_mask = xInc & 0xffff; | ||
| 2179 | x86_reg dstWidth_reg = dstWidth; | ||
| 2180 | //NO MMX just normal asm ... | ||
| 2181 | __asm__ volatile( | ||
| 2182 | "xor %%"REG_a", %%"REG_a" \n\t" // i | ||
| 2183 | "xor %%"REG_d", %%"REG_d" \n\t" // xx | ||
| 2184 | "xorl %%ecx, %%ecx \n\t" // xalpha | ||
| 2185 | ".p2align 4 \n\t" | ||
| 2186 | "1: \n\t" | ||
| 2187 | "movzbl (%0, %%"REG_d"), %%edi \n\t" //src[xx] | ||
| 2188 | "movzbl 1(%0, %%"REG_d"), %%esi \n\t" //src[xx+1] | ||
| 2189 | FAST_BILINEAR_X86 | ||
| 2190 | "movw %%si, (%%"REG_D", %%"REG_a", 2) \n\t" | ||
| 2191 | "addw %4, %%cx \n\t" //xalpha += xInc&0xFFFF | ||
| 2192 | "adc %3, %%"REG_d" \n\t" //xx+= xInc>>16 + carry | ||
| 2193 | |||
| 2194 | "movzbl (%0, %%"REG_d"), %%edi \n\t" //src[xx] | ||
| 2195 | "movzbl 1(%0, %%"REG_d"), %%esi \n\t" //src[xx+1] | ||
| 2196 | FAST_BILINEAR_X86 | ||
| 2197 | "movw %%si, 2(%%"REG_D", %%"REG_a", 2) \n\t" | ||
| 2198 | "addw %4, %%cx \n\t" //xalpha += xInc&0xFFFF | ||
| 2199 | "adc %3, %%"REG_d" \n\t" //xx+= xInc>>16 + carry | ||
| 2200 | |||
| 2201 | |||
| 2202 | "add $2, %%"REG_a" \n\t" | ||
| 2203 | "cmp %2, %%"REG_a" \n\t" | ||
| 2204 | " jb 1b \n\t" | ||
| 2205 | |||
| 2206 | |||
| 2207 | :: "r" (src), "m" (dst), "m" (dstWidth_reg), "m" (xInc_shr16), "m" (xInc_mask) | ||
| 2208 | : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi" | ||
| 2209 | ); | ||
| 2210 | #if COMPILE_TEMPLATE_MMX2 | ||
| 2211 | } //if MMX2 can't be used | ||
| 2212 | #endif | ||
| 2213 | } | ||
| 2214 | |||
| 2215 | // *** horizontal scale Y line to temp buffer | ||
| 2216 | static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src, int srcW, int xInc, | ||
| 2217 | const int16_t *hLumFilter, | ||
| 2218 | const int16_t *hLumFilterPos, int hLumFilterSize, | ||
| 2219 | uint8_t *formatConvBuffer, | ||
| 2220 | uint32_t *pal, int isAlpha) | ||
| 2221 | { | ||
| 2222 | void (*toYV12)(uint8_t *, const uint8_t *, long, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12; | ||
| 2223 | void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange; | ||
| 2224 | |||
| 2225 | src += isAlpha ? c->alpSrcOffset : c->lumSrcOffset; | ||
| 2226 | |||
| 2227 | if (toYV12) { | ||
| 2228 | toYV12(formatConvBuffer, src, srcW, pal); | ||
| 2229 | src= formatConvBuffer; | ||
| 2230 | } | ||
| 2231 | |||
| 2232 | if (c->hScale16) { | ||
| 2233 | c->hScale16(dst, dstWidth, (uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1); | ||
| 2234 | } else if (!c->hyscale_fast) { | ||
| 2235 | c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize); | ||
| 2236 | } else { // fast bilinear upscale / crap downscale | ||
| 2237 | c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc); | ||
| 2238 | } | ||
| 2239 | |||
| 2240 | if (convertRange) | ||
| 2241 | convertRange(dst, dstWidth); | ||
| 2242 | } | 2136 | } |
| 2243 | 2137 | ||
| 2244 | static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, | 2138 | static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, |
| 2245 | long dstWidth, const uint8_t *src1, | 2139 | long dstWidth, const uint8_t *src1, |
| 2246 | const uint8_t *src2, int srcW, int xInc) | 2140 | const uint8_t *src2, int srcW, int xInc) |
| 2247 | { | 2141 | { |
| 2248 | #if COMPILE_TEMPLATE_MMX2 | ||
| 2249 | int32_t *filterPos = c->hChrFilterPos; | 2142 | int32_t *filterPos = c->hChrFilterPos; |
| 2250 | int16_t *filter = c->hChrFilter; | 2143 | int16_t *filter = c->hChrFilter; |
| 2251 | int canMMX2BeUsed = c->canMMX2BeUsed; | 2144 | int canMMX2BeUsed = c->canMMX2BeUsed; |
| @@ -2254,7 +2147,7 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, · 2 unmodified lines | |||
| 2254 | #if defined(PIC) | 2147 | #if defined(PIC) |
| 2255 | DECLARE_ALIGNED(8, uint64_t, ebxsave); | 2148 | DECLARE_ALIGNED(8, uint64_t, ebxsave); |
| 2256 | #endif | 2149 | #endif |
| 2257 | if (canMMX2BeUsed) { | 2150 | |
| 2258 | __asm__ volatile( | 2151 | __asm__ volatile( |
| 2259 | #if defined(PIC) | 2152 | #if defined(PIC) |
| 2260 | "mov %%"REG_b", %6 \n\t" | 2153 | "mov %%"REG_b", %6 \n\t" |
| @@ -2304,252 +2197,32 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, · 43 unmodified lines | |||
| 2304 | dst[i] = src1[srcW-1]*128; | 2197 | dst[i] = src1[srcW-1]*128; |
| 2305 | dst[i+VOFW] = src2[srcW-1]*128; | 2198 | dst[i+VOFW] = src2[srcW-1]*128; |
| 2306 | } | 2199 | } |
| 2307 | } else { | ||
| 2308 | #endif /* COMPILE_TEMPLATE_MMX2 */ | ||
| 2309 | x86_reg xInc_shr16 = (x86_reg) (xInc >> 16); | ||
| 2310 | uint16_t xInc_mask = xInc & 0xffff; | ||
| 2311 | x86_reg dstWidth_reg = dstWidth; | ||
| 2312 | __asm__ volatile( | ||
| 2313 | "xor %%"REG_a", %%"REG_a" \n\t" // i | ||
| 2314 | "xor %%"REG_d", %%"REG_d" \n\t" // xx | ||
| 2315 | "xorl %%ecx, %%ecx \n\t" // xalpha | ||
| 2316 | ".p2align 4 \n\t" | ||
| 2317 | "1: \n\t" | ||
| 2318 | "mov %0, %%"REG_S" \n\t" | ||
| 2319 | "movzbl (%%"REG_S", %%"REG_d"), %%edi \n\t" //src[xx] | ||
| 2320 | "movzbl 1(%%"REG_S", %%"REG_d"), %%esi \n\t" //src[xx+1] | ||
| 2321 | FAST_BILINEAR_X86 | ||
| 2322 | "movw %%si, (%%"REG_D", %%"REG_a", 2) \n\t" | ||
| 2323 | |||
| 2324 | "movzbl (%5, %%"REG_d"), %%edi \n\t" //src[xx] | ||
| 2325 | "movzbl 1(%5, %%"REG_d"), %%esi \n\t" //src[xx+1] | ||
| 2326 | FAST_BILINEAR_X86 | ||
| 2327 | "movw %%si, "AV_STRINGIFY(VOF)"(%%"REG_D", %%"REG_a", 2) \n\t" | ||
| 2328 | |||
| 2329 | "addw %4, %%cx \n\t" //xalpha += xInc&0xFFFF | ||
| 2330 | "adc %3, %%"REG_d" \n\t" //xx+= xInc>>16 + carry | ||
| 2331 | "add $1, %%"REG_a" \n\t" | ||
| 2332 | "cmp %2, %%"REG_a" \n\t" | ||
| 2333 | " jb 1b \n\t" | ||
| 2334 | |||
| 2335 | /* GCC 3.3 makes MPlayer crash on IA-32 machines when using "g" operand here, | ||
| 2336 | which is needed to support GCC 4.0. */ | ||
| 2337 | #if ARCH_X86_64 && AV_GCC_VERSION_AT_LEAST(3,4) | ||
| 2338 | :: "m" (src1), "m" (dst), "g" (dstWidth_reg), "m" (xInc_shr16), "m" (xInc_mask), | ||
| 2339 | #else | ||
| 2340 | :: "m" (src1), "m" (dst), "m" (dstWidth_reg), "m" (xInc_shr16), "m" (xInc_mask), | ||
| 2341 | #endif | ||
| 2342 | "r" (src2) | ||
| 2343 | : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi" | ||
| 2344 | ); | ||
| 2345 | #if COMPILE_TEMPLATE_MMX2 | ||
| 2346 | } //if MMX2 can't be used | ||
| 2347 | #endif | ||
| 2348 | } | ||
| 2349 | |||
| 2350 | inline static void RENAME(hcscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src1, const uint8_t *src2, | ||
| 2351 | int srcW, int xInc, const int16_t *hChrFilter, | ||
| 2352 | const int16_t *hChrFilterPos, int hChrFilterSize, | ||
| 2353 | uint8_t *formatConvBuffer, | ||
| 2354 | uint32_t *pal) | ||
| 2355 | { | ||
| 2356 | |||
| 2357 | src1 += c->chrSrcOffset; | ||
| 2358 | src2 += c->chrSrcOffset; | ||
| 2359 | |||
| 2360 | if (c->chrToYV12) { | ||
| 2361 | c->chrToYV12(formatConvBuffer, formatConvBuffer+VOFW, src1, src2, srcW, pal); | ||
| 2362 | src1= formatConvBuffer; | ||
| 2363 | src2= formatConvBuffer+VOFW; | ||
| 2364 | } | ||
| 2365 | |||
| 2366 | if (c->hScale16) { | ||
| 2367 | c->hScale16(dst , dstWidth, (uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1); | ||
| 2368 | c->hScale16(dst+VOFW, dstWidth, (uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1); | ||
| 2369 | } else if (!c->hcscale_fast) { | ||
| 2370 | c->hScale(dst , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize); | ||
| 2371 | c->hScale(dst+VOFW, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize); | ||
| 2372 | } else { // fast bilinear upscale / crap downscale | ||
| 2373 | c->hcscale_fast(c, dst, dstWidth, src1, src2, srcW, xInc); | ||
| 2374 | } | ||
| 2375 | |||
| 2376 | if (c->chrConvertRange) | ||
| 2377 | c->chrConvertRange(dst, dstWidth); | ||
| 2378 | } | 2200 | } |
| 2201 | #endif /* COMPILE_TEMPLATE_MMX2 */ | ||
| 2379 | 2202 | ||
| 2380 | #define DEBUG_SWSCALE_BUFFERS 0 | 2203 | #if !COMPILE_TEMPLATE_MMX2 |
| 2381 | #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__) | 2204 | static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, |
| 2382 | 2205 | int lastInLumBuf, int lastInChrBuf) | |
| 2383 | static int RENAME(swScale)(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | ||
| 2384 | int srcSliceH, uint8_t* dst[], int dstStride[]) | ||
| 2385 | { | 2206 | { |
| 2386 | /* load a few things into local vars to make the code more readable? and faster */ | ||
| 2387 | const int srcW= c->srcW; | ||
| 2388 | const int dstW= c->dstW; | ||
| 2389 | const int dstH= c->dstH; | 2207 | const int dstH= c->dstH; |
| 2390 | const int chrDstW= c->chrDstW; | ||
| 2391 | const int chrSrcW= c->chrSrcW; | ||
| 2392 | const int lumXInc= c->lumXInc; | ||
| 2393 | const int chrXInc= c->chrXInc; | ||
| 2394 | const enum PixelFormat dstFormat= c->dstFormat; | ||
| 2395 | const int flags= c->flags; | 2208 | const int flags= c->flags; |
| 2209 | int16_t **lumPixBuf= c->lumPixBuf; | ||
| 2210 | int16_t **chrPixBuf= c->chrPixBuf; | ||
| 2211 | int16_t **alpPixBuf= c->alpPixBuf; | ||
| 2212 | const int vLumBufSize= c->vLumBufSize; | ||
| 2213 | const int vChrBufSize= c->vChrBufSize; | ||
| 2396 | int16_t *vLumFilterPos= c->vLumFilterPos; | 2214 | int16_t *vLumFilterPos= c->vLumFilterPos; |
| 2397 | int16_t *vChrFilterPos= c->vChrFilterPos; | 2215 | int16_t *vChrFilterPos= c->vChrFilterPos; |
| 2398 | int16_t *hLumFilterPos= c->hLumFilterPos; | ||
| 2399 | int16_t *hChrFilterPos= c->hChrFilterPos; | ||
| 2400 | int16_t *vLumFilter= c->vLumFilter; | 2216 | int16_t *vLumFilter= c->vLumFilter; |
| 2401 | int16_t *vChrFilter= c->vChrFilter; | 2217 | int16_t *vChrFilter= c->vChrFilter; |
| 2402 | int16_t *hLumFilter= c->hLumFilter; | ||
| 2403 | int16_t *hChrFilter= c->hChrFilter; | ||
| 2404 | int32_t *lumMmxFilter= c->lumMmxFilter; | 2218 | int32_t *lumMmxFilter= c->lumMmxFilter; |
| 2405 | int32_t *chrMmxFilter= c->chrMmxFilter; | 2219 | int32_t *chrMmxFilter= c->chrMmxFilter; |
| 2406 | int32_t av_unused *alpMmxFilter= c->alpMmxFilter; | 2220 | int32_t av_unused *alpMmxFilter= c->alpMmxFilter; |
| 2407 | const int vLumFilterSize= c->vLumFilterSize; | 2221 | const int vLumFilterSize= c->vLumFilterSize; |
| 2408 | const int vChrFilterSize= c->vChrFilterSize; | 2222 | const int vChrFilterSize= c->vChrFilterSize; |
| 2409 | const int hLumFilterSize= c->hLumFilterSize; | 2223 | const int chrDstY= dstY>>c->chrDstVSubSample; |
| 2410 | const int hChrFilterSize= c->hChrFilterSize; | 2224 | const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input |
| 2411 | int16_t **lumPixBuf= c->lumPixBuf; | 2225 | const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input |
| 2412 | int16_t **chrPixBuf= c->chrPixBuf; | ||
| 2413 | int16_t **alpPixBuf= c->alpPixBuf; | ||
| 2414 | const int vLumBufSize= c->vLumBufSize; | ||
| 2415 | const int vChrBufSize= c->vChrBufSize; | ||
| 2416 | uint8_t *formatConvBuffer= c->formatConvBuffer; | ||
| 2417 | const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample; | ||
| 2418 | const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample); | ||
| 2419 | int lastDstY; | ||
| 2420 | uint32_t *pal=c->pal_yuv; | ||
| 2421 | |||
| 2422 | /* vars which will change and which we need to store back in the context */ | ||
| 2423 | int dstY= c->dstY; | ||
| 2424 | int lumBufIndex= c->lumBufIndex; | ||
| 2425 | int chrBufIndex= c->chrBufIndex; | ||
| 2426 | int lastInLumBuf= c->lastInLumBuf; | ||
| 2427 | int lastInChrBuf= c->lastInChrBuf; | ||
| 2428 | |||
| 2429 | if (isPacked(c->srcFormat)) { | ||
| 2430 | src[0]= | ||
| 2431 | src[1]= | ||
| 2432 | src[2]= | ||
| 2433 | src[3]= src[0]; | ||
| 2434 | srcStride[0]= | ||
| 2435 | srcStride[1]= | ||
| 2436 | srcStride[2]= | ||
| 2437 | srcStride[3]= srcStride[0]; | ||
| 2438 | } | ||
| 2439 | srcStride[1]<<= c->vChrDrop; | ||
| 2440 | srcStride[2]<<= c->vChrDrop; | ||
| 2441 | |||
| 2442 | DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n", | ||
| 2443 | src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3], | ||
| 2444 | dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]); | ||
| 2445 | DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n", | ||
| 2446 | srcSliceY, srcSliceH, dstY, dstH); | ||
| 2447 | DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n", | ||
| 2448 | vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize); | ||
| 2449 | |||
| 2450 | if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) { | ||
| 2451 | static int warnedAlready=0; //FIXME move this into the context perhaps | ||
| 2452 | if (flags & SWS_PRINT_INFO && !warnedAlready) { | ||
| 2453 | av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n" | ||
| 2454 | " ->cannot do aligned memory accesses anymore\n"); | ||
| 2455 | warnedAlready=1; | ||
| 2456 | } | ||
| 2457 | } | ||
| 2458 | |||
| 2459 | /* Note the user might start scaling the picture in the middle so this | ||
| 2460 | will not get executed. This is not really intended but works | ||
| 2461 | currently, so people might do it. */ | ||
| 2462 | if (srcSliceY ==0) { | ||
| 2463 | lumBufIndex=-1; | ||
| 2464 | chrBufIndex=-1; | ||
| 2465 | dstY=0; | ||
| 2466 | lastInLumBuf= -1; | ||
| 2467 | lastInChrBuf= -1; | ||
| 2468 | } | ||
| 2469 | |||
| 2470 | lastDstY= dstY; | ||
| 2471 | |||
| 2472 | for (;dstY < dstH; dstY++) { | ||
| 2473 | unsigned char *dest =dst[0]+dstStride[0]*dstY; | ||
| 2474 | const int chrDstY= dstY>>c->chrDstVSubSample; | ||
| 2475 | unsigned char *uDest=dst[1]+dstStride[1]*chrDstY; | ||
| 2476 | unsigned char *vDest=dst[2]+dstStride[2]*chrDstY; | ||
| 2477 | unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL; | ||
| 2478 | |||
| 2479 | const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input | ||
| 2480 | const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)]; | ||
| 2481 | const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input | ||
| 2482 | int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input | ||
| 2483 | int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input | ||
| 2484 | int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input | ||
| 2485 | int enough_lines; | ||
| 2486 | |||
| 2487 | //handle holes (FAST_BILINEAR & weird filters) | ||
| 2488 | if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1; | ||
| 2489 | if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1; | ||
| 2490 | assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1); | ||
| 2491 | assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1); | ||
| 2492 | |||
| 2493 | DEBUG_BUFFERS("dstY: %d\n", dstY); | ||
| 2494 | DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n", | ||
| 2495 | firstLumSrcY, lastLumSrcY, lastInLumBuf); | ||
| 2496 | DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n", | ||
| 2497 | firstChrSrcY, lastChrSrcY, lastInChrBuf); | ||
| 2498 | |||
| 2499 | // Do we have enough lines in this slice to output the dstY line | ||
| 2500 | enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample); | ||
| 2501 | |||
| 2502 | if (!enough_lines) { | ||
| 2503 | lastLumSrcY = srcSliceY + srcSliceH - 1; | ||
| 2504 | lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1; | ||
| 2505 | DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n", | ||
| 2506 | lastLumSrcY, lastChrSrcY); | ||
| 2507 | } | ||
| 2508 | |||
| 2509 | //Do horizontal scaling | ||
| 2510 | while(lastInLumBuf < lastLumSrcY) { | ||
| 2511 | const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0]; | ||
| 2512 | const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3]; | ||
| 2513 | lumBufIndex++; | ||
| 2514 | assert(lumBufIndex < 2*vLumBufSize); | ||
| 2515 | assert(lastInLumBuf + 1 - srcSliceY < srcSliceH); | ||
| 2516 | assert(lastInLumBuf + 1 - srcSliceY >= 0); | ||
| 2517 | RENAME(hyscale)(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc, | ||
| 2518 | hLumFilter, hLumFilterPos, hLumFilterSize, | ||
| 2519 | formatConvBuffer, | ||
| 2520 | pal, 0); | ||
| 2521 | if (CONFIG_SWSCALE_ALPHA && alpPixBuf) | ||
| 2522 | RENAME(hyscale)(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW, lumXInc, | ||
| 2523 | hLumFilter, hLumFilterPos, hLumFilterSize, | ||
| 2524 | formatConvBuffer, | ||
| 2525 | pal, 1); | ||
| 2526 | lastInLumBuf++; | ||
| 2527 | DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n", | ||
| 2528 | lumBufIndex, lastInLumBuf); | ||
| 2529 | } | ||
| 2530 | while(lastInChrBuf < lastChrSrcY) { | ||
| 2531 | const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1]; | ||
| 2532 | const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2]; | ||
| 2533 | chrBufIndex++; | ||
| 2534 | assert(chrBufIndex < 2*vChrBufSize); | ||
| 2535 | assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH)); | ||
| 2536 | assert(lastInChrBuf + 1 - chrSrcSliceY >= 0); | ||
| 2537 | //FIXME replace parameters through context struct (some at least) | ||
| 2538 | |||
| 2539 | if (c->needs_hcscale) | ||
| 2540 | RENAME(hcscale)(c, chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc, | ||
| 2541 | hChrFilter, hChrFilterPos, hChrFilterSize, | ||
| 2542 | formatConvBuffer, | ||
| 2543 | pal); | ||
| 2544 | lastInChrBuf++; | ||
| 2545 | DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n", | ||
| 2546 | chrBufIndex, lastInChrBuf); | ||
| 2547 | } | ||
| 2548 | //wrap buf index around to stay inside the ring buffer | ||
| 2549 | if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize; | ||
| 2550 | if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize; | ||
| 2551 | if (!enough_lines) | ||
| 2552 | break; //we can't output a dstY line so let's try with the next slice | ||
| 2553 | 2226 | ||
| 2554 | c->blueDither= ff_dither8[dstY&1]; | 2227 | c->blueDither= ff_dither8[dstY&1]; |
| 2555 | if (c->dstFormat == PIX_FMT_RGB555 || c->dstFormat == PIX_FMT_BGR555) | 2228 | if (c->dstFormat == PIX_FMT_RGB555 || c->dstFormat == PIX_FMT_BGR555) |
| @@ -2557,7 +2230,7 @@ static int RENAME(swScale)(SwsContext *c, const uint8_t* src[], int srcStride[], · 1 unmodified line | |||
| 2557 | else | 2230 | else |
| 2558 | c->greenDither= ff_dither4[dstY&1]; | 2231 | c->greenDither= ff_dither4[dstY&1]; |
| 2559 | c->redDither= ff_dither8[(dstY+1)&1]; | 2232 | c->redDither= ff_dither8[(dstY+1)&1]; |
| 2560 | if (dstY < dstH-2) { | 2233 | if (dstY < dstH - 2) { |
| 2561 | const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; | 2234 | const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; |
| 2562 | const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; | 2235 | const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; |
| 2563 | const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; | 2236 | const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; |
| @@ -2606,183 +2279,52 @@ static int RENAME(swScale)(SwsContext *c, const uint8_t* src[], int srcStride[], · 42 unmodified lines | |||
| 2606 | ((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001; | 2279 | ((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001; |
| 2607 | } | 2280 | } |
| 2608 | } | 2281 | } |
| 2609 | if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) { | ||
| 2610 | const int chrSkipMask= (1<<c->chrDstVSubSample)-1; | ||
| 2611 | if (dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi | ||
| 2612 | c->yuv2nv12X(c, | ||
| 2613 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 2614 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2615 | dest, uDest, dstW, chrDstW, dstFormat); | ||
| 2616 | } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like | ||
| 2617 | const int chrSkipMask= (1<<c->chrDstVSubSample)-1; | ||
| 2618 | if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi | ||
| 2619 | if (is16BPS(dstFormat) || isNBPS(dstFormat)) { | ||
| 2620 | yuv2yuvX16inC( | ||
| 2621 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 2622 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2623 | alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW, | ||
| 2624 | dstFormat); | ||
| 2625 | } else if (vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12 | ||
| 2626 | const int16_t *lumBuf = lumSrcPtr[0]; | ||
| 2627 | const int16_t *chrBuf= chrSrcPtr[0]; | ||
| 2628 | const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL; | ||
| 2629 | c->yuv2yuv1(c, lumBuf, chrBuf, alpBuf, dest, uDest, vDest, aDest, dstW, chrDstW); | ||
| 2630 | } else { //General YV12 | ||
| 2631 | c->yuv2yuvX(c, | ||
| 2632 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 2633 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2634 | alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW); | ||
| 2635 | } | ||
| 2636 | } else { | ||
| 2637 | assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); | ||
| 2638 | assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); | ||
| 2639 | if (vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB | ||
| 2640 | int chrAlpha= vChrFilter[2*dstY+1]; | ||
| 2641 | if(flags & SWS_FULL_CHR_H_INT) { | ||
| 2642 | yuv2rgbXinC_full(c, //FIXME write a packed1_full function | ||
| 2643 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 2644 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2645 | alpSrcPtr, dest, dstW, dstY); | ||
| 2646 | } else { | ||
| 2647 | c->yuv2packed1(c, *lumSrcPtr, *chrSrcPtr, *(chrSrcPtr+1), | ||
| 2648 | alpPixBuf ? *alpSrcPtr : NULL, | ||
| 2649 | dest, dstW, chrAlpha, dstFormat, flags, dstY); | ||
| 2650 | } | ||
| 2651 | } else if (vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB | ||
| 2652 | int lumAlpha= vLumFilter[2*dstY+1]; | ||
| 2653 | int chrAlpha= vChrFilter[2*dstY+1]; | ||
| 2654 | lumMmxFilter[2]= | ||
| 2655 | lumMmxFilter[3]= vLumFilter[2*dstY ]*0x10001; | ||
| 2656 | chrMmxFilter[2]= | ||
| 2657 | chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001; | ||
| 2658 | if(flags & SWS_FULL_CHR_H_INT) { | ||
| 2659 | yuv2rgbXinC_full(c, //FIXME write a packed2_full function | ||
| 2660 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 2661 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2662 | alpSrcPtr, dest, dstW, dstY); | ||
| 2663 | } else { | ||
| 2664 | c->yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrSrcPtr, *(chrSrcPtr+1), | ||
| 2665 | alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL, | ||
| 2666 | dest, dstW, lumAlpha, chrAlpha, dstY); | ||
| 2667 | } | ||
| 2668 | } else { //general RGB | ||
| 2669 | if(flags & SWS_FULL_CHR_H_INT) { | ||
| 2670 | yuv2rgbXinC_full(c, | ||
| 2671 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 2672 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2673 | alpSrcPtr, dest, dstW, dstY); | ||
| 2674 | } else { | ||
| 2675 | c->yuv2packedX(c, | ||
| 2676 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 2677 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2678 | alpSrcPtr, dest, dstW, dstY); | ||
| 2679 | } | ||
| 2680 | } | ||
| 2681 | } | ||
| 2682 | } else { // hmm looks like we can't use MMX here without overwriting this array's tail | ||
| 2683 | const int16_t **lumSrcPtr= (const int16_t **)lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; | ||
| 2684 | const int16_t **chrSrcPtr= (const int16_t **)chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; | ||
| 2685 | const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **)alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; | ||
| 2686 | if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) { | ||
| 2687 | const int chrSkipMask= (1<<c->chrDstVSubSample)-1; | ||
| 2688 | if (dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi | ||
| 2689 | yuv2nv12XinC( | ||
| 2690 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 2691 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2692 | dest, uDest, dstW, chrDstW, dstFormat); | ||
| 2693 | } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 | ||
| 2694 | const int chrSkipMask= (1<<c->chrDstVSubSample)-1; | ||
| 2695 | if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi | ||
| 2696 | if (is16BPS(dstFormat) || isNBPS(dstFormat)) { | ||
| 2697 | yuv2yuvX16inC( | ||
| 2698 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 2699 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2700 | alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW, | ||
| 2701 | dstFormat); | ||
| 2702 | } else { | ||
| 2703 | yuv2yuvXinC( | ||
| 2704 | vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, | ||
| 2705 | vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2706 | alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW); | ||
| 2707 | } | ||
| 2708 | } else { | ||
| 2709 | assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); | ||
| 2710 | assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); | ||
| 2711 | if(flags & SWS_FULL_CHR_H_INT) { | ||
| 2712 | yuv2rgbXinC_full(c, | ||
| 2713 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 2714 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2715 | alpSrcPtr, dest, dstW, dstY); | ||
| 2716 | } else { | ||
| 2717 | yuv2packedXinC(c, | ||
| 2718 | vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, | ||
| 2719 | vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, | ||
| 2720 | alpSrcPtr, dest, dstW, dstY); | ||
| 2721 | } | ||
| 2722 | } | ||
| 2723 | } | 2282 | } |
| 2724 | } | ||
| 2725 | |||
| 2726 | if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf) | ||
| 2727 | fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255); | ||
| 2728 | |||
| 2729 | if (flags & SWS_CPU_CAPS_MMX2 ) __asm__ volatile("sfence":::"memory"); | ||
| 2730 | /* On K6 femms is faster than emms. On K7 femms is directly mapped to emms. */ | ||
| 2731 | if (flags & SWS_CPU_CAPS_3DNOW) __asm__ volatile("femms" :::"memory"); | ||
| 2732 | else __asm__ volatile("emms" :::"memory"); | ||
| 2733 | /* store changed local vars back in the context */ | ||
| 2734 | c->dstY= dstY; | ||
| 2735 | c->lumBufIndex= lumBufIndex; | ||
| 2736 | c->chrBufIndex= chrBufIndex; | ||
| 2737 | c->lastInLumBuf= lastInLumBuf; | ||
| 2738 | c->lastInChrBuf= lastInChrBuf; | ||
| 2739 | |||
| 2740 | return dstY - lastDstY; | ||
| 2741 | } | 2283 | } |
| 2284 | #endif /* !COMPILE_TEMPLATE_MMX2 */ | ||
| 2742 | 2285 | ||
| 2743 | static void RENAME(sws_init_swScale)(SwsContext *c) | 2286 | static void RENAME(sws_init_swScale)(SwsContext *c) |
| 2744 | { | 2287 | { |
| 2745 | enum PixelFormat srcFormat = c->srcFormat; | 2288 | enum PixelFormat srcFormat = c->srcFormat; |
| 2746 | 2289 | ||
| 2747 | c->yuv2nv12X = RENAME(yuv2nv12X ); | 2290 | if (!(c->flags & SWS_BITEXACT)) { |
| 2748 | c->yuv2yuv1 = RENAME(yuv2yuv1 ); | 2291 | c->yuv2yuv1 = RENAME(yuv2yuv1 ); |
| 2749 | c->yuv2yuvX = RENAME(yuv2yuvX ); | 2292 | c->yuv2yuvX = RENAME(yuv2yuvX ); |
| 2750 | c->yuv2packed1 = RENAME(yuv2packed1 ); | 2293 | c->yuv2packed1 = RENAME(yuv2packed1 ); |
| 2751 | c->yuv2packed2 = RENAME(yuv2packed2 ); | 2294 | c->yuv2packed2 = RENAME(yuv2packed2 ); |
| 2752 | c->yuv2packedX = RENAME(yuv2packedX ); | 2295 | c->yuv2packedX = RENAME(yuv2packedX ); |
| 2296 | } | ||
| 2753 | 2297 | ||
| 2754 | c->hScale = RENAME(hScale ); | 2298 | c->hScale = RENAME(hScale ); |
| 2755 | 2299 | ||
| 2756 | // Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one). | 2300 | // Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one). |
| 2301 | #if COMPILE_TEMPLATE_MMX2 | ||
| 2757 | if (c->flags & SWS_FAST_BILINEAR && c->canMMX2BeUsed) | 2302 | if (c->flags & SWS_FAST_BILINEAR && c->canMMX2BeUsed) |
| 2758 | { | 2303 | { |
| 2759 | c->hyscale_fast = RENAME(hyscale_fast); | 2304 | c->hyscale_fast = RENAME(hyscale_fast); |
| 2760 | c->hcscale_fast = RENAME(hcscale_fast); | 2305 | c->hcscale_fast = RENAME(hcscale_fast); |
| 2761 | } else { | 2306 | } else { |
| 2307 | #endif /* COMPILE_TEMPLATE_MMX2 */ | ||
| 2762 | c->hyscale_fast = NULL; | 2308 | c->hyscale_fast = NULL; |
| 2763 | c->hcscale_fast = NULL; | 2309 | c->hcscale_fast = NULL; |
| 2310 | #if COMPILE_TEMPLATE_MMX2 | ||
| 2764 | } | 2311 | } |
| 2312 | #endif /* COMPILE_TEMPLATE_MMX2 */ | ||
| 2765 | 2313 | ||
| 2766 | switch(srcFormat) { | 2314 | switch(srcFormat) { |
| 2767 | case PIX_FMT_YUYV422 : c->chrToYV12 = RENAME(yuy2ToUV); break; | 2315 | case PIX_FMT_YUYV422 : c->chrToYV12 = RENAME(yuy2ToUV); break; |
| 2768 | case PIX_FMT_UYVY422 : c->chrToYV12 = RENAME(uyvyToUV); break; | 2316 | case PIX_FMT_UYVY422 : c->chrToYV12 = RENAME(uyvyToUV); break; |
| 2769 | case PIX_FMT_NV12 : c->chrToYV12 = RENAME(nv12ToUV); break; | 2317 | case PIX_FMT_NV12 : c->chrToYV12 = RENAME(nv12ToUV); break; |
| 2770 | case PIX_FMT_NV21 : c->chrToYV12 = RENAME(nv21ToUV); break; | 2318 | case PIX_FMT_NV21 : c->chrToYV12 = RENAME(nv21ToUV); break; |
| 2771 | case PIX_FMT_YUV420P16BE: | 2319 | case PIX_FMT_GRAY16LE : |
| 2772 | case PIX_FMT_YUV422P16BE: | 2320 | case PIX_FMT_YUV420P9LE: |
| 2773 | case PIX_FMT_YUV444P16BE: c->chrToYV12 = RENAME(BEToUV); break; | 2321 | case PIX_FMT_YUV422P10LE: |
| 2322 | case PIX_FMT_YUV420P10LE: | ||
| 2774 | case PIX_FMT_YUV420P16LE: | 2323 | case PIX_FMT_YUV420P16LE: |
| 2775 | case PIX_FMT_YUV422P16LE: | 2324 | case PIX_FMT_YUV422P16LE: |
| 2776 | case PIX_FMT_YUV444P16LE: c->chrToYV12 = RENAME(LEToUV); break; | 2325 | case PIX_FMT_YUV444P16LE: c->hScale16= RENAME(hScale16); break; |
| 2777 | default: break; | 2326 | } |
| 2778 | } | 2327 | if (!c->chrSrcHSubSample) { |
| 2779 | if (c->chrSrcHSubSample) { | ||
| 2780 | switch(srcFormat) { | ||
| 2781 | case PIX_FMT_BGR24 : c->chrToYV12 = RENAME(bgr24ToUV_half); break; | ||
| 2782 | case PIX_FMT_RGB24 : c->chrToYV12 = RENAME(rgb24ToUV_half); break; | ||
| 2783 | default: break; | ||
| 2784 | } | ||
| 2785 | } else { | ||
| 2786 | switch(srcFormat) { | 2328 | switch(srcFormat) { |
| 2787 | case PIX_FMT_BGR24 : c->chrToYV12 = RENAME(bgr24ToUV); break; | 2329 | case PIX_FMT_BGR24 : c->chrToYV12 = RENAME(bgr24ToUV); break; |
| 2788 | case PIX_FMT_RGB24 : c->chrToYV12 = RENAME(rgb24ToUV); break; | 2330 | case PIX_FMT_RGB24 : c->chrToYV12 = RENAME(rgb24ToUV); break; |
| @@ -2792,16 +2334,10 @@ static void RENAME(sws_init_swScale)(SwsContext *c) · 3 unmodified lines | |||
| 2792 | 2334 | ||
| 2793 | switch (srcFormat) { | 2335 | switch (srcFormat) { |
| 2794 | case PIX_FMT_YUYV422 : | 2336 | case PIX_FMT_YUYV422 : |
| 2795 | case PIX_FMT_YUV420P16BE: | ||
| 2796 | case PIX_FMT_YUV422P16BE: | ||
| 2797 | case PIX_FMT_YUV444P16BE: | ||
| 2798 | case PIX_FMT_Y400A : | 2337 | case PIX_FMT_Y400A : |
| 2799 | case PIX_FMT_GRAY16BE : c->lumToYV12 = RENAME(yuy2ToY); break; | 2338 | c->lumToYV12 = RENAME(yuy2ToY); break; |
| 2800 | case PIX_FMT_UYVY422 : | 2339 | case PIX_FMT_UYVY422 : |
| 2801 | case PIX_FMT_YUV420P16LE: | 2340 | c->lumToYV12 = RENAME(uyvyToY); break; |
| 2802 | case PIX_FMT_YUV422P16LE: | ||
| 2803 | case PIX_FMT_YUV444P16LE: | ||
| 2804 | case PIX_FMT_GRAY16LE : c->lumToYV12 = RENAME(uyvyToY); break; | ||
| 2805 | case PIX_FMT_BGR24 : c->lumToYV12 = RENAME(bgr24ToY); break; | 2341 | case PIX_FMT_BGR24 : c->lumToYV12 = RENAME(bgr24ToY); break; |
| 2806 | case PIX_FMT_RGB24 : c->lumToYV12 = RENAME(rgb24ToY); break; | 2342 | case PIX_FMT_RGB24 : c->lumToYV12 = RENAME(rgb24ToY); break; |
| 2807 | default: break; | 2343 | default: break; |
| @@ -2812,14 +2348,4 @@ static void RENAME(sws_init_swScale)(SwsContext *c) · 4 unmodified lines | |||
| 2812 | default: break; | 2348 | default: break; |
| 2813 | } | 2349 | } |
| 2814 | } | 2350 | } |
| 2815 | |||
| 2816 | if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) { | ||
| 2817 | if (c->srcRange) { | ||
| 2818 | c->lumConvertRange = RENAME(lumRangeFromJpeg); | ||
| 2819 | c->chrConvertRange = RENAME(chrRangeFromJpeg); | ||
| 2820 | } else { | ||
| 2821 | c->lumConvertRange = RENAME(lumRangeToJpeg); | ||
| 2822 | c->chrConvertRange = RENAME(chrRangeToJpeg); | ||
| 2823 | } | ||
| 2824 | } | ||
| 2825 | } | 2351 | } |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #include "libswscale/swscale.h" | 34 | #include "libswscale/swscale.h" |
| 35 | #include "libswscale/swscale_internal.h" | 35 | #include "libswscale/swscale_internal.h" |
| 36 | #include "libavutil/x86_cpu.h" | 36 | #include "libavutil/x86_cpu.h" |
| 37 | #include "libavutil/cpu.h" | ||
| 37 | 38 | ||
| 38 | #define DITHER1XBPP // only for MMX | 39 | #define DITHER1XBPP // only for MMX |
| 39 | 40 | ||
| @@ -46,57 +47,58 @@ DECLARE_ASM_CONST(8, uint64_t, pb_03) = 0x0303030303030303ULL; · 6 unmodified lines | |||
| 46 | DECLARE_ASM_CONST(8, uint64_t, pb_07) = 0x0707070707070707ULL; | 47 | DECLARE_ASM_CONST(8, uint64_t, pb_07) = 0x0707070707070707ULL; |
| 47 | 48 | ||
| 48 | //MMX versions | 49 | //MMX versions |
| 50 | #if HAVE_MMX | ||
| 49 | #undef RENAME | 51 | #undef RENAME |
| 50 | #undef HAVE_MMX2 | 52 | #undef COMPILE_TEMPLATE_MMX2 |
| 51 | #undef HAVE_AMD3DNOW | 53 | #define COMPILE_TEMPLATE_MMX2 0 |
| 52 | #define HAVE_MMX2 0 | ||
| 53 | #define HAVE_AMD3DNOW 0 | ||
| 54 | #define RENAME(a) a ## _MMX | 54 | #define RENAME(a) a ## _MMX |
| 55 | #include "yuv2rgb_template.c" | 55 | #include "yuv2rgb_template.c" |
| 56 | #endif /* HAVE_MMX */ | ||
| 56 | 57 | ||
| 57 | //MMX2 versions | 58 | //MMX2 versions |
| 59 | #if HAVE_MMX2 | ||
| 58 | #undef RENAME | 60 | #undef RENAME |
| 59 | #undef HAVE_MMX2 | 61 | #undef COMPILE_TEMPLATE_MMX2 |
| 60 | #define HAVE_MMX2 1 | 62 | #define COMPILE_TEMPLATE_MMX2 1 |
| 61 | #define RENAME(a) a ## _MMX2 | 63 | #define RENAME(a) a ## _MMX2 |
| 62 | #include "yuv2rgb_template.c" | 64 | #include "yuv2rgb_template.c" |
| 65 | #endif /* HAVE_MMX2 */ | ||
| 63 | 66 | ||
| 64 | SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c) | 67 | SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c) |
| 65 | { | 68 | { |
| 66 | if (c->flags & SWS_CPU_CAPS_MMX2) { | 69 | int cpu_flags = av_get_cpu_flags(); |
| 70 | |||
| 71 | if (c->srcFormat != PIX_FMT_YUV420P && | ||
| 72 | c->srcFormat != PIX_FMT_YUVA420P) | ||
| 73 | return NULL; | ||
| 74 | |||
| 75 | if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) { | ||
| 67 | switch (c->dstFormat) { | 76 | switch (c->dstFormat) { |
| 68 | case PIX_FMT_RGB32: | ||
| 69 | if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { | ||
| 70 | if (HAVE_7REGS) return yuva420_rgb32_MMX2; | ||
| 71 | break; | ||
| 72 | } else return yuv420_rgb32_MMX2; | ||
| 73 | case PIX_FMT_BGR32: | ||
| 74 | if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { | ||
| 75 | if (HAVE_7REGS) return yuva420_bgr32_MMX2; | ||
| 76 | break; | ||
| 77 | } else return yuv420_bgr32_MMX2; | ||
| 78 | case PIX_FMT_RGB24: return yuv420_rgb24_MMX2; | 77 | case PIX_FMT_RGB24: return yuv420_rgb24_MMX2; |
| 79 | case PIX_FMT_BGR24: return yuv420_bgr24_MMX2; | 78 | case PIX_FMT_BGR24: return yuv420_bgr24_MMX2; |
| 80 | case PIX_FMT_RGB565: return yuv420_rgb16_MMX2; | ||
| 81 | case PIX_FMT_RGB555: return yuv420_rgb15_MMX2; | ||
| 82 | } | 79 | } |
| 83 | } | 80 | } |
| 84 | if (c->flags & SWS_CPU_CAPS_MMX) { | 81 | |
| 82 | if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) { | ||
| 85 | switch (c->dstFormat) { | 83 | switch (c->dstFormat) { |
| 86 | case PIX_FMT_RGB32: | 84 | case PIX_FMT_RGB32: |
| 87 | if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { | 85 | if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { |
| 88 | if (HAVE_7REGS) return yuva420_rgb32_MMX; | 86 | #if HAVE_7REGS |
| 89 | break; | 87 | return yuva420_rgb32_MMX; |
| 90 | } else return yuv420_rgb32_MMX; | 88 | #endif |
| 91 | case PIX_FMT_BGR32: | 89 | break; |
| 92 | if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { | 90 | } else return yuv420_rgb32_MMX; |
| 93 | if (HAVE_7REGS) return yuva420_bgr32_MMX; | 91 | case PIX_FMT_BGR32: |
| 94 | break; | 92 | if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { |
| 95 | } else return yuv420_bgr32_MMX; | 93 | #if HAVE_7REGS |
| 96 | case PIX_FMT_RGB24: return yuv420_rgb24_MMX; | 94 | return yuva420_bgr32_MMX; |
| 97 | case PIX_FMT_BGR24: return yuv420_bgr24_MMX; | 95 | #endif |
| 98 | case PIX_FMT_RGB565: return yuv420_rgb16_MMX; | 96 | break; |
| 99 | case PIX_FMT_RGB555: return yuv420_rgb15_MMX; | 97 | } else return yuv420_bgr32_MMX; |
| 98 | case PIX_FMT_RGB24: return yuv420_rgb24_MMX; | ||
| 99 | case PIX_FMT_BGR24: return yuv420_bgr24_MMX; | ||
| 100 | case PIX_FMT_RGB565: return yuv420_rgb16_MMX; | ||
| 101 | case PIX_FMT_RGB555: return yuv420_rgb15_MMX; | ||
| 100 | } | 102 | } |
| 101 | } | 103 | } |
| 102 | 104 | ||
| @@ -25,14 +25,7 @@ · 24 unmodified lines | |||
| 25 | #undef EMMS | 25 | #undef EMMS |
| 26 | #undef SFENCE | 26 | #undef SFENCE |
| 27 | 27 | ||
| 28 | #if HAVE_AMD3DNOW | 28 | #if COMPILE_TEMPLATE_MMX2 |
| 29 | /* On K6 femms is faster than emms. On K7 femms is directly mapped to emms. */ | ||
| 30 | #define EMMS "femms" | ||
| 31 | #else | ||
| 32 | #define EMMS "emms" | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #if HAVE_MMX2 | ||
| 36 | #define MOVNTQ "movntq" | 29 | #define MOVNTQ "movntq" |
| 37 | #define SFENCE "sfence" | 30 | #define SFENCE "sfence" |
| 38 | #else | 31 | #else |
| @@ -159,7 +152,8 @@ · 120 unmodified lines | |||
| 159 | } \ | 152 | } \ |
| 160 | 153 | ||
| 161 | #define YUV2RGB_ENDFUNC \ | 154 | #define YUV2RGB_ENDFUNC \ |
| 162 | __asm__ volatile (SFENCE"\n\t"EMMS); \ | 155 | __asm__ volatile (SFENCE"\n\t" \ |
| 156 | "emms \n\t"); \ | ||
| 163 | return srcSliceH; \ | 157 | return srcSliceH; \ |
| 164 | 158 | ||
| 165 | #define IF0(x) | 159 | #define IF0(x) |
| @@ -188,6 +182,7 @@ · 22 unmodified lines | |||
| 188 | "paddusb "GREEN_DITHER"(%4), %%mm2\n\t" \ | 182 | "paddusb "GREEN_DITHER"(%4), %%mm2\n\t" \ |
| 189 | "paddusb "RED_DITHER"(%4), %%mm1\n\t" \ | 183 | "paddusb "RED_DITHER"(%4), %%mm1\n\t" \ |
| 190 | 184 | ||
| 185 | #if !COMPILE_TEMPLATE_MMX2 | ||
| 191 | static inline int RENAME(yuv420_rgb15)(SwsContext *c, const uint8_t *src[], | 186 | static inline int RENAME(yuv420_rgb15)(SwsContext *c, const uint8_t *src[], |
| 192 | int srcStride[], | 187 | int srcStride[], |
| 193 | int srcSliceY, int srcSliceH, | 188 | int srcSliceY, int srcSliceH, |
| @@ -243,6 +238,7 @@ static inline int RENAME(yuv420_rgb16)(SwsContext *c, const uint8_t *src[], · 49 unmodified lines | |||
| 243 | YUV2RGB_OPERANDS | 238 | YUV2RGB_OPERANDS |
| 244 | YUV2RGB_ENDFUNC | 239 | YUV2RGB_ENDFUNC |
| 245 | } | 240 | } |
| 241 | #endif /* !COMPILE_TEMPLATE_MMX2 */ | ||
| 246 | 242 | ||
| 247 | #define RGB_PACK24(blue, red)\ | 243 | #define RGB_PACK24(blue, red)\ |
| 248 | "packuswb %%mm3, %%mm0 \n" /* R0 R2 R4 R6 R1 R3 R5 R7 */\ | 244 | "packuswb %%mm3, %%mm0 \n" /* R0 R2 R4 R6 R1 R3 R5 R7 */\ |
| @@ -259,7 +255,7 @@ static inline int RENAME(yuv420_rgb16)(SwsContext *c, const uint8_t *src[], · 10 unmodified lines | |||
| 259 | "punpckhwd %%mm6, %%mm5 \n" /* R4 G4 B4 R5 R6 G6 B6 R7 */\ | 255 | "punpckhwd %%mm6, %%mm5 \n" /* R4 G4 B4 R5 R6 G6 B6 R7 */\ |
| 260 | RGB_PACK24_B | 256 | RGB_PACK24_B |
| 261 | 257 | ||
| 262 | #if HAVE_MMX2 | 258 | #if COMPILE_TEMPLATE_MMX2 |
| 263 | DECLARE_ASM_CONST(8, int16_t, mask1101[4]) = {-1,-1, 0,-1}; | 259 | DECLARE_ASM_CONST(8, int16_t, mask1101[4]) = {-1,-1, 0,-1}; |
| 264 | DECLARE_ASM_CONST(8, int16_t, mask0010[4]) = { 0, 0,-1, 0}; | 260 | DECLARE_ASM_CONST(8, int16_t, mask0010[4]) = { 0, 0,-1, 0}; |
| 265 | DECLARE_ASM_CONST(8, int16_t, mask0110[4]) = { 0,-1,-1, 0}; | 261 | DECLARE_ASM_CONST(8, int16_t, mask0110[4]) = { 0,-1,-1, 0}; |
| @@ -366,6 +362,7 @@ static inline int RENAME(yuv420_bgr24)(SwsContext *c, const uint8_t *src[], · 100 unmodified lines | |||
| 366 | MOVNTQ " %%mm5, 16(%1)\n\t" \ | 362 | MOVNTQ " %%mm5, 16(%1)\n\t" \ |
| 367 | MOVNTQ " %%mm"alpha", 24(%1)\n\t" \ | 363 | MOVNTQ " %%mm"alpha", 24(%1)\n\t" \ |
| 368 | 364 | ||
| 365 | #if !COMPILE_TEMPLATE_MMX2 | ||
| 369 | static inline int RENAME(yuv420_rgb32)(SwsContext *c, const uint8_t *src[], | 366 | static inline int RENAME(yuv420_rgb32)(SwsContext *c, const uint8_t *src[], |
| 370 | int srcStride[], | 367 | int srcStride[], |
| 371 | int srcSliceY, int srcSliceH, | 368 | int srcSliceY, int srcSliceH, |
| @@ -386,12 +383,12 @@ static inline int RENAME(yuv420_rgb32)(SwsContext *c, const uint8_t *src[], · 14 unmodified lines | |||
| 386 | YUV2RGB_ENDFUNC | 383 | YUV2RGB_ENDFUNC |
| 387 | } | 384 | } |
| 388 | 385 | ||
| 386 | #if HAVE_7REGS && CONFIG_SWSCALE_ALPHA | ||
| 389 | static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[], | 387 | static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[], |
| 390 | int srcStride[], | 388 | int srcStride[], |
| 391 | int srcSliceY, int srcSliceH, | 389 | int srcSliceY, int srcSliceH, |
| 392 | uint8_t *dst[], int dstStride[]) | 390 | uint8_t *dst[], int dstStride[]) |
| 393 | { | 391 | { |
| 394 | #if HAVE_7REGS | ||
| 395 | int y, h_size; | 392 | int y, h_size; |
| 396 | 393 | ||
| 397 | YUV2RGB_LOOP(4) | 394 | YUV2RGB_LOOP(4) |
| @@ -406,9 +403,8 @@ static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[], · 8 unmodified lines | |||
| 406 | YUV2RGB_ENDLOOP(4) | 403 | YUV2RGB_ENDLOOP(4) |
| 407 | YUV2RGB_OPERANDS_ALPHA | 404 | YUV2RGB_OPERANDS_ALPHA |
| 408 | YUV2RGB_ENDFUNC | 405 | YUV2RGB_ENDFUNC |
| 409 | #endif | ||
| 410 | return 0; | ||
| 411 | } | 406 | } |
| 407 | #endif | ||
| 412 | 408 | ||
| 413 | static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[], | 409 | static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[], |
| 414 | int srcStride[], | 410 | int srcStride[], |
| @@ -430,12 +426,12 @@ static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[], · 15 unmodified lines | |||
| 430 | YUV2RGB_ENDFUNC | 426 | YUV2RGB_ENDFUNC |
| 431 | } | 427 | } |
| 432 | 428 | ||
| 429 | #if HAVE_7REGS && CONFIG_SWSCALE_ALPHA | ||
| 433 | static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[], | 430 | static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[], |
| 434 | int srcStride[], | 431 | int srcStride[], |
| 435 | int srcSliceY, int srcSliceH, | 432 | int srcSliceY, int srcSliceH, |
| 436 | uint8_t *dst[], int dstStride[]) | 433 | uint8_t *dst[], int dstStride[]) |
| 437 | { | 434 | { |
| 438 | #if HAVE_7REGS | ||
| 439 | int y, h_size; | 435 | int y, h_size; |
| 440 | 436 | ||
| 441 | YUV2RGB_LOOP(4) | 437 | YUV2RGB_LOOP(4) |
| @@ -450,6 +446,7 @@ static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[], · 8 unmodified lines | |||
| 450 | YUV2RGB_ENDLOOP(4) | 446 | YUV2RGB_ENDLOOP(4) |
| 451 | YUV2RGB_OPERANDS_ALPHA | 447 | YUV2RGB_OPERANDS_ALPHA |
| 452 | YUV2RGB_ENDFUNC | 448 | YUV2RGB_ENDFUNC |
| 453 | #endif | ||
| 454 | return 0; | ||
| 455 | } | 449 | } |
| 450 | #endif | ||
| 451 | |||
| 452 | #endif /* !COMPILE_TEMPLATE_MMX2 */ | ||
| @@ -32,7 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include "rgb2rgb.h" | 32 | #include "rgb2rgb.h" |
| 33 | #include "swscale.h" | 33 | #include "swscale.h" |
| 34 | #include "swscale_internal.h" | 34 | #include "swscale_internal.h" |
| 35 | #include "libavutil/x86_cpu.h" | 35 | #include "libavutil/cpu.h" |
| 36 | #include "libavutil/bswap.h" | 36 | #include "libavutil/bswap.h" |
| 37 | 37 | ||
| 38 | extern const uint8_t dither_4x4_16[4][8]; | 38 | extern const uint8_t dither_4x4_16[4][8]; |
| @@ -579,24 +579,18 @@ CLOSEYUV2RGBFUNC(1) · 540 unmodified lines | |||
| 579 | SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c) | 579 | SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c) |
| 580 | { | 580 | { |
| 581 | SwsFunc t = NULL; | 581 | SwsFunc t = NULL; |
| 582 | #if HAVE_MMX | ||
| 583 | t = ff_yuv2rgb_init_mmx(c); | ||
| 584 | #endif | ||
| 585 | #if HAVE_VIS | ||
| 586 | t = ff_yuv2rgb_init_vis(c); | ||
| 587 | #endif | ||
| 588 | #if CONFIG_MLIB | ||
| 589 | t = ff_yuv2rgb_init_mlib(c); | ||
| 590 | #endif | ||
| 591 | #if HAVE_ALTIVEC | ||
| 592 | if (c->flags & SWS_CPU_CAPS_ALTIVEC) | ||
| 593 | t = ff_yuv2rgb_init_altivec(c); | ||
| 594 | #endif | ||
| 595 | 582 | ||
| 596 | #if ARCH_BFIN | 583 | if (HAVE_MMX) { |
| 597 | if (c->flags & SWS_CPU_CAPS_BFIN) | 584 | t = ff_yuv2rgb_init_mmx(c); |
| 585 | } else if (HAVE_VIS) { | ||
| 586 | t = ff_yuv2rgb_init_vis(c); | ||
| 587 | } else if (CONFIG_MLIB) { | ||
| 588 | t = ff_yuv2rgb_init_mlib(c); | ||
| 589 | } else if (HAVE_ALTIVEC) { | ||
| 590 | t = ff_yuv2rgb_init_altivec(c); | ||
| 591 | } else if (ARCH_BFIN) { | ||
| 598 | t = ff_yuv2rgb_get_func_ptr_bfin(c); | 592 | t = ff_yuv2rgb_get_func_ptr_bfin(c); |
| 599 | #endif | 593 | } |
| 600 | 594 | ||
| 601 | if (t) | 595 | if (t) |
| 602 | return t; | 596 | return t; |