* 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 | 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 | 2862 | disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib |
| 2868 | 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 | 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 | 3157 | echo "install prefix $prefix" |
| 3160 | 3158 | echo "source path $source_path" |
| 3161 | 3159 | echo "C compiler $cc" |
| @@ -433,3 +433,49 @@ For more information about libx264 and the supported options see: · 432 unmodified lines | ||
| 433 | 433 | @url{http://www.videolan.org/developers/x264.html} |
| 434 | 434 | |
| 435 | 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 | 269 | mpegvideo.o error_resilience.o |
| 270 | 270 | OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o |
| 271 | 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 | 272 | OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ |
| 275 | 273 | h263.o ituh263dec.o mpeg4videodec.o |
| 276 | 274 | OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ |
| @@ -28,7 +28,8 @@ · 27 unmodified lines | ||
| 28 | 28 | #define AVCODEC_AC3_H |
| 29 | 29 | |
| 30 | 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 | 34 | #define AC3_MAX_COEFS 256 |
| 34 | 35 | #define AC3_BLOCK_SIZE 256 |
| @@ -158,7 +159,9 @@ typedef struct AC3EncOptions { · 123 unmodified lines | ||
| 158 | 159 | |
| 159 | 160 | /* other encoding options */ |
| 160 | 161 | int allow_per_frame_metadata; |
| 161 | − int stereo_rematrixing; | |
| 162 | + int stereo_rematrixing; | |
| 163 | + int channel_coupling; | |
| 164 | + int cpl_start; | |
| 162 | 165 | } AC3EncOptions; |
| 163 | 166 | |
| 164 | 167 | |
| @@ -58,11 +58,6 @@ · 57 unmodified lines | ||
| 58 | 58 | #include "fft.h" |
| 59 | 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 | 61 | #define AC3_OUTPUT_LFEON 8 |
| 67 | 62 | |
| 68 | 63 | #define SPX_MAX_BANDS 17 |
| @@ -53,12 +53,6 @@ const uint8_t ff_eac3_hebap_tab[64] = { · 52 unmodified lines | ||
| 53 | 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 | 57 | * Table E2.15 Default Spectral Extension Banding Structure |
| 64 | 58 | */ |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | ||
| 27 | 27 | extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3]; |
| 28 | 28 | |
| 29 | 29 | extern const uint8_t ff_eac3_hebap_tab[64]; |
| 30 | −extern const uint8_t ff_eac3_default_cpl_band_struct[18]; | |
| 31 | 30 | extern const uint8_t ff_eac3_default_spx_band_struct[17]; |
| 32 | 31 | |
| 33 | 32 | #endif /* AVCODEC_AC3DEC_DATA_H */ |
| @@ -70,6 +70,7 @@ typedef struct AC3MDCTContext { · 69 unmodified lines | ||
| 70 | 70 | FFTContext fft; ///< FFT context for MDCT calculation |
| 71 | 71 | } AC3MDCTContext; |
| 72 | 72 | |
| 73 | + | |
| 73 | 74 | /** |
| 74 | 75 | * Data for a single audio block. |
| 75 | 76 | */ |
| @@ -83,10 +84,22 @@ typedef struct AC3Block { · 7 unmodified lines | ||
| 83 | 84 | int16_t **band_psd; ///< psd per critical band |
| 84 | 85 | int16_t **mask; ///< masking curve |
| 85 | 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 | 89 | uint8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values |
| 87 | 90 | uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block |
| 91 | + int num_rematrixing_bands; ///< number of rematrixing bands | |
| 88 | 92 | uint8_t rematrixing_flags[4]; ///< rematrixing flags |
| 89 | 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 | 103 | } AC3Block; |
| 91 | 104 | |
| 92 | 105 | /** |
| @@ -133,10 +146,16 @@ typedef struct AC3EncodeContext { · 40 unmodified lines | ||
| 133 | 146 | |
| 134 | 147 | int cutoff; ///< user-specified cutoff frequency, in Hz |
| 135 | 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 | 158 | int rematrixing_enabled; ///< stereo rematrixing enabled |
| 139 | − int num_rematrixing_bands; ///< number of rematrixing bands | |
| 140 | 159 | |
| 141 | 160 | /* bitrate allocation control */ |
| 142 | 161 | int slow_gain_code; ///< slow gain code (sgaincod) |
| @@ -163,6 +182,8 @@ typedef struct AC3EncodeContext { · 20 unmodified lines | ||
| 163 | 182 | int16_t *band_psd_buffer; |
| 164 | 183 | int16_t *mask_buffer; |
| 165 | 184 | uint16_t *qmant_buffer; |
| 185 | + uint8_t *cpl_coord_exp_buffer; | |
| 186 | + uint8_t *cpl_coord_mant_buffer; | |
| 166 | 187 | |
| 167 | 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 | 258 | {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, |
| 238 | 259 | /* Other Encoding Options */ |
| 239 | 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 | 267 | {NULL} |
| 241 | 268 | }; |
| 242 | 269 | #endif |
| @@ -267,9 +294,9 @@ static void scale_coefficients(AC3EncodeContext *s); · 24 unmodified lines | ||
| 267 | 294 | |
| 268 | 295 | /** |
| 269 | 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 | 404 | * Adjust the frame size to make the average bit rate match the target bit rate. |
| 335 | 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 | 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 | 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 | 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 | 765 | if (s->channel_mode != AC3_CHMODE_STEREO) |
| 414 | 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 | 768 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 421 | 769 | block = &s->blocks[blk]; |
| 422 | 770 | block->new_rematrixing_strategy = !blk; |
| 423 | − if (!s->rematrixing_enabled) | |
| 771 | + | |
| 772 | + if (!s->rematrixing_enabled) { | |
| 773 | + block0 = block; | |
| 424 | 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 | 787 | /* calculate calculate sum of squared coeffs for one band in one block */ |
| 427 | 788 | int start = ff_ac3_rematrix_band_tab[bnd]; |
| 428 | 789 | int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); |
| 429 | 790 | CoefSumType sum[4] = {0,}; |
| 430 | 791 | for (i = start; i < end; i++) { |
| 431 | − CoefType lt = block->mdct_coef[0][i]; | |
| 432 | − CoefType rt = block->mdct_coef[1][i]; | |
| 792 | + CoefType lt = block->mdct_coef[1][i]; | |
| 793 | + CoefType rt = block->mdct_coef[2][i]; | |
| 433 | 794 | CoefType md = lt + rt; |
| 434 | 795 | CoefType sd = lt - rt; |
| 435 | 796 | MAC_COEF(sum[0], lt, lt); |
| @@ -468,21 +829,20 @@ static void apply_rematrixing(AC3EncodeContext *s) · 32 unmodified lines | ||
| 468 | 829 | if (!s->rematrixing_enabled) |
| 469 | 830 | return; |
| 470 | 831 | |
| 471 | − nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); | |
| 472 | − | |
| 473 | 832 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 474 | 833 | AC3Block *block = &s->blocks[blk]; |
| 475 | 834 | if (block->new_rematrixing_strategy) |
| 476 | 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 | 838 | if (flags[bnd]) { |
| 479 | 839 | start = ff_ac3_rematrix_band_tab[bnd]; |
| 480 | 840 | end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); |
| 481 | 841 | for (i = start; i < end; i++) { |
| 482 | − int32_t lt = block->fixed_coef[0][i]; | |
| 483 | − int32_t rt = block->fixed_coef[1][i]; | |
| 484 | − block->fixed_coef[0][i] = (lt + rt) >> 1; | |
| 485 | − block->fixed_coef[1][i] = (lt - rt) >> 1; | |
| 842 | + int32_t lt = block->fixed_coef[1][i]; | |
| 843 | + int32_t rt = block->fixed_coef[2][i]; | |
| 844 | + 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 | 860 | for (expstr = EXP_D15-1; expstr <= EXP_D45-1; expstr++) { |
| 501 | 861 | grpsize = 3 << expstr; |
| 502 | − for (i = 73; i < 256; i++) { | |
| 503 | − exponent_group_tab[expstr][i] = (i + grpsize - 4) / grpsize; | |
| 862 | + for (i = 12; i < 256; i++) { | |
| 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 | 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 | 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 | 882 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 522 | 883 | AC3Block *block = &s->blocks[blk]; |
| 523 | 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 | 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 | 907 | uint8_t *exp_strategy = s->exp_strategy[ch]; |
| 547 | 908 | uint8_t *exp = s->blocks[0].exp[ch]; |
| 548 | 909 | int exp_diff; |
| @@ -551,13 +912,18 @@ static void compute_exp_strategy(AC3EncodeContext *s) · 2 unmodified lines | ||
| 551 | 912 | reused in the next frame */ |
| 552 | 913 | exp_strategy[0] = EXP_NEW; |
| 553 | 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 | 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 | 926 | exp_strategy[blk] = EXP_NEW; |
| 558 | − else | |
| 559 | − exp_strategy[blk] = EXP_REUSE; | |
| 560 | − exp += AC3_MAX_COEFS; | |
| 561 | 927 | } |
| 562 | 928 | |
| 563 | 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 | 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 | 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 | 964 | /* for each group, compute the minimum exponent */ |
| 598 | 965 | switch(exp_strategy) { |
| 599 | 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 | 968 | uint8_t exp_min = exp[k]; |
| 602 | 969 | if (exp[k+1] < exp_min) |
| 603 | 970 | exp_min = exp[k+1]; |
| 604 | − exp[i] = exp_min; | |
| 971 | + exp[i-cpl] = exp_min; | |
| 605 | 972 | k += 2; |
| 606 | 973 | } |
| 607 | 974 | break; |
| 608 | 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 | 977 | uint8_t exp_min = exp[k]; |
| 611 | 978 | if (exp[k+1] < exp_min) |
| 612 | 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 | 981 | exp_min = exp[k+2]; |
| 615 | 982 | if (exp[k+3] < exp_min) |
| 616 | 983 | exp_min = exp[k+3]; |
| 617 | − exp[i] = exp_min; | |
| 984 | + exp[i-cpl] = exp_min; | |
| 618 | 985 | k += 4; |
| 619 | 986 | } |
| 620 | 987 | break; |
| 621 | 988 | } |
| 622 | 989 | |
| 623 | 990 | /* constraint for DC exponent */ |
| 624 | − if (exp[0] > 15) | |
| 991 | + if (!cpl && exp[0] > 15) | |
| 625 | 992 | exp[0] = 15; |
| 626 | 993 | |
| 627 | 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 | 999 | while (--i >= 0) |
| 633 | 1000 | exp[i] = FFMIN(exp[i], exp[i+1] + 2); |
| 634 | 1001 | |
| 1002 | + if (cpl) | |
| 1003 | + exp[-1] = exp[0] & ~1; | |
| 1004 | + | |
| 635 | 1005 | /* now we have the exponent values the decoder will see */ |
| 636 | 1006 | switch (exp_strategy) { |
| 637 | 1007 | case EXP_D25: |
| 638 | − for (i = nb_groups, k = nb_groups * 2; i > 0; i--) { | |
| 639 | − uint8_t exp1 = exp[i]; | |
| 1008 | + for (i = nb_groups, k = (nb_groups * 2)-cpl; i > 0; i--) { | |
| 1009 | + uint8_t exp1 = exp[i-cpl]; | |
| 640 | 1010 | exp[k--] = exp1; |
| 641 | 1011 | exp[k--] = exp1; |
| 642 | 1012 | } |
| 643 | 1013 | break; |
| 644 | 1014 | case EXP_D45: |
| 645 | − for (i = nb_groups, k = nb_groups * 4; i > 0; i--) { | |
| 646 | − exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i]; | |
| 1015 | + for (i = nb_groups, k = (nb_groups * 4)-cpl; i > 0; i--) { | |
| 1016 | + exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i-cpl]; | |
| 647 | 1017 | k -= 4; |
| 648 | 1018 | } |
| 649 | 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 | 1030 | static void encode_exponents(AC3EncodeContext *s) |
| 661 | 1031 | { |
| 662 | − int blk, blk1, ch; | |
| 1032 | + int blk, blk1, ch, cpl; | |
| 663 | 1033 | uint8_t *exp, *exp_strategy; |
| 664 | 1034 | int nb_coefs, num_reuse_blocks; |
| 665 | 1035 | |
| 666 | − for (ch = 0; ch < s->channels; ch++) { | |
| 667 | − exp = s->blocks[0].exp[ch]; | |
| 1036 | + for (ch = !s->cpl_on; ch <= s->channels; ch++) { | |
| 1037 | + exp = s->blocks[0].exp[ch] + s->start_freq[ch]; | |
| 668 | 1038 | exp_strategy = s->exp_strategy[ch]; |
| 669 | − nb_coefs = s->nb_coefs[ch]; | |
| 670 | 1039 | |
| 1040 | + cpl = (ch == CPL_CH); | |
| 671 | 1041 | blk = 0; |
| 672 | 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 | 1050 | blk1 = blk + 1; |
| 674 | 1051 | |
| 675 | 1052 | /* count the number of EXP_REUSE blocks after the current block |
| 676 | 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 | 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 | 1057 | blk1++; |
| 681 | 1058 | } |
| 682 | 1059 | num_reuse_blocks = blk1 - blk - 1; |
| 683 | 1060 | |
| 684 | 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 | 1067 | exp += AC3_MAX_COEFS * (num_reuse_blocks + 1); |
| 690 | 1068 | blk = blk1; |
| @@ -700,7 +1078,7 @@ static void encode_exponents(AC3EncodeContext *s) · 9 unmodified lines | ||
| 700 | 1078 | */ |
| 701 | 1079 | static void group_exponents(AC3EncodeContext *s) |
| 702 | 1080 | { |
| 703 | − int blk, ch, i; | |
| 1081 | + int blk, ch, i, cpl; | |
| 704 | 1082 | int group_size, nb_groups, bit_count; |
| 705 | 1083 | uint8_t *p; |
| 706 | 1084 | int delta0, delta1, delta2; |
| @@ -709,14 +1087,15 @@ static void group_exponents(AC3EncodeContext *s) · 2 unmodified lines | ||
| 709 | 1087 | bit_count = 0; |
| 710 | 1088 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 711 | 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 | 1091 | int exp_strategy = s->exp_strategy[ch][blk]; |
| 714 | 1092 | if (exp_strategy == EXP_REUSE) |
| 715 | 1093 | continue; |
| 1094 | + cpl = (ch == CPL_CH); | |
| 716 | 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 | 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 | 1100 | /* DC exponent */ |
| 722 | 1101 | exp1 = *p++; |
| @@ -783,9 +1162,7 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 60 unmodified lines | ||
| 783 | 1162 | |
| 784 | 1163 | /* assumptions: |
| 785 | 1164 | * no dynamic range codes |
| 786 | − * no channel coupling | |
| 787 | 1165 | * bit allocation parameters do not change between blocks |
| 788 | − * SNR offsets do not change between blocks | |
| 789 | 1166 | * no delta bit allocation |
| 790 | 1167 | * no skipped data |
| 791 | 1168 | * no auxilliary data |
| @@ -806,11 +1183,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 14 unmodified lines | ||
| 806 | 1183 | /* dynamic range */ |
| 807 | 1184 | frame_bits++; |
| 808 | 1185 | |
| 809 | − /* coupling strategy */ | |
| 810 | − frame_bits++; | |
| 811 | − if (!blk) | |
| 812 | − frame_bits++; | |
| 813 | − | |
| 814 | 1186 | /* exponent strategy */ |
| 815 | 1187 | frame_bits += 2 * s->fbw_channels; |
| 816 | 1188 | if (s->lfe_on) |
| @@ -821,11 +1193,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 4 unmodified lines | ||
| 821 | 1193 | if (!blk) |
| 822 | 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 | 1196 | /* delta bit allocation */ |
| 830 | 1197 | frame_bits++; |
| 831 | 1198 | |
| @@ -857,7 +1224,7 @@ static void bit_alloc_init(AC3EncodeContext *s) · 25 unmodified lines | ||
| 857 | 1224 | s->slow_gain_code = 1; |
| 858 | 1225 | s->db_per_bit_code = 3; |
| 859 | 1226 | s->floor_code = 7; |
| 860 | − for (ch = 0; ch < s->channels; ch++) | |
| 1227 | + for (ch = 0; ch <= s->channels; ch++) | |
| 861 | 1228 | s->fast_gain_code[ch] = 4; |
| 862 | 1229 | |
| 863 | 1230 | /* initial snr offset */ |
| @@ -871,6 +1238,8 @@ static void bit_alloc_init(AC3EncodeContext *s) · 7 unmodified lines | ||
| 871 | 1238 | s->bit_alloc.slow_gain = ff_ac3_slow_gain_tab[s->slow_gain_code]; |
| 872 | 1239 | s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code]; |
| 873 | 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 | 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 | 1269 | /* audio blocks */ |
| 901 | 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 | 1299 | /* stereo rematrixing */ |
| 903 | 1300 | if (s->channel_mode == AC3_CHMODE_STEREO) { |
| 904 | 1301 | frame_bits++; |
| 905 | 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 | 1306 | /* bandwidth codes & gain range */ |
| 910 | − for (ch = 0; ch < s->fbw_channels; ch++) { | |
| 911 | − if (s->exp_strategy[ch][blk] != EXP_REUSE) | |
| 912 | − frame_bits += 6 + 2; | |
| 1307 | + for (ch = 1; ch <= s->fbw_channels; ch++) { | |
| 1308 | + if (s->exp_strategy[ch][blk] != EXP_REUSE) { | |
| 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 | 1360 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 945 | 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 | 1363 | /* We only need psd and mask for calculating bap. |
| 948 | 1364 | Since we currently do not calculate bap when exponent |
| 949 | 1365 | strategy is EXP_REUSE we do not need to calculate psd or mask. */ |
| 950 | 1366 | if (s->exp_strategy[ch][blk] != EXP_REUSE) { |
| 951 | − ff_ac3_bit_alloc_calc_psd(block->exp[ch], 0, | |
| 952 | − s->nb_coefs[ch], | |
| 953 | − block->psd[ch], block->band_psd[ch]); | |
| 1367 | + ff_ac3_bit_alloc_calc_psd(block->exp[ch], s->start_freq[ch], | |
| 1368 | + block->end_freq[ch], block->psd[ch], | |
| 1369 | + block->band_psd[ch]); | |
| 954 | 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 | 1372 | ff_ac3_fast_gain_tab[s->fast_gain_code[ch]], |
| 957 | 1373 | ch == s->lfe_channel, |
| 958 | 1374 | DBA_NONE, 0, NULL, NULL, NULL, |
| @@ -970,11 +1386,12 @@ static void bit_alloc_masking(AC3EncodeContext *s) · 11 unmodified lines | ||
| 970 | 1386 | static void reset_block_bap(AC3EncodeContext *s) |
| 971 | 1387 | { |
| 972 | 1388 | int blk, ch; |
| 1389 | + int channels = s->channels + 1; | |
| 973 | 1390 | if (s->blocks[0].bap[0] == s->bap_buffer) |
| 974 | 1391 | return; |
| 975 | 1392 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 976 | − for (ch = 0; ch < s->channels; ch++) { | |
| 977 | − s->blocks[blk].bap[ch] = &s->bap_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)]; | |
| 1393 | + for (ch = 0; ch < 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 | 1417 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 1001 | 1418 | AC3Block *block = &s->blocks[blk]; |
| 1002 | 1419 | AC3Block *ref_block; |
| 1420 | + int av_uninit(ch0); | |
| 1421 | + int got_cpl = !block->cpl_in_use; | |
| 1003 | 1422 | // initialize grouped mantissa counts. these are set so that they are |
| 1004 | 1423 | // padded to the next whole group size when bits are counted in |
| 1005 | 1424 | // compute_mantissa_size_final |
| 1006 | 1425 | mant_cnt[0] = mant_cnt[3] = 0; |
| 1007 | 1426 | mant_cnt[1] = mant_cnt[2] = 2; |
| 1008 | 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 | 1435 | /* Currently the only bit allocation parameters which vary across |
| 1011 | 1436 | blocks within a frame are the exponent values. We can take |
| 1012 | 1437 | advantage of that by reusing the bit allocation pointers |
| 1013 | 1438 | whenever we reuse exponents. */ |
| 1014 | 1439 | ref_block = block->exp_ref_block[ch]; |
| 1015 | 1440 | if (s->exp_strategy[ch][blk] != EXP_REUSE) { |
| 1016 | − s->ac3dsp.bit_alloc_calc_bap(ref_block->mask[ch], | |
| 1017 | − ref_block->psd[ch], 0, | |
| 1018 | − s->nb_coefs[ch], snr_offset, | |
| 1019 | − s->bit_alloc.floor, ff_ac3_bap_tab, | |
| 1020 | − ref_block->bap[ch]); | |
| 1441 | + s->ac3dsp.bit_alloc_calc_bap(ref_block->mask[ch], ref_block->psd[ch], | |
| 1442 | + s->start_freq[ch], block->end_freq[ch], | |
| 1443 | + snr_offset, s->bit_alloc.floor, | |
| 1444 | + ff_ac3_bap_tab, ref_block->bap[ch]); | |
| 1021 | 1445 | } |
| 1022 | 1446 | mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt, |
| 1023 | − ref_block->bap[ch], | |
| 1024 | − s->nb_coefs[ch]); | |
| 1447 | + ref_block->bap[ch]+s->start_freq[ch], | |
| 1448 | + block->end_freq[ch]-s->start_freq[ch]); | |
| 1449 | + if (ch == CPL_CH) | |
| 1450 | + ch = ch0; | |
| 1025 | 1451 | } |
| 1026 | 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 | 1474 | /* if previous frame SNR offset was 1023, check if current frame can also |
| 1049 | 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 | 1477 | if (bit_alloc(s, 1023) <= bits_left) |
| 1052 | 1478 | return 0; |
| 1053 | 1479 | } |
| @@ -1071,7 +1497,7 @@ static int cbr_bit_allocation(AC3EncodeContext *s) · 17 unmodified lines | ||
| 1071 | 1497 | reset_block_bap(s); |
| 1072 | 1498 | |
| 1073 | 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 | 1501 | s->fine_snr_offset[ch] = snr_offset & 0xF; |
| 1076 | 1502 | |
| 1077 | 1503 | return 0; |
| @@ -1089,26 +1515,26 @@ static int downgrade_exponents(AC3EncodeContext *s) · 11 unmodified lines | ||
| 1089 | 1515 | { |
| 1090 | 1516 | int ch, blk; |
| 1091 | 1517 | |
| 1092 | − for (ch = 0; ch < s->fbw_channels; ch++) { | |
| 1093 | − for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { | |
| 1518 | + for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { | |
| 1519 | + for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) { | |
| 1094 | 1520 | if (s->exp_strategy[ch][blk] == EXP_D15) { |
| 1095 | 1521 | s->exp_strategy[ch][blk] = EXP_D25; |
| 1096 | 1522 | return 0; |
| 1097 | 1523 | } |
| 1098 | 1524 | } |
| 1099 | 1525 | } |
| 1100 | − for (ch = 0; ch < s->fbw_channels; ch++) { | |
| 1101 | − for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { | |
| 1526 | + for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { | |
| 1527 | + for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) { | |
| 1102 | 1528 | if (s->exp_strategy[ch][blk] == EXP_D25) { |
| 1103 | 1529 | s->exp_strategy[ch][blk] = EXP_D45; |
| 1104 | 1530 | return 0; |
| 1105 | 1531 | } |
| 1106 | 1532 | } |
| 1107 | 1533 | } |
| 1108 | − for (ch = 0; ch < s->fbw_channels; ch++) { | |
| 1109 | − /* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if | |
| 1110 | − the block number > 0 */ | |
| 1111 | − for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) { | |
| 1534 | + /* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if | |
| 1535 | + the block number > 0 */ | |
| 1536 | + for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) { | |
| 1537 | + for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) { | |
| 1112 | 1538 | if (s->exp_strategy[ch][blk] > EXP_REUSE) { |
| 1113 | 1539 | s->exp_strategy[ch][blk] = EXP_REUSE; |
| 1114 | 1540 | return 0; |
| @@ -1135,7 +1561,18 @@ static int compute_bit_allocation(AC3EncodeContext *s) · 20 unmodified lines | ||
| 1135 | 1561 | |
| 1136 | 1562 | ret = cbr_bit_allocation(s); |
| 1137 | 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 | 1576 | if (!downgrade_exponents(s)) { |
| 1140 | 1577 | extract_exponents(s); |
| 1141 | 1578 | encode_exponents(s); |
| @@ -1189,12 +1626,13 @@ static inline int asym_quant(int c, int e, int qbits) · 47 unmodified lines | ||
| 1189 | 1626 | * Quantize a set of mantissas for a single channel in a single block. |
| 1190 | 1627 | */ |
| 1191 | 1628 | static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, |
| 1192 | − uint8_t *exp, | |
| 1193 | − uint8_t *bap, uint16_t *qmant, int n) | |
| 1629 | + uint8_t *exp, uint8_t *bap, | |
| 1630 | + uint16_t *qmant, int start_freq, | |
| 1631 | + int end_freq) | |
| 1194 | 1632 | { |
| 1195 | 1633 | int i; |
| 1196 | 1634 | |
| 1197 | − for (i = 0; i < n; i++) { | |
| 1635 | + for (i = start_freq; i < end_freq; i++) { | |
| 1198 | 1636 | int v; |
| 1199 | 1637 | int c = fixed_coef[i]; |
| 1200 | 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 | 1723 | static void quantize_mantissas(AC3EncodeContext *s) |
| 1286 | 1724 | { |
| 1287 | − int blk, ch; | |
| 1288 | − | |
| 1725 | + int blk, ch, ch0=0, got_cpl; | |
| 1289 | 1726 | |
| 1290 | 1727 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 1291 | 1728 | AC3Block *block = &s->blocks[blk]; |
| 1292 | 1729 | AC3Block *ref_block; |
| 1293 | 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 | 1739 | ref_block = block->exp_ref_block[ch]; |
| 1297 | 1740 | quantize_mantissas_blk_ch(&m, block->fixed_coef[ch], |
| 1298 | − ref_block->exp[ch], ref_block->bap[ch], | |
| 1299 | − block->qmant[ch], s->nb_coefs[ch]); | |
| 1741 | + ref_block->exp[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 | 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 | 1814 | AC3Block *block = &s->blocks[blk]; |
| 1368 | 1815 | |
| 1369 | 1816 | /* block switching */ |
| @@ -1378,11 +1825,38 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 8 unmodified lines | ||
| 1378 | 1825 | put_bits(&s->pb, 1, 0); |
| 1379 | 1826 | |
| 1380 | 1827 | /* channel coupling */ |
| 1381 | − if (!blk) { | |
| 1382 | − put_bits(&s->pb, 1, 1); /* coupling strategy present */ | |
| 1383 | − put_bits(&s->pb, 1, 0); /* no coupling strategy */ | |
| 1384 | − } else { | |
| 1385 | − put_bits(&s->pb, 1, 0); /* no new coupling strategy */ | |
| 1828 | + put_bits(&s->pb, 1, block->new_cpl_strategy); | |
| 1829 | + if (block->new_cpl_strategy) { | |
| 1830 | + put_bits(&s->pb, 1, block->cpl_in_use); | |
| 1831 | + if (block->cpl_in_use) { | |
| 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 | 1862 | /* stereo rematrixing */ |
| @@ -1390,40 +1864,41 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 1 unmodified line | ||
| 1390 | 1864 | put_bits(&s->pb, 1, block->new_rematrixing_strategy); |
| 1391 | 1865 | if (block->new_rematrixing_strategy) { |
| 1392 | 1866 | /* rematrixing flags */ |
| 1393 | − for (rbnd = 0; rbnd < s->num_rematrixing_bands; rbnd++) | |
| 1394 | − put_bits(&s->pb, 1, block->rematrixing_flags[rbnd]); | |
| 1867 | + for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) | |
| 1868 | + put_bits(&s->pb, 1, block->rematrixing_flags[bnd]); | |
| 1395 | 1869 | } |
| 1396 | 1870 | } |
| 1397 | 1871 | |
| 1398 | 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 | 1874 | put_bits(&s->pb, 2, s->exp_strategy[ch][blk]); |
| 1401 | 1875 | if (s->lfe_on) |
| 1402 | 1876 | put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]); |
| 1403 | 1877 | |
| 1404 | 1878 | /* bandwidth */ |
| 1405 | − for (ch = 0; ch < s->fbw_channels; ch++) { | |
| 1406 | − if (s->exp_strategy[ch][blk] != EXP_REUSE) | |
| 1879 | + for (ch = 1; ch <= s->fbw_channels; ch++) { | |
| 1880 | + if (s->exp_strategy[ch][blk] != EXP_REUSE && !block->channel_in_cpl[ch]) | |
| 1407 | 1881 | put_bits(&s->pb, 6, s->bandwidth_code); |
| 1408 | 1882 | } |
| 1409 | 1883 | |
| 1410 | 1884 | /* exponents */ |
| 1411 | − for (ch = 0; ch < s->channels; ch++) { | |
| 1885 | + for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { | |
| 1412 | 1886 | int nb_groups; |
| 1887 | + int cpl = (ch == CPL_CH); | |
| 1413 | 1888 | |
| 1414 | 1889 | if (s->exp_strategy[ch][blk] == EXP_REUSE) |
| 1415 | 1890 | continue; |
| 1416 | 1891 | |
| 1417 | 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 | 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 | 1897 | for (i = 1; i <= nb_groups; i++) |
| 1423 | 1898 | put_bits(&s->pb, 7, block->grouped_exp[ch][i]); |
| 1424 | 1899 | |
| 1425 | 1900 | /* gain range info */ |
| 1426 | − if (ch != s->lfe_channel) | |
| 1901 | + if (ch != s->lfe_channel && !cpl) | |
| 1427 | 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 | 1916 | /* snr offset */ |
| 1442 | − put_bits(&s->pb, 1, baie); | |
| 1443 | − if (baie) { | |
| 1917 | + put_bits(&s->pb, 1, block->new_snr_offsets); | |
| 1918 | + if (block->new_snr_offsets) { | |
| 1444 | 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 | 1921 | put_bits(&s->pb, 4, s->fine_snr_offset[ch]); |
| 1447 | 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 | 1935 | put_bits(&s->pb, 1, 0); /* no delta bit allocation */ |
| 1452 | 1936 | put_bits(&s->pb, 1, 0); /* no data to skip */ |
| 1453 | 1937 | |
| 1454 | 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 | 1941 | int b, q; |
| 1457 | − AC3Block *ref_block = block->exp_ref_block[ch]; | |
| 1458 | − for (i = 0; i < s->nb_coefs[ch]; i++) { | |
| 1942 | + AC3Block *ref_block; | |
| 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 | 1951 | q = block->qmant[ch][i]; |
| 1460 | 1952 | b = ref_block->bap[ch][i]; |
| 1461 | 1953 | switch (b) { |
| @@ -1469,6 +1961,8 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 7 unmodified lines | ||
| 1469 | 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 | 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 | 2357 | compute_rematrixing_strategy(s); |
| 1858 | 2358 | |
| 1859 | 2359 | apply_rematrixing(s); |
| @@ -1934,7 +2434,7 @@ static av_cold int set_channel_info(AC3EncodeContext *s, int channels, · 74 unmodified lines | ||
| 1934 | 2434 | s->lfe_on = !!(ch_layout & AV_CH_LOW_FREQUENCY); |
| 1935 | 2435 | s->channels = channels; |
| 1936 | 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 | 2438 | if (s->lfe_on) |
| 1939 | 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 | 2533 | s->rematrixing_enabled = s->options.stereo_rematrixing && |
| 2034 | 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 | 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 | 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 | 2554 | if (s->cutoff) { |
| 2050 | 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 | 2564 | /* set number of coefficients for each channel */ |
| 2060 | − for (ch = 0; ch < s->fbw_channels; ch++) { | |
| 2061 | − s->nb_coefs[ch] = s->bandwidth_code * 3 + 73; | |
| 2565 | + for (ch = 1; ch <= s->fbw_channels; ch++) { | |
| 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 | 2618 | int blk, ch; |
| 2071 | 2619 | AC3EncodeContext *s = avctx->priv_data; |
| 2620 | + int channels = s->channels + 1; /* includes coupling channel */ | |
| 2072 | 2621 | |
| 2073 | 2622 | FF_ALLOC_OR_GOTO(avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples), |
| 2074 | 2623 | alloc_fail); |
| @@ -2077,74 +2626,90 @@ static av_cold int allocate_buffers(AVCodecContext *avctx) · 2 unmodified lines | ||
| 2077 | 2626 | (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples), |
| 2078 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 2653 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 2099 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 2679 | /* arrangement: block, channel, coeff */ |
| 2119 | − block->bap[ch] = &s->bap_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; | |
| 2120 | − block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; | |
| 2121 | − block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * s->channels + ch)]; | |
| 2122 | − block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; | |
| 2123 | − block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * s->channels + ch)]; | |
| 2124 | − block->mask[ch] = &s->mask_buffer [64 * (blk * s->channels + ch)]; | |
| 2125 | − block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; | |
| 2680 | + block->bap[ch] = &s->bap_buffer [AC3_MAX_COEFS * (blk * channels + ch)]; | |
| 2681 | + block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * channels + ch)]; | |
| 2682 | + block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * channels + ch)]; | |
| 2683 | + block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * channels + ch)]; | |
| 2684 | + block->mask[ch] = &s->mask_buffer [64 * (blk * channels + ch)]; | |
| 2685 | + block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * 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 | 2691 | /* arrangement: channel, block, coeff */ |
| 2128 | 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 | 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 | 2699 | AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail); |
| 2135 | 2700 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 2136 | 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 | 2703 | sizeof(*block->fixed_coef), alloc_fail); |
| 2139 | − for (ch = 0; ch < s->channels; ch++) | |
| 2140 | − block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)]; | |
| 2704 | + for (ch = 0; ch < channels; ch++) | |
| 2705 | + block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; | |
| 2141 | 2706 | } |
| 2142 | 2707 | } else { |
| 2143 | 2708 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 2144 | 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 | 2711 | sizeof(*block->fixed_coef), alloc_fail); |
| 2147 | − for (ch = 0; ch < s->channels; ch++) | |
| 2712 | + for (ch = 0; ch < channels; ch++) | |
| 2148 | 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 | 102 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
| 103 | 103 | AC3Block *block = &s->blocks[blk]; |
| 104 | − for (ch = 0; ch < s->channels; ch++) { | |
| 104 | + for (ch = 1; ch <= s->channels; ch++) { | |
| 105 | 105 | s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS, |
| 106 | 106 | block->coeff_shift[ch]); |
| 107 | 107 | } |
| @@ -93,8 +93,10 @@ static int normalize_samples(AC3EncodeContext *s) · 92 unmodified lines | ||
| 93 | 93 | */ |
| 94 | 94 | static void scale_coefficients(AC3EncodeContext *s) |
| 95 | 95 | { |
| 96 | − s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer, s->mdct_coef_buffer, | |
| 97 | − AC3_MAX_COEFS * AC3_MAX_BLOCKS * s->channels); | |
| 96 | + int chan_size = AC3_MAX_COEFS * AC3_MAX_BLOCKS; | |
| 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 | 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 | 148 | /* AC-3 MDCT window */ |
| 142 | 149 | |
| 143 | 150 | /* MDCT window */ |
| @@ -39,6 +39,7 @@ extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; · 38 unmodified lines | ||
| 39 | 39 | extern const uint16_t ff_ac3_sample_rate_tab[3]; |
| 40 | 40 | extern const uint16_t ff_ac3_bitrate_tab[19]; |
| 41 | 41 | extern const uint8_t ff_ac3_rematrix_band_tab[5]; |
| 42 | +extern const uint8_t ff_eac3_default_cpl_band_struct[18]; | |
| 42 | 43 | extern const int16_t ff_ac3_window[AC3_WINDOW_SIZE/2]; |
| 43 | 44 | extern const uint8_t ff_ac3_log_add_tab[260]; |
| 44 | 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 | 156 | REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau); |
| 157 | 157 | REGISTER_DECODER (MPEG2_CRYSTALHD, mpeg2_crystalhd); |
| 158 | 158 | REGISTER_DECODER (MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); |
| 159 | − REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1); | |
| 159 | + REGISTER_DECODER (MSMPEG4V1, msmpeg4v1); | |
| 160 | 160 | REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); |
| 161 | 161 | REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); |
| 162 | 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 | 631 | void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); |
| 639 | 632 | void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx); |
| 640 | 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 | 645 | void ff_mlp_init(DSPContext* c, AVCodecContext *avctx); |
| 653 | 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) | |
| 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 | −} | |
| 649 | +#if ARCH_ARM | |
| 669 | 650 | |
| 670 | −#elif ARCH_ARM | |
| 671 | 651 | |
| 672 | 652 | #if HAVE_NEON |
| 673 | 653 | # define STRIDE_ALIGN 16 |
| @@ -638,15 +638,6 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) · 637 unmodified lines | ||
| 638 | 638 | s->low_delay= s->max_b_frames ? 0 : 1; |
| 639 | 639 | avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); |
| 640 | 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 | 641 | case CODEC_ID_MSMPEG4V2: |
| 651 | 642 | s->out_format = FMT_H263; |
| 652 | 643 | s->h263_msmpeg4 = 1; |
| @@ -3807,18 +3798,6 @@ AVCodec ff_h263p_encoder = { · 3154 unmodified lines | ||
| 3807 | 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 | 3801 | AVCodec ff_msmpeg4v2_encoder = { |
| 3823 | 3802 | "msmpeg4v2", |
| 3824 | 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 | 846 | int pred, extquant; |
| 847 | 847 | int extrabits = 0; |
| 848 | 848 | |
| 849 | − if(s->msmpeg4_version==1){ | |
| 850 | − int32_t *dc_val; | |
| 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); | |
| 849 | + int16_t *dc_val; | |
| 850 | + pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); | |
| 858 | 851 | |
| 859 | − /* update predictor */ | |
| 860 | − if (n < 4) { | |
| 861 | − *dc_val = level * s->y_dc_scale; | |
| 862 | − } else { | |
| 863 | − *dc_val = level * s->c_dc_scale; | |
| 864 | − } | |
| 852 | + /* update predictor */ | |
| 853 | + if (n < 4) { | |
| 854 | + *dc_val = level * s->y_dc_scale; | |
| 855 | + } else { | |
| 856 | + *dc_val = level * s->c_dc_scale; | |
| 865 | 857 | } |
| 866 | 858 | |
| 867 | 859 | /* do the prediction */ |
| @@ -54,8 +54,7 @@ int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); · 53 unmodified lines | ||
| 54 | 54 | CONFIG_MSMPEG4V3_DECODER || \ |
| 55 | 55 | CONFIG_WMV2_DECODER || \ |
| 56 | 56 | CONFIG_VC1_DECODER) |
| 57 | −#define CONFIG_MSMPEG4_ENCODER (CONFIG_MSMPEG4V1_ENCODER || \ | |
| 58 | − CONFIG_MSMPEG4V2_ENCODER || \ | |
| 57 | +#define CONFIG_MSMPEG4_ENCODER (CONFIG_MSMPEG4V2_ENCODER || \ | |
| 59 | 58 | CONFIG_MSMPEG4V3_ENCODER || \ |
| 60 | 59 | CONFIG_WMV2_ENCODER) |
| 61 | 60 | |
| @@ -39,6 +39,8 @@ typedef struct TiffContext { · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | int width, height; |
| 41 | 41 | unsigned int bpp, bppcount; |
| 42 | + uint32_t palette[256]; | |
| 43 | + int palette_is_set; | |
| 42 | 44 | int le; |
| 43 | 45 | enum TiffCompr compr; |
| 44 | 46 | int invert; |
| @@ -255,11 +257,15 @@ static int init_image(TiffContext *s) · 210 unmodified lines | ||
| 255 | 257 | av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
| 256 | 258 | return ret; |
| 257 | 259 | } |
| 258 | − if (s->bpp == 8 && s->picture.data[1]){ | |
| 259 | − /* make default grayscale pal */ | |
| 260 | − pal = (uint32_t *) s->picture.data[1]; | |
| 261 | − for (i = 0; i < 256; i++) | |
| 262 | − pal[i] = i * 0x010101; | |
| 260 | + if (s->avctx->pix_fmt == PIX_FMT_PAL8) { | |
| 261 | + if (s->palette_is_set) { | |
| 262 | + memcpy(s->picture.data[1], s->palette, sizeof(s->palette)); | |
| 263 | + } else { | |
| 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 | 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 | 448 | s->fill_order = value - 1; |
| 443 | 449 | break; |
| 444 | 450 | case TIFF_PAL: |
| 445 | − if(s->avctx->pix_fmt != PIX_FMT_PAL8){ | |
| 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]; | |
| 451 | + pal = (uint32_t *) s->palette; | |
| 450 | 452 | off = type_sizes[type]; |
| 451 | 453 | rp = buf; |
| 452 | 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 | 461 | j |= tget(&bp, type, s->le) >> off; |
| 460 | 462 | pal[i] = j; |
| 461 | 463 | } |
| 464 | + s->palette_is_set = 1; | |
| 462 | 465 | break; |
| 463 | 466 | case TIFF_PLANAR: |
| 464 | 467 | if(value == 2){ |
| @@ -287,13 +287,8 @@ zrmjpeg · 286 unmodified lines | ||
| 287 | 287 | CpuCaps gCpuCaps; //FIXME initialize this so optims work |
| 288 | 288 | |
| 289 | 289 | |
| 290 | −//exact copy from vf_scale.c | |
| 291 | 290 | int get_sws_cpuflags(void){ |
| 292 | − return | |
| 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); | |
| 291 | + return 0; | |
| 297 | 292 | } |
| 298 | 293 | |
| 299 | 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 | 343 | if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = PIX_FMT_PAL8; |
| 349 | 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 | 349 | typedef struct { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | * memory buffer source API for video |
| 28 | 28 | */ |
| 29 | 29 | |
| 30 | + | |
| 30 | 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 | 276 | ape->frames[0].nblocks = ape->blocksperframe; |
| 277 | 277 | ape->frames[0].skip = 0; |
| 278 | 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 | 280 | ape->frames[i].nblocks = ape->blocksperframe; |
| 281 | 281 | ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; |
| 282 | 282 | ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include "config.h" |
| 38 | 38 | #include "attributes.h" |
| 39 | 39 | #include "timer.h" |
| 40 | +#include "cpu.h" | |
| 40 | 41 | |
| 41 | 42 | #ifndef attribute_align_arg |
| 42 | 43 | #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2) |
| @@ -222,4 +223,19 @@ · 179 unmodified lines | ||
| 222 | 223 | # define ONLY_IF_THREADS_ENABLED(x) NULL |
| 223 | 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 | 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 | 79 | void ff_bfin_get_unscaled_swscale(SwsContext *c) |
| 80 | 80 | { |
| 81 | 81 | SwsFunc swScale = c->swScale; |
| 82 | − if (c->flags & SWS_CPU_CAPS_BFIN) | |
| 83 | − if (c->dstFormat == PIX_FMT_YUV420P) | |
| 84 | − if (c->srcFormat == PIX_FMT_UYVY422) { | |
| 85 | − av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized uyvytoyv12_unscaled\n"); | |
| 86 | − c->swScale = uyvytoyv12_unscaled; | |
| 87 | − } | |
| 88 | − if (c->dstFormat == PIX_FMT_YUV420P) | |
| 89 | − if (c->srcFormat == PIX_FMT_YUYV422) { | |
| 90 | − av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized yuyvtoyv12_unscaled\n"); | |
| 91 | − c->swScale = yuyvtoyv12_unscaled; | |
| 92 | − } | |
| 82 | + | |
| 83 | + if (c->dstFormat == PIX_FMT_YUV420P && c->srcFormat == PIX_FMT_UYVY422) { | |
| 84 | + av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized uyvytoyv12_unscaled\n"); | |
| 85 | + c->swScale = uyvytoyv12_unscaled; | |
| 86 | + } | |
| 87 | + if (c->dstFormat == PIX_FMT_YUV420P && c->srcFormat == PIX_FMT_YUYV422) { | |
| 88 | + av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized yuyvtoyv12_unscaled\n"); | |
| 89 | + c->swScale = yuyvtoyv12_unscaled; | |
| 90 | + } | |
| 93 | 91 | } |
| @@ -33,31 +33,6 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 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 | 36 | int main(int argc, char **argv) |
| 62 | 37 | { |
| 63 | 38 | int i, funcNum; |
| @@ -70,9 +45,7 @@ int main(int argc, char **argv) · 6 unmodified lines | ||
| 70 | 45 | return -1; |
| 71 | 46 | |
| 72 | 47 | av_log(NULL, AV_LOG_INFO, "memory corruption test ...\n"); |
| 73 | − args_parse(argc, argv); | |
| 74 | − av_log(NULL, AV_LOG_INFO, "CPU capabilities forced to %x\n", cpu_caps); | |
| 75 | − sws_rgb2rgb_init(cpu_caps); | |
| 48 | + sws_rgb2rgb_init(); | |
| 76 | 49 | |
| 77 | 50 | for(funcNum=0; ; funcNum++) { |
| 78 | 51 | struct func_info_s { |
| @@ -48,12 +48,6 @@ static const AVOption options[] = { · 47 unmodified lines | ||
| 48 | 48 | { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_SPLINE }, INT_MIN, INT_MAX, VE, "sws_flags" }, |
| 49 | 49 | { "print_info", "print info", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_PRINT_INFO }, INT_MIN, INT_MAX, VE, "sws_flags" }, |
| 50 | 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 | 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 | 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 | 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 | 23 | #include "swscale_altivec_template.c" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | +#if COMPILE_TEMPLATE_ALTIVEC | |
| 26 | 27 | static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize, |
| 27 | 28 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc, |
| 28 | 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 | 31 | yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize, |
| 32 | 32 | chrFilter, chrSrc, chrFilterSize, |
| 33 | 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 | 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 | 40 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, |
| 94 | 41 | const int16_t **alpSrc, uint8_t *dest, long dstW, long dstY) |
| 95 | 42 | { |
| 96 | −#if COMPILE_TEMPLATE_ALTIVEC | |
| 97 | 43 | /* The following list of supported dstFormat values should |
| 98 | 44 | match what's found in the body of ff_yuv2packedX_altivec() */ |
| 99 | 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 | 50 | chrFilter, chrSrc, chrFilterSize, |
| 105 | 51 | dest, dstW, dstY); |
| 106 | 52 | else |
| 107 | −#endif | |
| 108 | 53 | yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize, |
| 109 | 54 | chrFilter, chrSrc, chrFilterSize, |
| 110 | 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 | 60 | static void RENAME(sws_init_swScale)(SwsContext *c) |
| 768 | 61 | { |
| 769 | 62 | enum PixelFormat srcFormat = c->srcFormat; |
| 770 | 63 | |
| 771 | − c->yuv2nv12X = RENAME(yuv2nv12X ); | |
| 772 | − c->yuv2yuv1 = RENAME(yuv2yuv1 ); | |
| 773 | 64 | c->yuv2yuvX = RENAME(yuv2yuvX ); |
| 774 | − c->yuv2packed1 = RENAME(yuv2packed1 ); | |
| 775 | − c->yuv2packed2 = RENAME(yuv2packed2 ); | |
| 776 | 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 | 94 | #include "libswscale/rgb2rgb.h" |
| 95 | 95 | #include "libswscale/swscale.h" |
| 96 | 96 | #include "libswscale/swscale_internal.h" |
| 97 | +#include "libavutil/cpu.h" | |
| 97 | 98 | |
| 98 | 99 | #undef PROFILE_THE_BEAST |
| 99 | 100 | #undef INC_SCALING |
| @@ -692,7 +693,7 @@ static int altivec_uyvy_rgb32 (SwsContext *c, · 592 unmodified lines | ||
| 692 | 693 | */ |
| 693 | 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 | 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 | 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 | 121 | rgb2rgb_init_c(); |
| 122 | −#if HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX | |
| 123 | − rgb2rgb_init_x86(flags); | |
| 124 | −#endif /* HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX */ | |
| 122 | + if (HAVE_MMX) | |
| 123 | + rgb2rgb_init_x86(); | |
| 125 | 124 | } |
| 126 | 125 | |
| 127 | 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 | 166 | long width, long height, |
| 167 | 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 | 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 | 281 | static inline void rgb15to32_c(const uint8_t *src, uint8_t *dst, long src_size) |
| 301 | 282 | { |
| 302 | 283 | const uint16_t *end; |
| @@ -63,6 +63,7 @@ untested special converters · 62 unmodified lines | ||
| 63 | 63 | #include "libavutil/avassert.h" |
| 64 | 64 | #include "libavutil/intreadwrite.h" |
| 65 | 65 | #include "libavutil/x86_cpu.h" |
| 66 | +#include "libavutil/cpu.h" | |
| 66 | 67 | #include "libavutil/avutil.h" |
| 67 | 68 | #include "libavutil/mathematics.h" |
| 68 | 69 | #include "libavutil/bswap.h" |
| @@ -71,10 +72,6 @@ untested special converters · 2 unmodified lines | ||
| 71 | 72 | #undef MOVNTQ |
| 72 | 73 | #undef PAVGB |
| 73 | 74 | |
| 74 | −//#undef HAVE_MMX2 | |
| 75 | −//#define HAVE_AMD3DNOW | |
| 76 | −//#undef HAVE_MMX | |
| 77 | −//#undef ARCH_X86 | |
| 78 | 75 | #define DITHER1XBPP |
| 79 | 76 | |
| 80 | 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 | 1260 | //Note: we have C, MMX, MMX2, 3DNOW versions, there is no 3DNOW+MMX2 one |
| 1264 | 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 | 1263 | #define COMPILE_TEMPLATE_MMX2 0 |
| 1310 | −#define COMPILE_TEMPLATE_AMD3DNOW 0 | |
| 1311 | 1264 | #define COMPILE_TEMPLATE_ALTIVEC 0 |
| 1312 | 1265 | |
| 1313 | 1266 | #include "swscale_template.c" |
| 1314 | 1267 | |
| 1315 | −#if COMPILE_ALTIVEC | |
| 1268 | +#if HAVE_ALTIVEC | |
| 1316 | 1269 | #undef RENAME |
| 1317 | 1270 | #undef COMPILE_TEMPLATE_ALTIVEC |
| 1318 | 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 | 1273 | #include "ppc/swscale_template.c" |
| 1321 | 1274 | #endif |
| 1322 | 1275 | |
| 1323 | −#if ARCH_X86 | |
| 1324 | − | |
| 1325 | 1276 | //MMX versions |
| 1326 | −#if COMPILE_MMX | |
| 1277 | +#if HAVE_MMX | |
| 1327 | 1278 | #undef RENAME |
| 1328 | −#undef COMPILE_TEMPLATE_MMX | |
| 1329 | 1279 | #undef COMPILE_TEMPLATE_MMX2 |
| 1330 | −#undef COMPILE_TEMPLATE_AMD3DNOW | |
| 1331 | −#define COMPILE_TEMPLATE_MMX 1 | |
| 1332 | 1280 | #define COMPILE_TEMPLATE_MMX2 0 |
| 1333 | −#define COMPILE_TEMPLATE_AMD3DNOW 0 | |
| 1334 | 1281 | #define RENAME(a) a ## _MMX |
| 1335 | 1282 | #include "x86/swscale_template.c" |
| 1336 | 1283 | #endif |
| 1337 | 1284 | |
| 1338 | 1285 | //MMX2 versions |
| 1339 | −#if COMPILE_MMX2 | |
| 1286 | +#if HAVE_MMX2 | |
| 1340 | 1287 | #undef RENAME |
| 1341 | −#undef COMPILE_TEMPLATE_MMX | |
| 1342 | 1288 | #undef COMPILE_TEMPLATE_MMX2 |
| 1343 | −#undef COMPILE_TEMPLATE_AMD3DNOW | |
| 1344 | −#define COMPILE_TEMPLATE_MMX 1 | |
| 1345 | 1289 | #define COMPILE_TEMPLATE_MMX2 1 |
| 1346 | −#define COMPILE_TEMPLATE_AMD3DNOW 0 | |
| 1347 | 1290 | #define RENAME(a) a ## _MMX2 |
| 1348 | 1291 | #include "x86/swscale_template.c" |
| 1349 | 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 | 1294 | SwsFunc ff_getSwsFunc(SwsContext *c) |
| 1367 | 1295 | { |
| 1296 | + int cpu_flags = av_get_cpu_flags(); | |
| 1297 | + | |
| 1368 | 1298 | sws_init_swScale_c(c); |
| 1369 | 1299 | |
| 1370 | −#if CONFIG_RUNTIME_CPUDETECT | |
| 1371 | −#if ARCH_X86 | |
| 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) { | |
| 1300 | +#if HAVE_MMX | |
| 1301 | + if (cpu_flags & AV_CPU_FLAG_MMX) | |
| 1380 | 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 | 1303 | #endif |
| 1391 | −#endif /* ARCH_X86 */ | |
| 1392 | −#else //CONFIG_RUNTIME_CPUDETECT | |
| 1393 | −#if COMPILE_TEMPLATE_MMX2 | |
| 1394 | − sws_init_swScale_MMX2(c); | |
| 1395 | − return swScale_MMX2; | |
| 1396 | −#elif COMPILE_TEMPLATE_AMD3DNOW | |
| 1397 | − sws_init_swScale_3DNow(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; | |
| 1304 | +#if HAVE_MMX2 | |
| 1305 | + if (cpu_flags & AV_CPU_FLAG_MMX2) | |
| 1306 | + sws_init_swScale_MMX2(c); | |
| 1307 | +#endif | |
| 1308 | +#if HAVE_ALTIVEC | |
| 1309 | + if (cpu_flags & AV_CPU_FLAG_ALTIVEC) | |
| 1310 | + sws_init_swScale_altivec(c); | |
| 1405 | 1311 | #endif |
| 1406 | −#endif //!CONFIG_RUNTIME_CPUDETECT | |
| 1407 | 1312 | |
| 1408 | 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 | 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 | 1808 | void ff_get_unscaled_swscale(SwsContext *c) |
| 1921 | 1809 | { |
| 1922 | 1810 | const enum PixelFormat srcFormat = c->srcFormat; |
| @@ -2000,8 +1888,8 @@ void ff_get_unscaled_swscale(SwsContext *c) · 77 unmodified lines | ||
| 2000 | 1888 | if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P) |
| 2001 | 1889 | c->swScale= uyvyToYuv422Wrapper; |
| 2002 | 1890 | |
| 2003 | −#if COMPILE_ALTIVEC | |
| 2004 | − if ((c->flags & SWS_CPU_CAPS_ALTIVEC) && | |
| 1891 | +#if HAVE_ALTIVEC | |
| 1892 | + if ((av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) && | |
| 2005 | 1893 | !(c->flags & SWS_BITEXACT) && |
| 2006 | 1894 | srcFormat == PIX_FMT_YUV420P) { |
| 2007 | 1895 | // unscaled YV12 -> packed YUV, we want speed |
| @@ -2031,8 +1919,7 @@ void ff_get_unscaled_swscale(SwsContext *c) · 23 unmodified lines | ||
| 2031 | 1919 | c->swScale= planarCopyWrapper; |
| 2032 | 1920 | } |
| 2033 | 1921 | #if ARCH_BFIN |
| 2034 | − if (flags & SWS_CPU_CAPS_BFIN) | |
| 2035 | − ff_bfin_get_unscaled_swscale (c); | |
| 1922 | + ff_bfin_get_unscaled_swscale (c); | |
| 2036 | 1923 | #endif |
| 2037 | 1924 | } |
| 2038 | 1925 | |
| @@ -95,13 +95,6 @@ const char *swscale_license(void); · 94 unmodified lines | ||
| 95 | 95 | #define SWS_ACCURATE_RND 0x40000 |
| 96 | 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 | 98 | #define SWS_MAX_REDUCE_CUTOFF 0.002 |
| 106 | 99 | |
| 107 | 100 | #define SWS_CS_ITU709 1 |
| @@ -481,11 +481,6 @@ extern const AVClass sws_context_class; · 480 unmodified lines | ||
| 481 | 481 | */ |
| 482 | 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 | 485 | * Returns function pointer to fastest main scaler path function depending |
| 491 | 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 | 367 | const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) |
| 368 | 368 | { |
| 369 | 369 | int i, j; |
| 370 | −#if COMPILE_TEMPLATE_MMX | |
| 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 | |
| 370 | + | |
| 513 | 371 | for (i=0; i<dstW; i++) { |
| 514 | 372 | int srcPos= filterPos[i]; |
| 515 | 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 | 382 | const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) |
| 525 | 383 | { |
| 526 | 384 | int i, j; |
| @@ -660,6 +518,11 @@ inline static void hcscale_c(SwsContext *c, uint16_t *dst, long dstWidth, · 133 unmodified lines | ||
| 660 | 518 | #define DEBUG_SWSCALE_BUFFERS 0 |
| 661 | 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 | 526 | static int swScale_c(SwsContext *c, const uint8_t* src[], int srcStride[], |
| 664 | 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 | 694 | if (!enough_lines) |
| 832 | 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 | 700 | if (dstY < dstH-2) { |
| 835 | 701 | const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; |
| 836 | 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 | 821 | if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf) |
| 956 | 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 | 830 | /* store changed local vars back in the context */ |
| 959 | 831 | c->dstY= dstY; |
| 960 | 832 | c->lumBufIndex= lumBufIndex; |
| @@ -1001,14 +873,14 @@ static void sws_init_swScale_c(SwsContext *c) · 40 unmodified lines | ||
| 1001 | 873 | case PIX_FMT_YUV420P10BE: |
| 1002 | 874 | case PIX_FMT_YUV420P16BE: |
| 1003 | 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 | 877 | case PIX_FMT_GRAY16LE : |
| 1006 | 878 | case PIX_FMT_YUV420P9LE: |
| 1007 | 879 | case PIX_FMT_YUV422P10LE: |
| 1008 | 880 | case PIX_FMT_YUV420P10LE: |
| 1009 | 881 | case PIX_FMT_YUV420P16LE: |
| 1010 | 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 | 885 | if (c->chrSrcHSubSample) { |
| 1014 | 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 | 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 | 189 | SwsVector *srcFilter, SwsVector *dstFilter, double param[2]) |
| 190 | 190 | { |
| 191 | 191 | int i; |
| @@ -196,10 +196,8 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi · 4 unmodified lines | ||
| 196 | 196 | int64_t *filter2=NULL; |
| 197 | 197 | const int64_t fone= 1LL<<54; |
| 198 | 198 | int ret= -1; |
| 199 | −#if ARCH_X86 | |
| 200 | − if (flags & SWS_CPU_CAPS_MMX) | |
| 201 | − __asm__ volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions) | |
| 202 | −#endif | |
| 199 | + | |
| 200 | + emms_c(); //FIXME this should not be required but it IS (even for non-MMX versions) | |
| 203 | 201 | |
| 204 | 202 | // NOTE: the +1 is for the MMX scaler which reads over the end |
| 205 | 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 | 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 | 418 | // we can handle the special case 4, |
| 421 | 419 | // so we don't want to go to the full 8 |
| 422 | 420 | if (minFilterSize < 5) |
| @@ -431,7 +429,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi · 8 unmodified lines | ||
| 431 | 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 | 433 | // special case for unscaled vertical filtering |
| 436 | 434 | if (minFilterSize == 1 && filterAlign == 2) |
| 437 | 435 | filterAlign= 1; |
| @@ -521,7 +519,7 @@ fail: · 83 unmodified lines | ||
| 521 | 519 | return ret; |
| 522 | 520 | } |
| 523 | 521 | |
| 524 | −#if ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) | |
| 522 | +#if HAVE_MMX2 | |
| 525 | 523 | static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *filter, int32_t *filterPos, int numSplits) |
| 526 | 524 | { |
| 527 | 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 | 678 | return fragmentPos + 1; |
| 681 | 679 | } |
| 682 | −#endif /* ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) */ | |
| 680 | +#endif /* HAVE_MMX2 */ | |
| 683 | 681 | |
| 684 | 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 | 685 | *v = av_pix_fmt_descriptors[format].log2_chroma_h; |
| 688 | 686 | } |
| 689 | 687 | |
| 690 | −static int update_flags_cpu(int flags); | |
| 691 | − | |
| 692 | 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 | 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 | 700 | c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->dstFormat]); |
| 705 | 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 | 703 | ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation); |
| 709 | 704 | //FIXME factorize |
| 710 | 705 | |
| 711 | −#if HAVE_ALTIVEC | |
| 712 | − if (c->flags & SWS_CPU_CAPS_ALTIVEC) | |
| 706 | + if (HAVE_ALTIVEC && av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) | |
| 713 | 707 | ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness, contrast, saturation); |
| 714 | −#endif | |
| 715 | 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 | 737 | SwsContext *sws_alloc_context(void) |
| 766 | 738 | { |
| 767 | 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 | 754 | int srcH= c->srcH; |
| 783 | 755 | int dstW= c->dstW; |
| 784 | 756 | int dstH= c->dstH; |
| 785 | − int flags; | |
| 757 | + int flags, cpu_flags; | |
| 786 | 758 | enum PixelFormat srcFormat= c->srcFormat; |
| 787 | 759 | enum PixelFormat dstFormat= c->dstFormat; |
| 788 | 760 | |
| 789 | − flags= c->flags = update_flags_cpu(c->flags); | |
| 790 | −#if ARCH_X86 | |
| 791 | − if (flags & SWS_CPU_CAPS_MMX) | |
| 792 | − __asm__ volatile("emms\n\t"::: "memory"); | |
| 793 | −#endif | |
| 794 | − if (!rgb15to16) sws_rgb2rgb_init(flags); | |
| 761 | + cpu_flags = av_get_cpu_flags(); | |
| 762 | + flags = c->flags; | |
| 763 | + emms_c(); | |
| 764 | + if (!rgb15to16) sws_rgb2rgb_init(); | |
| 795 | 765 | |
| 796 | 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 | 858 | c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0; |
| 889 | 859 | if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR)) { |
| 890 | 860 | if (flags&SWS_PRINT_INFO) |
| @@ -910,7 +880,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 19 unmodified lines | ||
| 910 | 880 | c->chrXInc+= 20; |
| 911 | 881 | } |
| 912 | 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 | 884 | c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20; |
| 915 | 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 | 889 | /* precalculate horizontal scaler filter coefficients */ |
| 920 | 890 | { |
| 921 | −#if ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) | |
| 891 | +#if HAVE_MMX2 | |
| 922 | 892 | // can't downscale !!! |
| 923 | 893 | if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR)) { |
| 924 | 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 | 924 | mprotect(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, PROT_EXEC | PROT_READ); |
| 955 | 925 | #endif |
| 956 | 926 | } else |
| 957 | −#endif /* ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) */ | |
| 927 | +#endif /* HAVE_MMX2 */ | |
| 958 | 928 | { |
| 959 | 929 | const int filterAlign= |
| 960 | − (flags & SWS_CPU_CAPS_MMX) ? 4 : | |
| 961 | − (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 : | |
| 930 | + (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 4 : | |
| 931 | + (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 : | |
| 962 | 932 | 1; |
| 963 | 933 | |
| 964 | 934 | if (initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc, |
| 965 | 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 | 937 | srcFilter->lumH, dstFilter->lumH, c->param) < 0) |
| 968 | 938 | goto fail; |
| 969 | 939 | if (initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc, |
| 970 | 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 | 942 | srcFilter->chrH, dstFilter->chrH, c->param) < 0) |
| 973 | 943 | goto fail; |
| 974 | 944 | } |
| @@ -977,18 +947,18 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 2 unmodified lines | ||
| 977 | 947 | /* precalculate vertical scaler filter coefficients */ |
| 978 | 948 | { |
| 979 | 949 | const int filterAlign= |
| 980 | − (flags & SWS_CPU_CAPS_MMX) && (flags & SWS_ACCURATE_RND) ? 2 : | |
| 981 | − (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 : | |
| 950 | + (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) && (flags & SWS_ACCURATE_RND) ? 2 : | |
| 951 | + (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 : | |
| 982 | 952 | 1; |
| 983 | 953 | |
| 984 | 954 | if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc, |
| 985 | 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 | 957 | srcFilter->lumV, dstFilter->lumV, c->param) < 0) |
| 988 | 958 | goto fail; |
| 989 | 959 | if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc, |
| 990 | 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 | 962 | srcFilter->chrV, dstFilter->chrV, c->param) < 0) |
| 993 | 963 | goto fail; |
| 994 | 964 | |
| @@ -1082,13 +1052,13 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 87 unmodified lines | ||
| 1082 | 1052 | #endif |
| 1083 | 1053 | sws_format_name(dstFormat)); |
| 1084 | 1054 | |
| 1085 | − if (flags & SWS_CPU_CAPS_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"); | |
| 1087 | − else if (flags & SWS_CPU_CAPS_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"); | |
| 1055 | + if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) av_log(c, AV_LOG_INFO, "using MMX2\n"); | |
| 1056 | + else if (HAVE_AMD3DNOW && cpu_flags & AV_CPU_FLAG_3DNOW) av_log(c, AV_LOG_INFO, "using 3DNOW\n"); | |
| 1057 | + else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) av_log(c, AV_LOG_INFO, "using MMX\n"); | |
| 1058 | + else if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) av_log(c, AV_LOG_INFO, "using AltiVec\n"); | |
| 1089 | 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 | 1062 | if (c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR)) |
| 1093 | 1063 | av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR MMX2 scaler for horizontal scaling\n"); |
| 1094 | 1064 | else { |
| @@ -1107,7 +1077,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 12 unmodified lines | ||
| 1107 | 1077 | av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal chrominance scaling\n"); |
| 1108 | 1078 | } |
| 1109 | 1079 | } else { |
| 1110 | −#if ARCH_X86 | |
| 1080 | +#if HAVE_MMX | |
| 1111 | 1081 | av_log(c, AV_LOG_VERBOSE, "using x86 asm scaler for horizontal scaling\n"); |
| 1112 | 1082 | #else |
| 1113 | 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 | 1089 | if (isPlanarYUV(dstFormat)) { |
| 1120 | 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 | 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 | 1096 | } else { |
| 1125 | 1097 | if (c->vLumFilterSize==1 && c->vChrFilterSize==2) |
| 1126 | 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 | 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 | 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 | 1109 | if (dstFormat==PIX_FMT_BGR24) |
| 1135 | 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 | 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 | 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 | 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 | 1122 | else if (dstFormat == PIX_FMT_RGB444BE || dstFormat == PIX_FMT_RGB444LE || |
| 1144 | 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 | 1127 | av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH); |
| 1148 | 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 | 1507 | av_freep(&c->hLumFilterPos); |
| 1528 | 1508 | av_freep(&c->hChrFilterPos); |
| 1529 | 1509 | |
| 1530 | −#if ARCH_X86 | |
| 1510 | +#if HAVE_MMX | |
| 1531 | 1511 | #ifdef MAP_ANONYMOUS |
| 1532 | 1512 | if (c->lumMmx2FilterCode) munmap(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize); |
| 1533 | 1513 | if (c->chrMmx2FilterCode) munmap(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize); |
| @@ -1540,7 +1520,7 @@ void sws_freeContext(SwsContext *c) · 6 unmodified lines | ||
| 1540 | 1520 | #endif |
| 1541 | 1521 | c->lumMmx2FilterCode=NULL; |
| 1542 | 1522 | c->chrMmx2FilterCode=NULL; |
| 1543 | −#endif /* ARCH_X86 */ | |
| 1523 | +#endif /* HAVE_MMX */ | |
| 1544 | 1524 | |
| 1545 | 1525 | av_freep(&c->yuvTable); |
| 1546 | 1526 | |
| @@ -1557,8 +1537,6 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context, · 10 unmodified lines | ||
| 1557 | 1537 | if (!param) |
| 1558 | 1538 | param = default_param; |
| 1559 | 1539 | |
| 1560 | − flags = update_flags_cpu(flags); | |
| 1561 | − | |
| 1562 | 1540 | if (context && |
| 1563 | 1541 | (context->srcW != srcW || |
| 1564 | 1542 | context->srcH != srcH || |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | #include "config.h" |
| 29 | 29 | #include "libavutil/x86_cpu.h" |
| 30 | +#include "libavutil/cpu.h" | |
| 30 | 31 | #include "libavutil/bswap.h" |
| 31 | 32 | #include "libswscale/rgb2rgb.h" |
| 32 | 33 | #include "libswscale/swscale.h" |
| @@ -122,16 +123,16 @@ DECLARE_ASM_CONST(8, uint64_t, blue_15mask) = 0x0000001f0000001fULL; · 89 unmodified lines | ||
| 122 | 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 | − if (flags & SWS_CPU_CAPS_SSE2) | |
| 129 | − rgb2rgb_init_SSE2(); | |
| 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) | |
| 128 | + int cpu_flags = av_get_cpu_flags(); | |
| 129 | + | |
| 130 | + if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) | |
| 135 | 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 | 23 | #undef REAL_MOVNTQ |
| 24 | 24 | #undef MOVNTQ |
| 25 | −#undef PAVGB | |
| 26 | 25 | #undef PREFETCH |
| 27 | 26 | |
| 28 | −#if COMPILE_TEMPLATE_AMD3DNOW | |
| 29 | −#define PREFETCH "prefetch" | |
| 30 | −#elif COMPILE_TEMPLATE_MMX2 | |
| 27 | +#if COMPILE_TEMPLATE_MMX2 | |
| 31 | 28 | #define PREFETCH "prefetchnta" |
| 32 | 29 | #else |
| 33 | 30 | #define PREFETCH " # nop" |
| 34 | 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 | 33 | #if COMPILE_TEMPLATE_MMX2 |
| 43 | 34 | #define REAL_MOVNTQ(a,b) "movntq " #a ", " #b " \n\t" |
| 44 | 35 | #else |
| @@ -709,62 +700,6 @@ · 664 unmodified lines | ||
| 709 | 700 | " jb 1b \n\t" |
| 710 | 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 | 703 | #define WRITEBGR24MMX(dst, dstw, index) \ |
| 769 | 704 | /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\ |
| 770 | 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 | 831 | const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc, |
| 897 | 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 | 834 | if (c->flags & SWS_ACCURATE_RND) { |
| 901 | 835 | if (uDest) { |
| 902 | 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 | 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 | 857 | static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const int16_t *chrSrc, const int16_t *alpSrc, |
| 938 | 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 | 860 | long p= 4; |
| 943 | 861 | const int16_t *src[4]= {alpSrc + dstW, lumSrc + dstW, chrSrc + chrDstW, chrSrc + VOFW + chrDstW}; |
| 944 | 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 | 898 | x86_reg dummy=0; |
| 1015 | 899 | x86_reg dstW_reg = dstW; |
| 1016 | − if(!(c->flags & SWS_BITEXACT)) { | |
| 900 | + | |
| 1017 | 901 | if (c->flags & SWS_ACCURATE_RND) { |
| 1018 | 902 | switch(c->dstFormat) { |
| 1019 | 903 | case PIX_FMT_RGB32: |
| @@ -1170,7 +1054,7 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 150 unmodified lines | ||
| 1170 | 1054 | return; |
| 1171 | 1055 | } |
| 1172 | 1056 | } |
| 1173 | − } | |
| 1057 | + | |
| 1174 | 1058 | yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize, |
| 1175 | 1059 | chrFilter, chrSrc, chrFilterSize, |
| 1176 | 1060 | alpSrc, dest, dstW, dstY); |
| @@ -1182,11 +1066,6 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 5 unmodified lines | ||
| 1182 | 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 | 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 | 1069 | switch(c->dstFormat) { |
| 1191 | 1070 | //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( |
| 1192 | 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 | 1196 | "a" (&c->redDither) |
| 1318 | 1197 | ); |
| 1319 | 1198 | return; |
| 1320 | − default: break; | |
| 1321 | 1199 | } |
| 1322 | − } | |
| 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) | |
| 1200 | + | |
| 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 | 1208 | static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, const uint16_t *uvbuf0, const uint16_t *uvbuf1, |
| 1330 | 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; | |
| 1333 | − int i; | |
| 1334 | − | |
| 1335 | − const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1 | |
| 1336 | − const int yalpha= 4096; //FIXME ... | |
| 1211 | + const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1 | |
| 1337 | 1212 | |
| 1338 | − if (flags&SWS_FULL_CHR_H_INT) { | |
| 1339 | − c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y); | |
| 1340 | − return; | |
| 1341 | − } | |
| 1213 | + if (flags&SWS_FULL_CHR_H_INT) { | |
| 1214 | + c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y); | |
| 1215 | + return; | |
| 1216 | + } | |
| 1342 | 1217 | |
| 1343 | − if(!(flags & SWS_BITEXACT)) { | |
| 1344 | 1218 | if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster |
| 1345 | 1219 | switch(dstFormat) { |
| 1346 | 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 | 1428 | return; |
| 1555 | 1429 | } |
| 1556 | 1430 | } |
| 1557 | − } | |
| 1558 | − if (uvalpha < 2048) { | |
| 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) | |
| 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 | − } | |
| 1431 | + | |
| 1432 | + yuv2packed1_c(c, buf0, uvbuf0, uvbuf1, abuf0, dest, | |
| 1433 | + dstW, uvalpha, dstFormat, flags, y); | |
| 1563 | 1434 | } |
| 1564 | 1435 | |
| 1565 | 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 | 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 | 1740 | static inline void RENAME(rgb24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused) |
| 1884 | 1741 | { |
| 1885 | 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 | 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 | 1752 | // bilinear / bicubic scaling |
| 1910 | 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 | |
| 2065 | −//FIXME all scalers more complex than bilinear could do half of this transform | |
| 2066 | −static void RENAME(chrRangeToJpeg)(int16_t *dst, int width) | |
| 1907 | +static inline void RENAME(hScale16)(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc, | |
| 1908 | + const int16_t *filter, const int16_t *filterPos, long filterSize, int shift) | |
| 2067 | 1909 | { |
| 2068 | − int i; | |
| 2069 | − for (i = 0; i < width; i++) { | |
| 2070 | − dst[i ] = (FFMIN(dst[i ],30775)*4663 - 9289992)>>12; //-264 | |
| 2071 | − dst[i+VOFW] = (FFMIN(dst[i+VOFW],30775)*4663 - 9289992)>>12; //-264 | |
| 2072 | − } | |
| 2073 | −} | |
| 2074 | −static void RENAME(chrRangeFromJpeg)(int16_t *dst, int width) | |
| 2075 | −{ | |
| 2076 | − int i; | |
| 2077 | − for (i = 0; i < width; i++) { | |
| 2078 | − dst[i ] = (dst[i ]*1799 + 4081085)>>11; //1469 | |
| 2079 | − dst[i+VOFW] = (dst[i+VOFW]*1799 + 4081085)>>11; //1469 | |
| 1910 | + int i, j; | |
| 1911 | + | |
| 1912 | + assert(filterSize % 4 == 0 && filterSize>0); | |
| 1913 | + if (filterSize==4 && shift<15) { // Always true for upscaling, sometimes for down, too. | |
| 1914 | + x86_reg counter= -2*dstW; | |
| 1915 | + filter-= counter*2; | |
| 1916 | + filterPos-= counter/2; | |
| 1917 | + dst-= counter/2; | |
| 1918 | + __asm__ volatile( | |
| 1919 | + "movd %5, %%mm7 \n\t" | |
| 1920 | +#if defined(PIC) | |
| 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 | 2065 | static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, |
| 2104 | 2066 | long dstWidth, const uint8_t *src, int srcW, |
| 2105 | 2067 | int xInc) |
| 2106 | 2068 | { |
| 2107 | −#if COMPILE_TEMPLATE_MMX2 | |
| 2108 | 2069 | int32_t *filterPos = c->hLumFilterPos; |
| 2109 | 2070 | int16_t *filter = c->hLumFilter; |
| 2110 | 2071 | int canMMX2BeUsed = c->canMMX2BeUsed; |
| @@ -2113,7 +2074,7 @@ static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, · 2 unmodified lines | ||
| 2113 | 2074 | #if defined(PIC) |
| 2114 | 2075 | DECLARE_ALIGNED(8, uint64_t, ebxsave); |
| 2115 | 2076 | #endif |
| 2116 | − if (canMMX2BeUsed) { | |
| 2077 | + | |
| 2117 | 2078 | __asm__ volatile( |
| 2118 | 2079 | #if defined(PIC) |
| 2119 | 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 | 2133 | #endif |
| 2173 | 2134 | ); |
| 2174 | 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 | 2138 | static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, |
| 2245 | 2139 | long dstWidth, const uint8_t *src1, |
| 2246 | 2140 | const uint8_t *src2, int srcW, int xInc) |
| 2247 | 2141 | { |
| 2248 | −#if COMPILE_TEMPLATE_MMX2 | |
| 2249 | 2142 | int32_t *filterPos = c->hChrFilterPos; |
| 2250 | 2143 | int16_t *filter = c->hChrFilter; |
| 2251 | 2144 | int canMMX2BeUsed = c->canMMX2BeUsed; |
| @@ -2254,7 +2147,7 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, · 2 unmodified lines | ||
| 2254 | 2147 | #if defined(PIC) |
| 2255 | 2148 | DECLARE_ALIGNED(8, uint64_t, ebxsave); |
| 2256 | 2149 | #endif |
| 2257 | − if (canMMX2BeUsed) { | |
| 2150 | + | |
| 2258 | 2151 | __asm__ volatile( |
| 2259 | 2152 | #if defined(PIC) |
| 2260 | 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 | 2197 | dst[i] = src1[srcW-1]*128; |
| 2305 | 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 | |
| 2381 | −#define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__) | |
| 2382 | − | |
| 2383 | −static int RENAME(swScale)(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY, | |
| 2384 | − int srcSliceH, uint8_t* dst[], int dstStride[]) | |
| 2203 | +#if !COMPILE_TEMPLATE_MMX2 | |
| 2204 | +static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex, | |
| 2205 | + int lastInLumBuf, int lastInChrBuf) | |
| 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 | 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 | 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 | 2214 | int16_t *vLumFilterPos= c->vLumFilterPos; |
| 2397 | 2215 | int16_t *vChrFilterPos= c->vChrFilterPos; |
| 2398 | − int16_t *hLumFilterPos= c->hLumFilterPos; | |
| 2399 | − int16_t *hChrFilterPos= c->hChrFilterPos; | |
| 2400 | 2216 | int16_t *vLumFilter= c->vLumFilter; |
| 2401 | 2217 | int16_t *vChrFilter= c->vChrFilter; |
| 2402 | − int16_t *hLumFilter= c->hLumFilter; | |
| 2403 | − int16_t *hChrFilter= c->hChrFilter; | |
| 2404 | 2218 | int32_t *lumMmxFilter= c->lumMmxFilter; |
| 2405 | 2219 | int32_t *chrMmxFilter= c->chrMmxFilter; |
| 2406 | 2220 | int32_t av_unused *alpMmxFilter= c->alpMmxFilter; |
| 2407 | 2221 | const int vLumFilterSize= c->vLumFilterSize; |
| 2408 | 2222 | const int vChrFilterSize= c->vChrFilterSize; |
| 2409 | − const int hLumFilterSize= c->hLumFilterSize; | |
| 2410 | − const int hChrFilterSize= c->hChrFilterSize; | |
| 2411 | − int16_t **lumPixBuf= c->lumPixBuf; | |
| 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 | |
| 2223 | + const int chrDstY= dstY>>c->chrDstVSubSample; | |
| 2224 | + const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input | |
| 2225 | + const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input | |
| 2553 | 2226 | |
| 2554 | 2227 | c->blueDither= ff_dither8[dstY&1]; |
| 2555 | 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 | 2230 | else |
| 2558 | 2231 | c->greenDither= ff_dither4[dstY&1]; |
| 2559 | 2232 | c->redDither= ff_dither8[(dstY+1)&1]; |
| 2560 | − if (dstY < dstH-2) { | |
| 2233 | + if (dstY < dstH - 2) { | |
| 2561 | 2234 | const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; |
| 2562 | 2235 | const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; |
| 2563 | 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 | 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 | 2286 | static void RENAME(sws_init_swScale)(SwsContext *c) |
| 2744 | 2287 | { |
| 2745 | 2288 | enum PixelFormat srcFormat = c->srcFormat; |
| 2746 | 2289 | |
| 2747 | − c->yuv2nv12X = RENAME(yuv2nv12X ); | |
| 2748 | − c->yuv2yuv1 = RENAME(yuv2yuv1 ); | |
| 2749 | − c->yuv2yuvX = RENAME(yuv2yuvX ); | |
| 2750 | − c->yuv2packed1 = RENAME(yuv2packed1 ); | |
| 2751 | − c->yuv2packed2 = RENAME(yuv2packed2 ); | |
| 2752 | − c->yuv2packedX = RENAME(yuv2packedX ); | |
| 2290 | + if (!(c->flags & SWS_BITEXACT)) { | |
| 2291 | + c->yuv2yuv1 = RENAME(yuv2yuv1 ); | |
| 2292 | + c->yuv2yuvX = RENAME(yuv2yuvX ); | |
| 2293 | + c->yuv2packed1 = RENAME(yuv2packed1 ); | |
| 2294 | + c->yuv2packed2 = RENAME(yuv2packed2 ); | |
| 2295 | + c->yuv2packedX = RENAME(yuv2packedX ); | |
| 2296 | + } | |
| 2753 | 2297 | |
| 2754 | 2298 | c->hScale = RENAME(hScale ); |
| 2755 | 2299 | |
| 2756 | 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 | 2302 | if (c->flags & SWS_FAST_BILINEAR && c->canMMX2BeUsed) |
| 2758 | 2303 | { |
| 2759 | 2304 | c->hyscale_fast = RENAME(hyscale_fast); |
| 2760 | 2305 | c->hcscale_fast = RENAME(hcscale_fast); |
| 2761 | 2306 | } else { |
| 2307 | +#endif /* COMPILE_TEMPLATE_MMX2 */ | |
| 2762 | 2308 | c->hyscale_fast = NULL; |
| 2763 | 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 | 2315 | case PIX_FMT_YUYV422 : c->chrToYV12 = RENAME(yuy2ToUV); break; |
| 2768 | 2316 | case PIX_FMT_UYVY422 : c->chrToYV12 = RENAME(uyvyToUV); break; |
| 2769 | 2317 | case PIX_FMT_NV12 : c->chrToYV12 = RENAME(nv12ToUV); break; |
| 2770 | 2318 | case PIX_FMT_NV21 : c->chrToYV12 = RENAME(nv21ToUV); break; |
| 2771 | − case PIX_FMT_YUV420P16BE: | |
| 2772 | − case PIX_FMT_YUV422P16BE: | |
| 2773 | − case PIX_FMT_YUV444P16BE: c->chrToYV12 = RENAME(BEToUV); break; | |
| 2319 | + case PIX_FMT_GRAY16LE : | |
| 2320 | + case PIX_FMT_YUV420P9LE: | |
| 2321 | + case PIX_FMT_YUV422P10LE: | |
| 2322 | + case PIX_FMT_YUV420P10LE: | |
| 2774 | 2323 | case PIX_FMT_YUV420P16LE: |
| 2775 | 2324 | case PIX_FMT_YUV422P16LE: |
| 2776 | − case PIX_FMT_YUV444P16LE: c->chrToYV12 = RENAME(LEToUV); break; | |
| 2777 | − default: break; | |
| 2778 | − } | |
| 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 { | |
| 2325 | + case PIX_FMT_YUV444P16LE: c->hScale16= RENAME(hScale16); break; | |
| 2326 | + } | |
| 2327 | + if (!c->chrSrcHSubSample) { | |
| 2786 | 2328 | switch(srcFormat) { |
| 2787 | 2329 | case PIX_FMT_BGR24 : c->chrToYV12 = RENAME(bgr24ToUV); break; |
| 2788 | 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 | 2335 | switch (srcFormat) { |
| 2794 | 2336 | case PIX_FMT_YUYV422 : |
| 2795 | − case PIX_FMT_YUV420P16BE: | |
| 2796 | − case PIX_FMT_YUV422P16BE: | |
| 2797 | − case PIX_FMT_YUV444P16BE: | |
| 2798 | 2337 | case PIX_FMT_Y400A : |
| 2799 | − case PIX_FMT_GRAY16BE : c->lumToYV12 = RENAME(yuy2ToY); break; | |
| 2338 | + c->lumToYV12 = RENAME(yuy2ToY); break; | |
| 2800 | 2339 | case PIX_FMT_UYVY422 : |
| 2801 | − case PIX_FMT_YUV420P16LE: | |
| 2802 | − case PIX_FMT_YUV422P16LE: | |
| 2803 | − case PIX_FMT_YUV444P16LE: | |
| 2804 | − case PIX_FMT_GRAY16LE : c->lumToYV12 = RENAME(uyvyToY); break; | |
| 2340 | + c->lumToYV12 = RENAME(uyvyToY); break; | |
| 2805 | 2341 | case PIX_FMT_BGR24 : c->lumToYV12 = RENAME(bgr24ToY); break; |
| 2806 | 2342 | case PIX_FMT_RGB24 : c->lumToYV12 = RENAME(rgb24ToY); break; |
| 2807 | 2343 | default: break; |
| @@ -2812,14 +2348,4 @@ static void RENAME(sws_init_swScale)(SwsContext *c) · 4 unmodified lines | ||
| 2812 | 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 | 34 | #include "libswscale/swscale.h" |
| 35 | 35 | #include "libswscale/swscale_internal.h" |
| 36 | 36 | #include "libavutil/x86_cpu.h" |
| 37 | +#include "libavutil/cpu.h" | |
| 37 | 38 | |
| 38 | 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 | 47 | DECLARE_ASM_CONST(8, uint64_t, pb_07) = 0x0707070707070707ULL; |
| 47 | 48 | |
| 48 | 49 | //MMX versions |
| 50 | +#if HAVE_MMX | |
| 49 | 51 | #undef RENAME |
| 50 | −#undef HAVE_MMX2 | |
| 51 | −#undef HAVE_AMD3DNOW | |
| 52 | −#define HAVE_MMX2 0 | |
| 53 | −#define HAVE_AMD3DNOW 0 | |
| 52 | +#undef COMPILE_TEMPLATE_MMX2 | |
| 53 | +#define COMPILE_TEMPLATE_MMX2 0 | |
| 54 | 54 | #define RENAME(a) a ## _MMX |
| 55 | 55 | #include "yuv2rgb_template.c" |
| 56 | +#endif /* HAVE_MMX */ | |
| 56 | 57 | |
| 57 | 58 | //MMX2 versions |
| 59 | +#if HAVE_MMX2 | |
| 58 | 60 | #undef RENAME |
| 59 | −#undef HAVE_MMX2 | |
| 60 | −#define HAVE_MMX2 1 | |
| 61 | +#undef COMPILE_TEMPLATE_MMX2 | |
| 62 | +#define COMPILE_TEMPLATE_MMX2 1 | |
| 61 | 63 | #define RENAME(a) a ## _MMX2 |
| 62 | 64 | #include "yuv2rgb_template.c" |
| 65 | +#endif /* HAVE_MMX2 */ | |
| 63 | 66 | |
| 64 | 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 | 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 | 77 | case PIX_FMT_RGB24: return yuv420_rgb24_MMX2; |
| 79 | 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 | 83 | switch (c->dstFormat) { |
| 86 | − case PIX_FMT_RGB32: | |
| 87 | − if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { | |
| 88 | − if (HAVE_7REGS) return yuva420_rgb32_MMX; | |
| 89 | − break; | |
| 90 | − } else return yuv420_rgb32_MMX; | |
| 91 | − case PIX_FMT_BGR32: | |
| 92 | − if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { | |
| 93 | − if (HAVE_7REGS) return yuva420_bgr32_MMX; | |
| 94 | − break; | |
| 95 | − } else return yuv420_bgr32_MMX; | |
| 96 | − case PIX_FMT_RGB24: return yuv420_rgb24_MMX; | |
| 97 | − case PIX_FMT_BGR24: return yuv420_bgr24_MMX; | |
| 98 | − case PIX_FMT_RGB565: return yuv420_rgb16_MMX; | |
| 99 | − case PIX_FMT_RGB555: return yuv420_rgb15_MMX; | |
| 84 | + case PIX_FMT_RGB32: | |
| 85 | + if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { | |
| 86 | +#if HAVE_7REGS | |
| 87 | + return yuva420_rgb32_MMX; | |
| 88 | +#endif | |
| 89 | + break; | |
| 90 | + } else return yuv420_rgb32_MMX; | |
| 91 | + case PIX_FMT_BGR32: | |
| 92 | + if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) { | |
| 93 | +#if HAVE_7REGS | |
| 94 | + return yuva420_bgr32_MMX; | |
| 95 | +#endif | |
| 96 | + break; | |
| 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 | 25 | #undef EMMS |
| 26 | 26 | #undef SFENCE |
| 27 | 27 | |
| 28 | −#if HAVE_AMD3DNOW | |
| 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 | |
| 28 | +#if COMPILE_TEMPLATE_MMX2 | |
| 36 | 29 | #define MOVNTQ "movntq" |
| 37 | 30 | #define SFENCE "sfence" |
| 38 | 31 | #else |
| @@ -159,7 +152,8 @@ · 120 unmodified lines | ||
| 159 | 152 | } \ |
| 160 | 153 | |
| 161 | 154 | #define YUV2RGB_ENDFUNC \ |
| 162 | − __asm__ volatile (SFENCE"\n\t"EMMS); \ | |
| 155 | + __asm__ volatile (SFENCE"\n\t" \ | |
| 156 | + "emms \n\t"); \ | |
| 163 | 157 | return srcSliceH; \ |
| 164 | 158 | |
| 165 | 159 | #define IF0(x) |
| @@ -188,6 +182,7 @@ · 22 unmodified lines | ||
| 188 | 182 | "paddusb "GREEN_DITHER"(%4), %%mm2\n\t" \ |
| 189 | 183 | "paddusb "RED_DITHER"(%4), %%mm1\n\t" \ |
| 190 | 184 | |
| 185 | +#if !COMPILE_TEMPLATE_MMX2 | |
| 191 | 186 | static inline int RENAME(yuv420_rgb15)(SwsContext *c, const uint8_t *src[], |
| 192 | 187 | int srcStride[], |
| 193 | 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 | 238 | YUV2RGB_OPERANDS |
| 244 | 239 | YUV2RGB_ENDFUNC |
| 245 | 240 | } |
| 241 | +#endif /* !COMPILE_TEMPLATE_MMX2 */ | |
| 246 | 242 | |
| 247 | 243 | #define RGB_PACK24(blue, red)\ |
| 248 | 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 | 255 | "punpckhwd %%mm6, %%mm5 \n" /* R4 G4 B4 R5 R6 G6 B6 R7 */\ |
| 260 | 256 | RGB_PACK24_B |
| 261 | 257 | |
| 262 | −#if HAVE_MMX2 | |
| 258 | +#if COMPILE_TEMPLATE_MMX2 | |
| 263 | 259 | DECLARE_ASM_CONST(8, int16_t, mask1101[4]) = {-1,-1, 0,-1}; |
| 264 | 260 | DECLARE_ASM_CONST(8, int16_t, mask0010[4]) = { 0, 0,-1, 0}; |
| 265 | 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 | 362 | MOVNTQ " %%mm5, 16(%1)\n\t" \ |
| 367 | 363 | MOVNTQ " %%mm"alpha", 24(%1)\n\t" \ |
| 368 | 364 | |
| 365 | +#if !COMPILE_TEMPLATE_MMX2 | |
| 369 | 366 | static inline int RENAME(yuv420_rgb32)(SwsContext *c, const uint8_t *src[], |
| 370 | 367 | int srcStride[], |
| 371 | 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 | 383 | YUV2RGB_ENDFUNC |
| 387 | 384 | } |
| 388 | 385 | |
| 386 | +#if HAVE_7REGS && CONFIG_SWSCALE_ALPHA | |
| 389 | 387 | static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[], |
| 390 | 388 | int srcStride[], |
| 391 | 389 | int srcSliceY, int srcSliceH, |
| 392 | 390 | uint8_t *dst[], int dstStride[]) |
| 393 | 391 | { |
| 394 | −#if HAVE_7REGS | |
| 395 | 392 | int y, h_size; |
| 396 | 393 | |
| 397 | 394 | YUV2RGB_LOOP(4) |
| @@ -406,9 +403,8 @@ static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[], · 8 unmodified lines | ||
| 406 | 403 | YUV2RGB_ENDLOOP(4) |
| 407 | 404 | YUV2RGB_OPERANDS_ALPHA |
| 408 | 405 | YUV2RGB_ENDFUNC |
| 409 | −#endif | |
| 410 | − return 0; | |
| 411 | 406 | } |
| 407 | +#endif | |
| 412 | 408 | |
| 413 | 409 | static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[], |
| 414 | 410 | int srcStride[], |
| @@ -430,12 +426,12 @@ static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[], · 15 unmodified lines | ||
| 430 | 426 | YUV2RGB_ENDFUNC |
| 431 | 427 | } |
| 432 | 428 | |
| 429 | +#if HAVE_7REGS && CONFIG_SWSCALE_ALPHA | |
| 433 | 430 | static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[], |
| 434 | 431 | int srcStride[], |
| 435 | 432 | int srcSliceY, int srcSliceH, |
| 436 | 433 | uint8_t *dst[], int dstStride[]) |
| 437 | 434 | { |
| 438 | −#if HAVE_7REGS | |
| 439 | 435 | int y, h_size; |
| 440 | 436 | |
| 441 | 437 | YUV2RGB_LOOP(4) |
| @@ -450,6 +446,7 @@ static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[], · 8 unmodified lines | ||
| 450 | 446 | YUV2RGB_ENDLOOP(4) |
| 451 | 447 | YUV2RGB_OPERANDS_ALPHA |
| 452 | 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 | 32 | #include "rgb2rgb.h" |
| 33 | 33 | #include "swscale.h" |
| 34 | 34 | #include "swscale_internal.h" |
| 35 | −#include "libavutil/x86_cpu.h" | |
| 35 | +#include "libavutil/cpu.h" | |
| 36 | 36 | #include "libavutil/bswap.h" |
| 37 | 37 | |
| 38 | 38 | extern const uint8_t dither_4x4_16[4][8]; |
| @@ -579,24 +579,18 @@ CLOSEYUV2RGBFUNC(1) · 540 unmodified lines | ||
| 579 | 579 | SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c) |
| 580 | 580 | { |
| 581 | 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 | |
| 597 | − if (c->flags & SWS_CPU_CAPS_BFIN) | |
| 583 | + if (HAVE_MMX) { | |
| 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 | 592 | t = ff_yuv2rgb_get_func_ptr_bfin(c); |
| 599 | −#endif | |
| 593 | + } | |
| 600 | 594 | |
| 601 | 595 | if (t) |
| 602 | 596 | return t; |