History

Merge remote-tracking branch 'qatar/master'

* 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. ...

Michael Niedermayer committed 15 years ago

Commit 034fc7b2 parents d1adad3 9bbd6a440 files · +1222 −2310Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t