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
28592859
28602860 check_struct dxva2api.h DXVA_PictureParameters wDecodedPictureIndex
28612861
2862−if ! enabled_any memalign memalign_hack posix_memalign malloc_aligned &&
2863− enabled_any $need_memalign ; then
2864− die "Error, no aligned memory allocator but SSE enabled, disable it or use --enable-memalign-hack."
2865−fi
2866−
28672862 disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib
28682863 disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib
28692864
@@ -3156,6 +3151,9 @@ check_deps $CONFIG_LIST \ · 286 unmodified lines
31563151
31573152 enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; }
31583153
3154+! enabled_any memalign posix_memalign malloc_aligned &&
3155+ enabled_any $need_memalign && enable memalign_hack
3156+
31593157 echo "install prefix $prefix"
31603158 echo "source path $source_path"
31613159 echo "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
433433 @url{http://www.videolan.org/developers/x264.html}
434434
435435 @c man end VIDEO ENCODERS
436+
437+@subheading Floating-Point-Only AC-3 Encoding Options
438+
439+These options are only valid for the floating-point encoder and do not exist
440+for the fixed-point encoder due to the corresponding features not being
441+implemented in fixed-point.
442+
443+@table @option
444+
445+@item -channel_coupling @var{boolean}
446+Enables/Disables use of channel coupling, which is an optional AC-3 feature
447+that increases quality by combining high frequency information from multiple
448+channels into a single channel. The per-channel high frequency information is
449+sent with less accuracy in both the frequency and time domains. This allows
450+more bits to be used for lower frequencies while preserving enough information
451+to reconstruct the high frequencies. This option is enabled by default for the
452+floating-point encoder and should generally be left as enabled except for
453+testing purposes or to increase encoding speed.
454+@table @option
455+@item -1
456+@itemx auto
457+Selected by Encoder (default)
458+@item 0
459+@itemx off
460+Disable Channel Coupling
461+@item 1
462+@itemx on
463+Enable Channel Coupling
464+@end table
465+
466+@item -cpl_start_band @var{number}
467+Coupling Start Band. Sets the channel coupling start band, from 1 to 15. If a
468+value higher than the bandwidth is used, it will be reduced to 1 less than the
469+coupling end band. If @var{auto} is used, the start band will be determined by
470+the encoder based on the bit rate, sample rate, and channel layout. This option
471+has no effect if channel coupling is disabled.
472+@table @option
473+@item -1
474+@itemx auto
475+Selected by Encoder (default)
476+@end table
477+
478+@end table
479+
480+@c man end ENCODERS
481+
libavcodec/Makefile+0−2
@@ -269,8 +269,6 @@ OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ · 268 unmodified lines
269269 mpegvideo.o error_resilience.o
270270 OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o
271271 OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o
272−OBJS-$(CONFIG_MSMPEG4V1_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \
273− h263.o ituh263dec.o mpeg4videodec.o
274272 OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \
275273 h263.o ituh263dec.o mpeg4videodec.o
276274 OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \
libavcodec/ac3.h+5−2
@@ -28,7 +28,8 @@ · 27 unmodified lines
2828 #define AVCODEC_AC3_H
2929
3030 #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 */
3233
3334 #define AC3_MAX_COEFS 256
3435 #define AC3_BLOCK_SIZE 256
@@ -158,7 +159,9 @@ typedef struct AC3EncOptions { · 123 unmodified lines
158159
159160 /* other encoding options */
160161 int allow_per_frame_metadata;
161− int stereo_rematrixing;
162+ int stereo_rematrixing;
163+ int channel_coupling;
164+ int cpl_start;
162165 } AC3EncOptions;
163166
164167
libavcodec/ac3dec.h+0−5
@@ -58,11 +58,6 @@ · 57 unmodified lines
5858 #include "fft.h"
5959 #include "fmtconvert.h"
6060
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−
6661 #define AC3_OUTPUT_LFEON 8
6762
6863 #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
5353 19, 19, 19, 19,
5454 };
5555
56−/**
57− * Table E2.16 Default Coupling Banding Structure
58− */
59−const uint8_t ff_eac3_default_cpl_band_struct[18] =
60−{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 };
61−
6256 /**
6357 * Table E2.15 Default Spectral Extension Banding Structure
6458 */
libavcodec/ac3dec_data.h+0−1
@@ -27,7 +27,6 @@ · 26 unmodified lines
2727 extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3];
2828
2929 extern const uint8_t ff_eac3_hebap_tab[64];
30−extern const uint8_t ff_eac3_default_cpl_band_struct[18];
3130 extern const uint8_t ff_eac3_default_spx_band_struct[17];
3231
3332 #endif /* AVCODEC_AC3DEC_DATA_H */
libavcodec/ac3enc.c+728−163
@@ -70,6 +70,7 @@ typedef struct AC3MDCTContext { · 69 unmodified lines
7070 FFTContext fft; ///< FFT context for MDCT calculation
7171 } AC3MDCTContext;
7272
73+
7374 /**
7475 * Data for a single audio block.
7576 */
@@ -83,10 +84,22 @@ typedef struct AC3Block { · 7 unmodified lines
8384 int16_t **band_psd; ///< psd per critical band
8485 int16_t **mask; ///< masking curve
8586 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)
8689 uint8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values
8790 uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block
91+ int num_rematrixing_bands; ///< number of rematrixing bands
8892 uint8_t rematrixing_flags[4]; ///< rematrixing flags
8993 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)
90103 } AC3Block;
91104
92105 /**
@@ -133,10 +146,16 @@ typedef struct AC3EncodeContext { · 40 unmodified lines
133146
134147 int cutoff; ///< user-specified cutoff frequency, in Hz
135148 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
137157
138158 int rematrixing_enabled; ///< stereo rematrixing enabled
139− int num_rematrixing_bands; ///< number of rematrixing bands
140159
141160 /* bitrate allocation control */
142161 int slow_gain_code; ///< slow gain code (sgaincod)
@@ -163,6 +182,8 @@ typedef struct AC3EncodeContext { · 20 unmodified lines
163182 int16_t *band_psd_buffer;
164183 int16_t *mask_buffer;
165184 uint16_t *qmant_buffer;
185+ uint8_t *cpl_coord_exp_buffer;
186+ uint8_t *cpl_coord_mant_buffer;
166187
167188 uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies
168189
@@ -237,6 +258,12 @@ const AVOption ff_ac3_options[] = { · 68 unmodified lines
237258 {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
238259 /* Other Encoding Options */
239260 {"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
240267 {NULL}
241268 };
242269 #endif
@@ -267,9 +294,9 @@ static void scale_coefficients(AC3EncodeContext *s); · 24 unmodified lines
267294
268295 /**
269296 * 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]
271298 */
272−static uint8_t exponent_group_tab[3][256];
299+static uint8_t exponent_group_tab[2][3][256];
273300
274301
275302 /**
@@ -330,6 +357,49 @@ static const uint8_t ac3_bandwidth_tab[5][3][19] = { · 54 unmodified lines
330357 };
331358
332359
360+/**
361+ * LUT to select the coupling start band based on the bit rate, sample rate, and
362+ * number of full-bandwidth channels. -1 = coupling off
363+ * ac3_coupling_start_tab[channel_mode-2][sample rate code][bit rate code]
364+ *
365+ * TODO: more testing for optimal parameters.
366+ * multi-channel tests at 44.1kHz and 32kHz.
367+ */
368+static const int8_t ac3_coupling_start_tab[6][3][19] = {
369+// 32 40 48 56 64 80 96 112 128 160 192 224 256 320 384 448 512 576 640
370+
371+ // 2/0
372+ { { 0, 0, 0, 0, 0, 0, 0, 1, 1, 7, 8, 11, 12, -1, -1, -1, -1, -1, -1 },
373+ { 0, 0, 0, 0, 0, 0, 1, 3, 5, 7, 10, 12, 13, -1, -1, -1, -1, -1, -1 },
374+ { 0, 0, 0, 0, 1, 2, 2, 9, 13, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
375+
376+ // 3/0
377+ { { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 },
378+ { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 },
379+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
380+
381+ // 2/1 - untested
382+ { { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 },
383+ { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, 9, 11, 12, 13, -1, -1, -1, -1 },
384+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
385+
386+ // 3/1
387+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 },
388+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 },
389+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
390+
391+ // 2/2 - untested
392+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 },
393+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 10, 11, 11, 12, 12, 14, -1 },
394+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
395+
396+ // 3/2
397+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 8, 11, 12, 12, -1, -1 },
398+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 8, 11, 12, 12, -1, -1 },
399+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } },
400+};
401+
402+
333403 /**
334404 * Adjust the frame size to make the average bit rate match the target bit rate.
335405 * This is only needed for 11025, 22050, and 44100 sample rates.
@@ -392,15 +462,297 @@ static void apply_mdct(AC3EncodeContext *s) · 56 unmodified lines
392462
393463 apply_window(&s->dsp, s->windowed_samples, input_samples, s->mdct.window, AC3_WINDOW_SIZE);
394464
395− block->coeff_shift[ch] = normalize_samples(s);
465+ block->coeff_shift[ch+1] = normalize_samples(s);
396466
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],
398468 s->windowed_samples);
399469 }
400470 }
401471 }
402472
403473
474+static void compute_coupling_strategy(AC3EncodeContext *s)
475+{
476+ int blk, ch;
477+ int got_cpl_snr;
478+
479+ /* set coupling use flags for each block/channel */
480+ /* TODO: turn coupling on/off and adjust start band based on bit usage */
481+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
482+ AC3Block *block = &s->blocks[blk];
483+ for (ch = 1; ch <= s->fbw_channels; ch++)
484+ block->channel_in_cpl[ch] = s->cpl_on;
485+ }
486+
487+ /* enable coupling for each block if at least 2 channels have coupling
488+ enabled for that block */
489+ got_cpl_snr = 0;
490+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
491+ AC3Block *block = &s->blocks[blk];
492+ block->num_cpl_channels = 0;
493+ for (ch = 1; ch <= s->fbw_channels; ch++)
494+ block->num_cpl_channels += block->channel_in_cpl[ch];
495+ block->cpl_in_use = block->num_cpl_channels > 1;
496+ if (!block->cpl_in_use) {
497+ block->num_cpl_channels = 0;
498+ for (ch = 1; ch <= s->fbw_channels; ch++)
499+ block->channel_in_cpl[ch] = 0;
500+ }
501+
502+ block->new_cpl_strategy = !blk;
503+ if (blk) {
504+ for (ch = 1; ch <= s->fbw_channels; ch++) {
505+ if (block->channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) {
506+ block->new_cpl_strategy = 1;
507+ break;
508+ }
509+ }
510+ }
511+ block->new_cpl_leak = block->new_cpl_strategy;
512+
513+ if (!blk || (block->cpl_in_use && !got_cpl_snr)) {
514+ block->new_snr_offsets = 1;
515+ if (block->cpl_in_use)
516+ got_cpl_snr = 1;
517+ } else {
518+ block->new_snr_offsets = 0;
519+ }
520+ }
521+
522+ /* set bandwidth for each channel */
523+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
524+ AC3Block *block = &s->blocks[blk];
525+ for (ch = 1; ch <= s->fbw_channels; ch++) {
526+ if (block->channel_in_cpl[ch])
527+ block->end_freq[ch] = s->start_freq[CPL_CH];
528+ else
529+ block->end_freq[ch] = s->bandwidth_code * 3 + 73;
530+ }
531+ }
532+}
533+
534+
535+/**
536+ * Calculate a single coupling coordinate.
537+ */
538+static inline float calc_cpl_coord(float energy_ch, float energy_cpl)
539+{
540+ float coord = 0.125;
541+ if (energy_cpl > 0)
542+ coord *= sqrtf(energy_ch / energy_cpl);
543+ return coord;
544+}
545+
546+
547+/**
548+ * Calculate coupling channel and coupling coordinates.
549+ * TODO: Currently this is only used for the floating-point encoder. I was
550+ * able to make it work for the fixed-point encoder, but quality was
551+ * generally lower in most cases than not using coupling. If a more
552+ * adaptive coupling strategy were to be implemented it might be useful
553+ * at that time to use coupling for the fixed-point encoder as well.
554+ */
555+static void apply_channel_coupling(AC3EncodeContext *s)
556+{
557+#if CONFIG_AC3ENC_FLOAT
558+ DECLARE_ALIGNED(16, float, cpl_coords) [AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16];
559+ DECLARE_ALIGNED(16, int32_t, fixed_cpl_coords)[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16];
560+ int blk, ch, bnd, i, j;
561+ CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}};
562+ int num_cpl_coefs = s->num_cpl_subbands * 12;
563+
564+ /* calculate coupling channel from fbw channels */
565+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
566+ AC3Block *block = &s->blocks[blk];
567+ CoefType *cpl_coef = &block->mdct_coef[CPL_CH][s->start_freq[CPL_CH]];
568+ if (!block->cpl_in_use)
569+ continue;
570+ memset(cpl_coef-1, 0, (num_cpl_coefs+4) * sizeof(*cpl_coef));
571+ for (ch = 1; ch <= s->fbw_channels; ch++) {
572+ CoefType *ch_coef = &block->mdct_coef[ch][s->start_freq[CPL_CH]];
573+ if (!block->channel_in_cpl[ch])
574+ continue;
575+ for (i = 0; i < num_cpl_coefs; i++)
576+ cpl_coef[i] += ch_coef[i];
577+ }
578+ /* note: coupling start bin % 4 will always be 1 and num_cpl_coefs
579+ will always be a multiple of 12, so we need to subtract 1 from
580+ the start and add 4 to the length when using optimized
581+ functions which require 16-byte alignment. */
582+
583+ /* coefficients must be clipped to +/- 1.0 in order to be encoded */
584+ s->dsp.vector_clipf(cpl_coef-1, cpl_coef-1, -1.0f, 1.0f, num_cpl_coefs+4);
585+
586+ /* scale coupling coefficients from float to 24-bit fixed-point */
587+ s->ac3dsp.float_to_fixed24(&block->fixed_coef[CPL_CH][s->start_freq[CPL_CH]-1],
588+ cpl_coef-1, num_cpl_coefs+4);
589+ }
590+
591+ /* calculate energy in each band in coupling channel and each fbw channel */
592+ /* TODO: possibly use SIMD to speed up energy calculation */
593+ bnd = 0;
594+ i = s->start_freq[CPL_CH];
595+ while (i < s->cpl_end_freq) {
596+ int band_size = s->cpl_band_sizes[bnd];
597+ for (ch = CPL_CH; ch <= s->fbw_channels; ch++) {
598+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
599+ AC3Block *block = &s->blocks[blk];
600+ if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch]))
601+ continue;
602+ for (j = 0; j < band_size; j++) {
603+ CoefType v = block->mdct_coef[ch][i+j];
604+ MAC_COEF(energy[blk][ch][bnd], v, v);
605+ }
606+ }
607+ }
608+ i += band_size;
609+ bnd++;
610+ }
611+
612+ /* determine which blocks to send new coupling coordinates for */
613+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
614+ AC3Block *block = &s->blocks[blk];
615+ AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL;
616+ int new_coords = 0;
617+ CoefSumType coord_diff[AC3_MAX_CHANNELS] = {0,};
618+
619+ if (block->cpl_in_use) {
620+ /* calculate coupling coordinates for all blocks and calculate the
621+ average difference between coordinates in successive blocks */
622+ for (ch = 1; ch <= s->fbw_channels; ch++) {
623+ if (!block->channel_in_cpl[ch])
624+ continue;
625+
626+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
627+ cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd],
628+ energy[blk][CPL_CH][bnd]);
629+ if (blk > 0 && block0->cpl_in_use &&
630+ block0->channel_in_cpl[ch]) {
631+ coord_diff[ch] += fabs(cpl_coords[blk-1][ch][bnd] -
632+ cpl_coords[blk ][ch][bnd]);
633+ }
634+ }
635+ coord_diff[ch] /= s->num_cpl_bands;
636+ }
637+
638+ /* send new coordinates if this is the first block, if previous
639+ * block did not use coupling but this block does, the channels
640+ * using coupling has changed from the previous block, or the
641+ * coordinate difference from the last block for any channel is
642+ * greater than a threshold value. */
643+ if (blk == 0) {
644+ new_coords = 1;
645+ } else if (!block0->cpl_in_use) {
646+ new_coords = 1;
647+ } else {
648+ for (ch = 1; ch <= s->fbw_channels; ch++) {
649+ if (block->channel_in_cpl[ch] && !block0->channel_in_cpl[ch]) {
650+ new_coords = 1;
651+ break;
652+ }
653+ }
654+ if (!new_coords) {
655+ for (ch = 1; ch <= s->fbw_channels; ch++) {
656+ if (block->channel_in_cpl[ch] && coord_diff[ch] > 0.04) {
657+ new_coords = 1;
658+ break;
659+ }
660+ }
661+ }
662+ }
663+ }
664+ block->new_cpl_coords = new_coords;
665+ }
666+
667+ /* calculate final coupling coordinates, taking into account reusing of
668+ coordinates in successive blocks */
669+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
670+ blk = 0;
671+ while (blk < AC3_MAX_BLOCKS) {
672+ int blk1;
673+ CoefSumType energy_cpl;
674+ AC3Block *block = &s->blocks[blk];
675+
676+ if (!block->cpl_in_use) {
677+ blk++;
678+ continue;
679+ }
680+
681+ energy_cpl = energy[blk][CPL_CH][bnd];
682+ blk1 = blk+1;
683+ while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) {
684+ if (s->blocks[blk1].cpl_in_use)
685+ energy_cpl += energy[blk1][CPL_CH][bnd];
686+ blk1++;
687+ }
688+
689+ for (ch = 1; ch <= s->fbw_channels; ch++) {
690+ CoefType energy_ch;
691+ if (!block->channel_in_cpl[ch])
692+ continue;
693+ energy_ch = energy[blk][ch][bnd];
694+ blk1 = blk+1;
695+ while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) {
696+ if (s->blocks[blk1].cpl_in_use)
697+ energy_ch += energy[blk1][ch][bnd];
698+ blk1++;
699+ }
700+ cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl);
701+ }
702+ blk = blk1;
703+ }
704+ }
705+
706+ /* calculate exponents/mantissas for coupling coordinates */
707+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
708+ AC3Block *block = &s->blocks[blk];
709+ if (!block->cpl_in_use || !block->new_cpl_coords)
710+ continue;
711+
712+ s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1],
713+ cpl_coords[blk][1],
714+ s->fbw_channels * 16);
715+ s->ac3dsp.extract_exponents(block->cpl_coord_exp[1],
716+ fixed_cpl_coords[blk][1],
717+ s->fbw_channels * 16);
718+
719+ for (ch = 1; ch <= s->fbw_channels; ch++) {
720+ int bnd, min_exp, max_exp, master_exp;
721+
722+ /* determine master exponent */
723+ min_exp = max_exp = block->cpl_coord_exp[ch][0];
724+ for (bnd = 1; bnd < s->num_cpl_bands; bnd++) {
725+ int exp = block->cpl_coord_exp[ch][bnd];
726+ min_exp = FFMIN(exp, min_exp);
727+ max_exp = FFMAX(exp, max_exp);
728+ }
729+ master_exp = ((max_exp - 15) + 2) / 3;
730+ master_exp = FFMAX(master_exp, 0);
731+ while (min_exp < master_exp * 3)
732+ master_exp--;
733+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
734+ block->cpl_coord_exp[ch][bnd] = av_clip(block->cpl_coord_exp[ch][bnd] -
735+ master_exp * 3, 0, 15);
736+ }
737+ block->cpl_master_exp[ch] = master_exp;
738+
739+ /* quantize mantissas */
740+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
741+ int cpl_exp = block->cpl_coord_exp[ch][bnd];
742+ int cpl_mant = (fixed_cpl_coords[blk][ch][bnd] << (5 + cpl_exp + master_exp * 3)) >> 24;
743+ if (cpl_exp == 15)
744+ cpl_mant >>= 1;
745+ else
746+ cpl_mant -= 16;
747+
748+ block->cpl_coord_mant[ch][bnd] = cpl_mant;
749+ }
750+ }
751+ }
752+#endif /* CONFIG_AC3ENC_FLOAT */
753+}
754+
755+
404756 /**
405757 * Determine rematrixing flags for each block and band.
406758 */
@@ -413,23 +765,32 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) · 6 unmodified lines
413765 if (s->channel_mode != AC3_CHMODE_STEREO)
414766 return;
415767
416− s->num_rematrixing_bands = 4;
417−
418− nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]);
419−
420768 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
421769 block = &s->blocks[blk];
422770 block->new_rematrixing_strategy = !blk;
423− if (!s->rematrixing_enabled)
771+
772+ if (!s->rematrixing_enabled) {
773+ block0 = block;
424774 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++) {
426787 /* calculate calculate sum of squared coeffs for one band in one block */
427788 int start = ff_ac3_rematrix_band_tab[bnd];
428789 int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
429790 CoefSumType sum[4] = {0,};
430791 for (i = start; i < end; i++) {
431− CoefType lt = block->mdct_coef[0][i];
432− CoefType rt = block->mdct_coef[1][i];
792+ CoefType lt = block->mdct_coef[1][i];
793+ CoefType rt = block->mdct_coef[2][i];
433794 CoefType md = lt + rt;
434795 CoefType sd = lt - rt;
435796 MAC_COEF(sum[0], lt, lt);
@@ -468,21 +829,20 @@ static void apply_rematrixing(AC3EncodeContext *s) · 32 unmodified lines
468829 if (!s->rematrixing_enabled)
469830 return;
470831
471− nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]);
472−
473832 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
474833 AC3Block *block = &s->blocks[blk];
475834 if (block->new_rematrixing_strategy)
476835 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++) {
478838 if (flags[bnd]) {
479839 start = ff_ac3_rematrix_band_tab[bnd];
480840 end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
481841 for (i = start; i < end; i++) {
482− int32_t lt = block->fixed_coef[0][i];
483− int32_t rt = block->fixed_coef[1][i];
484− block->fixed_coef[0][i] = (lt + rt) >> 1;
485− block->fixed_coef[1][i] = (lt - rt) >> 1;
842+ int32_t lt = block->fixed_coef[1][i];
843+ int32_t rt = block->fixed_coef[2][i];
844+ block->fixed_coef[1][i] = (lt + rt) >> 1;
845+ block->fixed_coef[2][i] = (lt - rt) >> 1;
486846 }
487847 }
488848 }
@@ -499,12 +859,13 @@ static av_cold void exponent_init(AC3EncodeContext *s) · 10 unmodified lines
499859
500860 for (expstr = EXP_D15-1; expstr <= EXP_D45-1; expstr++) {
501861 grpsize = 3 << expstr;
502− for (i = 73; i < 256; i++) {
503− exponent_group_tab[expstr][i] = (i + grpsize - 4) / grpsize;
862+ for (i = 12; i < 256; i++) {
863+ exponent_group_tab[0][expstr][i] = (i + grpsize - 4) / grpsize;
864+ exponent_group_tab[1][expstr][i] = (i ) / grpsize;
504865 }
505866 }
506867 /* LFE */
507− exponent_group_tab[0][7] = 2;
868+ exponent_group_tab[0][0][7] = 2;
508869 }
509870
510871
@@ -517,7 +878,7 @@ static void extract_exponents(AC3EncodeContext *s) · 6 unmodified lines
517878 {
518879 int blk, ch;
519880
520− for (ch = 0; ch < s->channels; ch++) {
881+ for (ch = !s->cpl_on; ch <= s->channels; ch++) {
521882 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
522883 AC3Block *block = &s->blocks[blk];
523884 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
542903 {
543904 int ch, blk, blk1;
544905
545− for (ch = 0; ch < s->fbw_channels; ch++) {
906+ for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) {
546907 uint8_t *exp_strategy = s->exp_strategy[ch];
547908 uint8_t *exp = s->blocks[0].exp[ch];
548909 int exp_diff;
@@ -551,13 +912,18 @@ static void compute_exp_strategy(AC3EncodeContext *s) · 2 unmodified lines
551912 reused in the next frame */
552913 exp_strategy[0] = EXP_NEW;
553914 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+ }
555921 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)
557926 exp_strategy[blk] = EXP_NEW;
558− else
559− exp_strategy[blk] = EXP_REUSE;
560− exp += AC3_MAX_COEFS;
561927 }
562928
563929 /* now select the encoding strategy type : if exponents are often
@@ -588,25 +954,26 @@ static void compute_exp_strategy(AC3EncodeContext *s) · 24 unmodified lines
588954 /**
589955 * Update the exponents so that they are the ones the decoder will decode.
590956 */
591−static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy)
957+static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy,
958+ int cpl)
592959 {
593960 int nb_groups, i, k;
594961
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;
596963
597964 /* for each group, compute the minimum exponent */
598965 switch(exp_strategy) {
599966 case EXP_D25:
600− for (i = 1, k = 1; i <= nb_groups; i++) {
967+ for (i = 1, k = 1-cpl; i <= nb_groups; i++) {
601968 uint8_t exp_min = exp[k];
602969 if (exp[k+1] < exp_min)
603970 exp_min = exp[k+1];
604− exp[i] = exp_min;
971+ exp[i-cpl] = exp_min;
605972 k += 2;
606973 }
607974 break;
608975 case EXP_D45:
609− for (i = 1, k = 1; i <= nb_groups; i++) {
976+ for (i = 1, k = 1-cpl; i <= nb_groups; i++) {
610977 uint8_t exp_min = exp[k];
611978 if (exp[k+1] < exp_min)
612979 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
614981 exp_min = exp[k+2];
615982 if (exp[k+3] < exp_min)
616983 exp_min = exp[k+3];
617− exp[i] = exp_min;
984+ exp[i-cpl] = exp_min;
618985 k += 4;
619986 }
620987 break;
621988 }
622989
623990 /* constraint for DC exponent */
624− if (exp[0] > 15)
991+ if (!cpl && exp[0] > 15)
625992 exp[0] = 15;
626993
627994 /* 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
632999 while (--i >= 0)
6331000 exp[i] = FFMIN(exp[i], exp[i+1] + 2);
6341001
1002+ if (cpl)
1003+ exp[-1] = exp[0] & ~1;
1004+
6351005 /* now we have the exponent values the decoder will see */
6361006 switch (exp_strategy) {
6371007 case EXP_D25:
638− for (i = nb_groups, k = nb_groups * 2; i > 0; i--) {
639− uint8_t exp1 = exp[i];
1008+ for (i = nb_groups, k = (nb_groups * 2)-cpl; i > 0; i--) {
1009+ uint8_t exp1 = exp[i-cpl];
6401010 exp[k--] = exp1;
6411011 exp[k--] = exp1;
6421012 }
6431013 break;
6441014 case EXP_D45:
645− for (i = nb_groups, k = nb_groups * 4; i > 0; i--) {
646− exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i];
1015+ for (i = nb_groups, k = (nb_groups * 4)-cpl; i > 0; i--) {
1016+ exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i-cpl];
6471017 k -= 4;
6481018 }
6491019 break;
@@ -659,32 +1029,40 @@ static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy) · 9 unmodified lines
6591029 */
6601030 static void encode_exponents(AC3EncodeContext *s)
6611031 {
662− int blk, blk1, ch;
1032+ int blk, blk1, ch, cpl;
6631033 uint8_t *exp, *exp_strategy;
6641034 int nb_coefs, num_reuse_blocks;
6651035
666− for (ch = 0; ch < s->channels; ch++) {
667− exp = s->blocks[0].exp[ch];
1036+ for (ch = !s->cpl_on; ch <= s->channels; ch++) {
1037+ exp = s->blocks[0].exp[ch] + s->start_freq[ch];
6681038 exp_strategy = s->exp_strategy[ch];
669− nb_coefs = s->nb_coefs[ch];
6701039
1040+ cpl = (ch == CPL_CH);
6711041 blk = 0;
6721042 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];
6731050 blk1 = blk + 1;
6741051
6751052 /* count the number of EXP_REUSE blocks after the current block
6761053 and set exponent reference block pointers */
677− s->blocks[blk].exp_ref_block[ch] = &s->blocks[blk];
1054+ block->exp_ref_block[ch] = block;
6781055 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;
6801057 blk1++;
6811058 }
6821059 num_reuse_blocks = blk1 - blk - 1;
6831060
6841061 /* 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);
6861064
687− encode_exponents_blk_ch(exp, nb_coefs, exp_strategy[blk]);
1065+ encode_exponents_blk_ch(exp, nb_coefs, exp_strategy[blk], cpl);
6881066
6891067 exp += AC3_MAX_COEFS * (num_reuse_blocks + 1);
6901068 blk = blk1;
@@ -700,7 +1078,7 @@ static void encode_exponents(AC3EncodeContext *s) · 9 unmodified lines
7001078 */
7011079 static void group_exponents(AC3EncodeContext *s)
7021080 {
703− int blk, ch, i;
1081+ int blk, ch, i, cpl;
7041082 int group_size, nb_groups, bit_count;
7051083 uint8_t *p;
7061084 int delta0, delta1, delta2;
@@ -709,14 +1087,15 @@ static void group_exponents(AC3EncodeContext *s) · 2 unmodified lines
7091087 bit_count = 0;
7101088 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
7111089 AC3Block *block = &s->blocks[blk];
712− for (ch = 0; ch < s->channels; ch++) {
1090+ for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
7131091 int exp_strategy = s->exp_strategy[ch][blk];
7141092 if (exp_strategy == EXP_REUSE)
7151093 continue;
1094+ cpl = (ch == CPL_CH);
7161095 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]];
7181097 bit_count += 4 + (nb_groups * 7);
719− p = block->exp[ch];
1098+ p = block->exp[ch] + s->start_freq[ch] - cpl;
7201099
7211100 /* DC exponent */
7221101 exp1 = *p++;
@@ -783,9 +1162,7 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 60 unmodified lines
7831162
7841163 /* assumptions:
7851164 * no dynamic range codes
786− * no channel coupling
7871165 * bit allocation parameters do not change between blocks
788− * SNR offsets do not change between blocks
7891166 * no delta bit allocation
7901167 * no skipped data
7911168 * no auxilliary data
@@ -806,11 +1183,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 14 unmodified lines
8061183 /* dynamic range */
8071184 frame_bits++;
8081185
809− /* coupling strategy */
810− frame_bits++;
811− if (!blk)
812− frame_bits++;
813−
8141186 /* exponent strategy */
8151187 frame_bits += 2 * s->fbw_channels;
8161188 if (s->lfe_on)
@@ -821,11 +1193,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) · 4 unmodified lines
8211193 if (!blk)
8221194 frame_bits += 2 + 2 + 2 + 2 + 3;
8231195
824− /* snr offsets and fast gain codes */
825− frame_bits++;
826− if (!blk)
827− frame_bits += 6 + s->channels * (4 + 3);
828−
8291196 /* delta bit allocation */
8301197 frame_bits++;
8311198
@@ -857,7 +1224,7 @@ static void bit_alloc_init(AC3EncodeContext *s) · 25 unmodified lines
8571224 s->slow_gain_code = 1;
8581225 s->db_per_bit_code = 3;
8591226 s->floor_code = 7;
860− for (ch = 0; ch < s->channels; ch++)
1227+ for (ch = 0; ch <= s->channels; ch++)
8611228 s->fast_gain_code[ch] = 4;
8621229
8631230 /* initial snr offset */
@@ -871,6 +1238,8 @@ static void bit_alloc_init(AC3EncodeContext *s) · 7 unmodified lines
8711238 s->bit_alloc.slow_gain = ff_ac3_slow_gain_tab[s->slow_gain_code];
8721239 s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code];
8731240 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;
8741243
8751244 count_frame_bits_fixed(s);
8761245 }
@@ -899,17 +1268,64 @@ static void count_frame_bits(AC3EncodeContext *s) · 22 unmodified lines
8991268
9001269 /* audio blocks */
9011270 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+
9021299 /* stereo rematrixing */
9031300 if (s->channel_mode == AC3_CHMODE_STEREO) {
9041301 frame_bits++;
9051302 if (s->blocks[blk].new_rematrixing_strategy)
906− frame_bits += s->num_rematrixing_bands;
1303+ frame_bits += block->num_rematrixing_bands;
9071304 }
9081305
9091306 /* bandwidth codes & gain range */
910− for (ch = 0; ch < s->fbw_channels; ch++) {
911− if (s->exp_strategy[ch][blk] != EXP_REUSE)
912− frame_bits += 6 + 2;
1307+ for (ch = 1; ch <= s->fbw_channels; ch++) {
1308+ if (s->exp_strategy[ch][blk] != EXP_REUSE) {
1309+ if (!block->channel_in_cpl[ch])
1310+ frame_bits += 6;
1311+ frame_bits += 2;
1312+ }
1313+ }
1314+
1315+ /* coupling exponent strategy */
1316+ if (block->cpl_in_use)
1317+ frame_bits += 2;
1318+
1319+ /* snr offsets and fast gain codes */
1320+ frame_bits++;
1321+ if (block->new_snr_offsets)
1322+ frame_bits += 6 + (s->channels + block->cpl_in_use) * (4 + 3);
1323+
1324+ /* coupling leak info */
1325+ if (block->cpl_in_use) {
1326+ frame_bits++;
1327+ if (block->new_cpl_leak)
1328+ frame_bits += 3 + 3;
9131329 }
9141330 }
9151331
@@ -943,16 +1359,16 @@ static void bit_alloc_masking(AC3EncodeContext *s) · 27 unmodified lines
9431359
9441360 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
9451361 AC3Block *block = &s->blocks[blk];
946− for (ch = 0; ch < s->channels; ch++) {
1362+ for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
9471363 /* We only need psd and mask for calculating bap.
9481364 Since we currently do not calculate bap when exponent
9491365 strategy is EXP_REUSE we do not need to calculate psd or mask. */
9501366 if (s->exp_strategy[ch][blk] != EXP_REUSE) {
951− ff_ac3_bit_alloc_calc_psd(block->exp[ch], 0,
952− s->nb_coefs[ch],
953− block->psd[ch], block->band_psd[ch]);
1367+ ff_ac3_bit_alloc_calc_psd(block->exp[ch], s->start_freq[ch],
1368+ block->end_freq[ch], block->psd[ch],
1369+ block->band_psd[ch]);
9541370 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],
9561372 ff_ac3_fast_gain_tab[s->fast_gain_code[ch]],
9571373 ch == s->lfe_channel,
9581374 DBA_NONE, 0, NULL, NULL, NULL,
@@ -970,11 +1386,12 @@ static void bit_alloc_masking(AC3EncodeContext *s) · 11 unmodified lines
9701386 static void reset_block_bap(AC3EncodeContext *s)
9711387 {
9721388 int blk, ch;
1389+ int channels = s->channels + 1;
9731390 if (s->blocks[0].bap[0] == s->bap_buffer)
9741391 return;
9751392 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
976− for (ch = 0; ch < s->channels; ch++) {
977− s->blocks[blk].bap[ch] = &s->bap_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)];
1393+ for (ch = 0; ch < channels; ch++) {
1394+ s->blocks[blk].bap[ch] = &s->bap_buffer[AC3_MAX_COEFS * (blk * channels + ch)];
9781395 }
9791396 }
9801397 }
@@ -1000,28 +1417,37 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset) · 19 unmodified lines
10001417 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
10011418 AC3Block *block = &s->blocks[blk];
10021419 AC3Block *ref_block;
1420+ int av_uninit(ch0);
1421+ int got_cpl = !block->cpl_in_use;
10031422 // initialize grouped mantissa counts. these are set so that they are
10041423 // padded to the next whole group size when bits are counted in
10051424 // compute_mantissa_size_final
10061425 mant_cnt[0] = mant_cnt[3] = 0;
10071426 mant_cnt[1] = mant_cnt[2] = 2;
10081427 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+
10101435 /* Currently the only bit allocation parameters which vary across
10111436 blocks within a frame are the exponent values. We can take
10121437 advantage of that by reusing the bit allocation pointers
10131438 whenever we reuse exponents. */
10141439 ref_block = block->exp_ref_block[ch];
10151440 if (s->exp_strategy[ch][blk] != EXP_REUSE) {
1016− s->ac3dsp.bit_alloc_calc_bap(ref_block->mask[ch],
1017− ref_block->psd[ch], 0,
1018− s->nb_coefs[ch], snr_offset,
1019− s->bit_alloc.floor, ff_ac3_bap_tab,
1020− ref_block->bap[ch]);
1441+ s->ac3dsp.bit_alloc_calc_bap(ref_block->mask[ch], ref_block->psd[ch],
1442+ s->start_freq[ch], block->end_freq[ch],
1443+ snr_offset, s->bit_alloc.floor,
1444+ ff_ac3_bap_tab, ref_block->bap[ch]);
10211445 }
10221446 mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt,
1023− ref_block->bap[ch],
1024− s->nb_coefs[ch]);
1447+ ref_block->bap[ch]+s->start_freq[ch],
1448+ block->end_freq[ch]-s->start_freq[ch]);
1449+ if (ch == CPL_CH)
1450+ ch = ch0;
10251451 }
10261452 mantissa_bits += compute_mantissa_size_final(mant_cnt);
10271453 }
@@ -1047,7 +1473,7 @@ static int cbr_bit_allocation(AC3EncodeContext *s) · 19 unmodified lines
10471473
10481474 /* if previous frame SNR offset was 1023, check if current frame can also
10491475 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) {
10511477 if (bit_alloc(s, 1023) <= bits_left)
10521478 return 0;
10531479 }
@@ -1071,7 +1497,7 @@ static int cbr_bit_allocation(AC3EncodeContext *s) · 17 unmodified lines
10711497 reset_block_bap(s);
10721498
10731499 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++)
10751501 s->fine_snr_offset[ch] = snr_offset & 0xF;
10761502
10771503 return 0;
@@ -1089,26 +1515,26 @@ static int downgrade_exponents(AC3EncodeContext *s) · 11 unmodified lines
10891515 {
10901516 int ch, blk;
10911517
1092− for (ch = 0; ch < s->fbw_channels; ch++) {
1093− for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) {
1518+ for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) {
1519+ for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) {
10941520 if (s->exp_strategy[ch][blk] == EXP_D15) {
10951521 s->exp_strategy[ch][blk] = EXP_D25;
10961522 return 0;
10971523 }
10981524 }
10991525 }
1100− for (ch = 0; ch < s->fbw_channels; ch++) {
1101− for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) {
1526+ for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) {
1527+ for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) {
11021528 if (s->exp_strategy[ch][blk] == EXP_D25) {
11031529 s->exp_strategy[ch][blk] = EXP_D45;
11041530 return 0;
11051531 }
11061532 }
11071533 }
1108− for (ch = 0; ch < s->fbw_channels; ch++) {
1109− /* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if
1110− the block number > 0 */
1111− for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) {
1534+ /* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if
1535+ the block number > 0 */
1536+ for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) {
1537+ for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) {
11121538 if (s->exp_strategy[ch][blk] > EXP_REUSE) {
11131539 s->exp_strategy[ch][blk] = EXP_REUSE;
11141540 return 0;
@@ -1135,7 +1561,18 @@ static int compute_bit_allocation(AC3EncodeContext *s) · 20 unmodified lines
11351561
11361562 ret = cbr_bit_allocation(s);
11371563 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 */
11391576 if (!downgrade_exponents(s)) {
11401577 extract_exponents(s);
11411578 encode_exponents(s);
@@ -1189,12 +1626,13 @@ static inline int asym_quant(int c, int e, int qbits) · 47 unmodified lines
11891626 * Quantize a set of mantissas for a single channel in a single block.
11901627 */
11911628 static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef,
1192− uint8_t *exp,
1193− uint8_t *bap, uint16_t *qmant, int n)
1629+ uint8_t *exp, uint8_t *bap,
1630+ uint16_t *qmant, int start_freq,
1631+ int end_freq)
11941632 {
11951633 int i;
11961634
1197− for (i = 0; i < n; i++) {
1635+ for (i = start_freq; i < end_freq; i++) {
11981636 int v;
11991637 int c = fixed_coef[i];
12001638 int e = exp[i];
@@ -1284,19 +1722,27 @@ static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, · 83 unmodified lines
12841722 */
12851723 static void quantize_mantissas(AC3EncodeContext *s)
12861724 {
1287− int blk, ch;
1288−
1725+ int blk, ch, ch0=0, got_cpl;
12891726
12901727 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
12911728 AC3Block *block = &s->blocks[blk];
12921729 AC3Block *ref_block;
12931730 AC3Mant m = { 0 };
12941731
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+ }
12961739 ref_block = block->exp_ref_block[ch];
12971740 quantize_mantissas_blk_ch(&m, block->fixed_coef[ch],
1298− ref_block->exp[ch], ref_block->bap[ch],
1299− block->qmant[ch], s->nb_coefs[ch]);
1741+ ref_block->exp[ch],
1742+ ref_block->bap[ch], block->qmant[ch],
1743+ s->start_freq[ch], block->end_freq[ch]);
1744+ if (ch == CPL_CH)
1745+ ch = ch0;
13001746 }
13011747 }
13021748 }
@@ -1363,7 +1809,8 @@ static void output_frame_header(AC3EncodeContext *s) · 60 unmodified lines
13631809 */
13641810 static void output_audio_block(AC3EncodeContext *s, int blk)
13651811 {
1366− int ch, i, baie, rbnd;
1812+ int ch, i, baie, bnd, got_cpl;
1813+ int av_uninit(ch0);
13671814 AC3Block *block = &s->blocks[blk];
13681815
13691816 /* block switching */
@@ -1378,11 +1825,38 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 8 unmodified lines
13781825 put_bits(&s->pb, 1, 0);
13791826
13801827 /* channel coupling */
1381− if (!blk) {
1382− put_bits(&s->pb, 1, 1); /* coupling strategy present */
1383− put_bits(&s->pb, 1, 0); /* no coupling strategy */
1384− } else {
1385− put_bits(&s->pb, 1, 0); /* no new coupling strategy */
1828+ put_bits(&s->pb, 1, block->new_cpl_strategy);
1829+ if (block->new_cpl_strategy) {
1830+ put_bits(&s->pb, 1, block->cpl_in_use);
1831+ if (block->cpl_in_use) {
1832+ int start_sub, end_sub;
1833+ for (ch = 1; ch <= s->fbw_channels; ch++)
1834+ put_bits(&s->pb, 1, block->channel_in_cpl[ch]);
1835+ if (s->channel_mode == AC3_CHMODE_STEREO)
1836+ put_bits(&s->pb, 1, 0); /* phase flags in use */
1837+ start_sub = (s->start_freq[CPL_CH] - 37) / 12;
1838+ end_sub = (s->cpl_end_freq - 37) / 12;
1839+ put_bits(&s->pb, 4, start_sub);
1840+ put_bits(&s->pb, 4, end_sub - 3);
1841+ for (bnd = start_sub+1; bnd < end_sub; bnd++)
1842+ put_bits(&s->pb, 1, ff_eac3_default_cpl_band_struct[bnd]);
1843+ }
1844+ }
1845+
1846+ /* coupling coordinates */
1847+ if (block->cpl_in_use) {
1848+ for (ch = 1; ch <= s->fbw_channels; ch++) {
1849+ if (block->channel_in_cpl[ch]) {
1850+ put_bits(&s->pb, 1, block->new_cpl_coords);
1851+ if (block->new_cpl_coords) {
1852+ put_bits(&s->pb, 2, block->cpl_master_exp[ch]);
1853+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
1854+ put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]);
1855+ put_bits(&s->pb, 4, block->cpl_coord_mant[ch][bnd]);
1856+ }
1857+ }
1858+ }
1859+ }
13861860 }
13871861
13881862 /* stereo rematrixing */
@@ -1390,40 +1864,41 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 1 unmodified line
13901864 put_bits(&s->pb, 1, block->new_rematrixing_strategy);
13911865 if (block->new_rematrixing_strategy) {
13921866 /* rematrixing flags */
1393− for (rbnd = 0; rbnd < s->num_rematrixing_bands; rbnd++)
1394− put_bits(&s->pb, 1, block->rematrixing_flags[rbnd]);
1867+ for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++)
1868+ put_bits(&s->pb, 1, block->rematrixing_flags[bnd]);
13951869 }
13961870 }
13971871
13981872 /* exponent strategy */
1399− for (ch = 0; ch < s->fbw_channels; ch++)
1873+ for (ch = !block->cpl_in_use; ch <= s->fbw_channels; ch++)
14001874 put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
14011875 if (s->lfe_on)
14021876 put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);
14031877
14041878 /* bandwidth */
1405− for (ch = 0; ch < s->fbw_channels; ch++) {
1406− if (s->exp_strategy[ch][blk] != EXP_REUSE)
1879+ for (ch = 1; ch <= s->fbw_channels; ch++) {
1880+ if (s->exp_strategy[ch][blk] != EXP_REUSE && !block->channel_in_cpl[ch])
14071881 put_bits(&s->pb, 6, s->bandwidth_code);
14081882 }
14091883
14101884 /* exponents */
1411− for (ch = 0; ch < s->channels; ch++) {
1885+ for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
14121886 int nb_groups;
1887+ int cpl = (ch == CPL_CH);
14131888
14141889 if (s->exp_strategy[ch][blk] == EXP_REUSE)
14151890 continue;
14161891
14171892 /* 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);
14191894
14201895 /* 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]];
14221897 for (i = 1; i <= nb_groups; i++)
14231898 put_bits(&s->pb, 7, block->grouped_exp[ch][i]);
14241899
14251900 /* gain range info */
1426− if (ch != s->lfe_channel)
1901+ if (ch != s->lfe_channel && !cpl)
14271902 put_bits(&s->pb, 2, 0);
14281903 }
14291904
@@ -1439,23 +1914,40 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 9 unmodified lines
14391914 }
14401915
14411916 /* snr offset */
1442− put_bits(&s->pb, 1, baie);
1443− if (baie) {
1917+ put_bits(&s->pb, 1, block->new_snr_offsets);
1918+ if (block->new_snr_offsets) {
14441919 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++) {
14461921 put_bits(&s->pb, 4, s->fine_snr_offset[ch]);
14471922 put_bits(&s->pb, 3, s->fast_gain_code[ch]);
14481923 }
14491924 }
14501925
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+
14511935 put_bits(&s->pb, 1, 0); /* no delta bit allocation */
14521936 put_bits(&s->pb, 1, 0); /* no data to skip */
14531937
14541938 /* mantissas */
1455− for (ch = 0; ch < s->channels; ch++) {
1939+ got_cpl = !block->cpl_in_use;
1940+ for (ch = 1; ch <= s->channels; ch++) {
14561941 int b, q;
1457− AC3Block *ref_block = block->exp_ref_block[ch];
1458− for (i = 0; i < s->nb_coefs[ch]; i++) {
1942+ AC3Block *ref_block;
1943+
1944+ if (!got_cpl && ch > 1 && block->channel_in_cpl[ch-1]) {
1945+ ch0 = ch - 1;
1946+ ch = CPL_CH;
1947+ got_cpl = 1;
1948+ }
1949+ ref_block = block->exp_ref_block[ch];
1950+ for (i = s->start_freq[ch]; i < block->end_freq[ch]; i++) {
14591951 q = block->qmant[ch][i];
14601952 b = ref_block->bap[ch][i];
14611953 switch (b) {
@@ -1469,6 +1961,8 @@ static void output_audio_block(AC3EncodeContext *s, int blk) · 7 unmodified lines
14691961 default: put_bits(&s->pb, b-1, q); break;
14701962 }
14711963 }
1964+ if (ch == CPL_CH)
1965+ ch = ch0;
14721966 }
14731967 }
14741968
@@ -1854,6 +2348,12 @@ static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame, · 379 unmodified lines
18542348
18552349 scale_coefficients(s);
18562350
2351+ s->cpl_on = s->cpl_enabled;
2352+ compute_coupling_strategy(s);
2353+
2354+ if (s->cpl_on)
2355+ apply_channel_coupling(s);
2356+
18572357 compute_rematrixing_strategy(s);
18582358
18592359 apply_rematrixing(s);
@@ -1934,7 +2434,7 @@ static av_cold int set_channel_info(AC3EncodeContext *s, int channels, · 74 unmodified lines
19342434 s->lfe_on = !!(ch_layout & AV_CH_LOW_FREQUENCY);
19352435 s->channels = channels;
19362436 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;
19382438 if (s->lfe_on)
19392439 ch_layout -= AV_CH_LOW_FREQUENCY;
19402440
@@ -2033,6 +2533,10 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) · 92 unmodified lines
20332533 s->rematrixing_enabled = s->options.stereo_rematrixing &&
20342534 (s->channel_mode == AC3_CHMODE_STEREO);
20352535
2536+ s->cpl_enabled = s->options.channel_coupling &&
2537+ s->channel_mode >= AC3_CHMODE_STEREO &&
2538+ CONFIG_AC3ENC_FLOAT;
2539+
20362540 return 0;
20372541 }
20382542
@@ -2044,7 +2548,8 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) · 5 unmodified lines
20442548 */
20452549 static av_cold void set_bandwidth(AC3EncodeContext *s)
20462550 {
2047− int ch;
2551+ int blk, ch;
2552+ int av_uninit(cpl_start);
20482553
20492554 if (s->cutoff) {
20502555 /* calculate bandwidth based on user-specified cutoff frequency */
@@ -2057,11 +2562,54 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) · 6 unmodified lines
20572562 }
20582563
20592564 /* set number of coefficients for each channel */
2060− for (ch = 0; ch < s->fbw_channels; ch++) {
2061− s->nb_coefs[ch] = s->bandwidth_code * 3 + 73;
2565+ for (ch = 1; ch <= s->fbw_channels; ch++) {
2566+ s->start_freq[ch] = 0;
2567+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
2568+ s->blocks[blk].end_freq[ch] = s->bandwidth_code * 3 + 73;
2569+ }
2570+ /* LFE channel always has 7 coefs */
2571+ if (s->lfe_on) {
2572+ s->start_freq[s->lfe_channel] = 0;
2573+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
2574+ s->blocks[blk].end_freq[ch] = 7;
2575+ }
2576+
2577+ /* initialize coupling strategy */
2578+ if (s->cpl_enabled) {
2579+ if (s->options.cpl_start >= 0) {
2580+ cpl_start = s->options.cpl_start;
2581+ } else {
2582+ cpl_start = ac3_coupling_start_tab[s->channel_mode-2][s->bit_alloc.sr_code][s->frame_size_code/2];
2583+ if (cpl_start < 0)
2584+ s->cpl_enabled = 0;
2585+ }
2586+ }
2587+ if (s->cpl_enabled) {
2588+ int i, cpl_start_band, cpl_end_band;
2589+ uint8_t *cpl_band_sizes = s->cpl_band_sizes;
2590+
2591+ cpl_end_band = s->bandwidth_code / 4 + 3;
2592+ cpl_start_band = av_clip(cpl_start, 0, FFMIN(cpl_end_band-1, 15));
2593+
2594+ s->num_cpl_subbands = cpl_end_band - cpl_start_band;
2595+
2596+ s->num_cpl_bands = 1;
2597+ *cpl_band_sizes = 12;
2598+ for (i = cpl_start_band + 1; i < cpl_end_band; i++) {
2599+ if (ff_eac3_default_cpl_band_struct[i]) {
2600+ *cpl_band_sizes += 12;
2601+ } else {
2602+ s->num_cpl_bands++;
2603+ cpl_band_sizes++;
2604+ *cpl_band_sizes = 12;
2605+ }
2606+ }
2607+
2608+ s->start_freq[CPL_CH] = cpl_start_band * 12 + 37;
2609+ s->cpl_end_freq = cpl_end_band * 12 + 37;
2610+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
2611+ s->blocks[blk].end_freq[CPL_CH] = s->cpl_end_freq;
20622612 }
2063− if (s->lfe_on)
2064− s->nb_coefs[s->lfe_channel] = 7; /* LFE channel always has 7 coefs */
20652613 }
20662614
20672615
@@ -2069,6 +2617,7 @@ static av_cold int allocate_buffers(AVCodecContext *avctx) · 1 unmodified line
20692617 {
20702618 int blk, ch;
20712619 AC3EncodeContext *s = avctx->priv_data;
2620+ int channels = s->channels + 1; /* includes coupling channel */
20722621
20732622 FF_ALLOC_OR_GOTO(avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples),
20742623 alloc_fail);
@@ -2077,74 +2626,90 @@ static av_cold int allocate_buffers(AVCodecContext *avctx) · 2 unmodified lines
20772626 (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples),
20782627 alloc_fail);
20792628 }
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 *
20812630 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 *
20832632 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 *
20852634 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 *
20872636 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 *
20892638 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 *
20912640 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 *
20932642 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 *
20952644 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 *
20972646 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+ }
20982653 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
20992654 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),
21012656 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),
21032658 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),
21052660 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),
21072662 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),
21092664 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),
21112666 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),
21132668 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),
21152670 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+ }
21162677
2117− for (ch = 0; ch < s->channels; ch++) {
2678+ for (ch = 0; ch < channels; ch++) {
21182679 /* arrangement: block, channel, coeff */
2119− block->bap[ch] = &s->bap_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)];
2120− block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)];
2121− block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * s->channels + ch)];
2122− block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)];
2123− block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * s->channels + ch)];
2124− block->mask[ch] = &s->mask_buffer [64 * (blk * s->channels + ch)];
2125− block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)];
2680+ block->bap[ch] = &s->bap_buffer [AC3_MAX_COEFS * (blk * channels + ch)];
2681+ block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * channels + ch)];
2682+ block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * channels + ch)];
2683+ block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * channels + ch)];
2684+ block->mask[ch] = &s->mask_buffer [64 * (blk * channels + ch)];
2685+ block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * channels + ch)];
2686+ if (s->cpl_enabled) {
2687+ block->cpl_coord_exp[ch] = &s->cpl_coord_exp_buffer [16 * (blk * channels + ch)];
2688+ block->cpl_coord_mant[ch] = &s->cpl_coord_mant_buffer[16 * (blk * channels + ch)];
2689+ }
21262690
21272691 /* arrangement: channel, block, coeff */
21282692 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)];
21292694 }
21302695 }
21312696
21322697 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 *
21342699 AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail);
21352700 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
21362701 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 *
21382703 sizeof(*block->fixed_coef), alloc_fail);
2139− for (ch = 0; ch < s->channels; ch++)
2140− block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)];
2704+ for (ch = 0; ch < channels; ch++)
2705+ block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)];
21412706 }
21422707 } else {
21432708 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
21442709 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 *
21462711 sizeof(*block->fixed_coef), alloc_fail);
2147− for (ch = 0; ch < s->channels; ch++)
2712+ for (ch = 0; ch < channels; ch++)
21482713 block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch];
21492714 }
21502715 }
libavcodec/ac3enc_fixed.c+1−1
@@ -101,7 +101,7 @@ static void scale_coefficients(AC3EncodeContext *s) · 100 unmodified lines
101101
102102 for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
103103 AC3Block *block = &s->blocks[blk];
104− for (ch = 0; ch < s->channels; ch++) {
104+ for (ch = 1; ch <= s->channels; ch++) {
105105 s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
106106 block->coeff_shift[ch]);
107107 }
libavcodec/ac3enc_float.c+4−2
@@ -93,8 +93,10 @@ static int normalize_samples(AC3EncodeContext *s) · 92 unmodified lines
9393 */
9494 static void scale_coefficients(AC3EncodeContext *s)
9595 {
96− s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer, s->mdct_coef_buffer,
97− AC3_MAX_COEFS * AC3_MAX_BLOCKS * s->channels);
96+ int chan_size = AC3_MAX_COEFS * AC3_MAX_BLOCKS;
97+ s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + chan_size,
98+ s->mdct_coef_buffer + chan_size,
99+ chan_size * s->channels);
98100 }
99101
100102
libavcodec/ac3tab.c+7−0
@@ -138,6 +138,13 @@ const uint16_t ff_ac3_bitrate_tab[19] = { · 137 unmodified lines
138138 */
139139 const uint8_t ff_ac3_rematrix_band_tab[5] = { 13, 25, 37, 61, 253 };
140140
141+/**
142+ * Table E2.16 Default Coupling Banding Structure
143+ */
144+const uint8_t ff_eac3_default_cpl_band_struct[18] = {
145+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1
146+};
147+
141148 /* AC-3 MDCT window */
142149
143150 /* 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
3939 extern const uint16_t ff_ac3_sample_rate_tab[3];
4040 extern const uint16_t ff_ac3_bitrate_tab[19];
4141 extern const uint8_t ff_ac3_rematrix_band_tab[5];
42+extern const uint8_t ff_eac3_default_cpl_band_struct[18];
4243 extern const int16_t ff_ac3_window[AC3_WINDOW_SIZE/2];
4344 extern const uint8_t ff_ac3_log_add_tab[260];
4445 extern 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
156156 REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau);
157157 REGISTER_DECODER (MPEG2_CRYSTALHD, mpeg2_crystalhd);
158158 REGISTER_DECODER (MSMPEG4_CRYSTALHD, msmpeg4_crystalhd);
159− REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1);
159+ REGISTER_DECODER (MSMPEG4V1, msmpeg4v1);
160160 REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);
161161 REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);
162162 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
628628 }
629629 }
630630
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−
638631 void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx);
639632 void dsputil_init_arm(DSPContext* c, AVCodecContext *avctx);
640633 void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx);
@@ -652,22 +645,9 @@ void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx); · 11 unmodified lines
652645 void ff_mlp_init(DSPContext* c, AVCodecContext *avctx);
653646 void ff_mlp_init_x86(DSPContext* c, AVCodecContext *avctx);
654647
655−#if HAVE_MMX
656−
657−#undef emms_c
658648
659−static inline void emms(void)
660−{
661− __asm__ volatile ("emms;":::"memory");
662−}
663−
664−#define emms_c() \
665−{\
666− if(av_get_cpu_flags() & AV_CPU_FLAG_MMX)\
667− emms();\
668−}
649+#if ARCH_ARM
669650
670−#elif ARCH_ARM
671651
672652 #if HAVE_NEON
673653 # 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
638638 s->low_delay= s->max_b_frames ? 0 : 1;
639639 avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);
640640 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;
650641 case CODEC_ID_MSMPEG4V2:
651642 s->out_format = FMT_H263;
652643 s->h263_msmpeg4 = 1;
@@ -3807,18 +3798,6 @@ AVCodec ff_h263p_encoder = { · 3154 unmodified lines
38073798 .long_name= NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"),
38083799 };
38093800
3810−AVCodec ff_msmpeg4v1_encoder = {
3811− "msmpeg4v1",
3812− AVMEDIA_TYPE_VIDEO,
3813− CODEC_ID_MSMPEG4V1,
3814− sizeof(MpegEncContext),
3815− MPV_encode_init,
3816− MPV_encode_picture,
3817− MPV_encode_end,
3818− .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
3819− .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
3820−};
3821−
38223801 AVCodec ff_msmpeg4v2_encoder = {
38233802 "msmpeg4v2",
38243803 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
846846 int pred, extquant;
847847 int extrabits = 0;
848848
849− if(s->msmpeg4_version==1){
850− int32_t *dc_val;
851− pred = msmpeg4v1_pred_dc(s, n, &dc_val);
852−
853− /* update predictor */
854− *dc_val= level;
855− }else{
856− int16_t *dc_val;
857− pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
849+ int16_t *dc_val;
850+ pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
858851
859− /* update predictor */
860− if (n < 4) {
861− *dc_val = level * s->y_dc_scale;
862− } else {
863− *dc_val = level * s->c_dc_scale;
864− }
852+ /* update predictor */
853+ if (n < 4) {
854+ *dc_val = level * s->y_dc_scale;
855+ } else {
856+ *dc_val = level * s->c_dc_scale;
865857 }
866858
867859 /* 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
5454 CONFIG_MSMPEG4V3_DECODER || \
5555 CONFIG_WMV2_DECODER || \
5656 CONFIG_VC1_DECODER)
57−#define CONFIG_MSMPEG4_ENCODER (CONFIG_MSMPEG4V1_ENCODER || \
58− CONFIG_MSMPEG4V2_ENCODER || \
57+#define CONFIG_MSMPEG4_ENCODER (CONFIG_MSMPEG4V2_ENCODER || \
5958 CONFIG_MSMPEG4V3_ENCODER || \
6059 CONFIG_WMV2_ENCODER)
6160
libavcodec/tiff.c+13−10
@@ -39,6 +39,8 @@ typedef struct TiffContext { · 38 unmodified lines
3939
4040 int width, height;
4141 unsigned int bpp, bppcount;
42+ uint32_t palette[256];
43+ int palette_is_set;
4244 int le;
4345 enum TiffCompr compr;
4446 int invert;
@@ -255,11 +257,15 @@ static int init_image(TiffContext *s) · 210 unmodified lines
255257 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
256258 return ret;
257259 }
258− if (s->bpp == 8 && s->picture.data[1]){
259− /* make default grayscale pal */
260− pal = (uint32_t *) s->picture.data[1];
261− for (i = 0; i < 256; i++)
262− pal[i] = i * 0x010101;
260+ if (s->avctx->pix_fmt == PIX_FMT_PAL8) {
261+ if (s->palette_is_set) {
262+ memcpy(s->picture.data[1], s->palette, sizeof(s->palette));
263+ } else {
264+ /* make default grayscale pal */
265+ pal = (uint32_t *) s->picture.data[1];
266+ for (i = 0; i < 256; i++)
267+ pal[i] = i * 0x010101;
268+ }
263269 }
264270 return 0;
265271 }
@@ -442,11 +448,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * · 176 unmodified lines
442448 s->fill_order = value - 1;
443449 break;
444450 case TIFF_PAL:
445− if(s->avctx->pix_fmt != PIX_FMT_PAL8){
446− av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n");
447− return -1;
448− }
449− pal = (uint32_t *) s->picture.data[1];
451+ pal = (uint32_t *) s->palette;
450452 off = type_sizes[type];
451453 rp = buf;
452454 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
459461 j |= tget(&bp, type, s->le) >> off;
460462 pal[i] = j;
461463 }
464+ s->palette_is_set = 1;
462465 break;
463466 case TIFF_PLANAR:
464467 if(value == 2){
libavfilter/vf_mp.c+2−7
@@ -287,13 +287,8 @@ zrmjpeg · 286 unmodified lines
287287 CpuCaps gCpuCaps; //FIXME initialize this so optims work
288288
289289
290−//exact copy from vf_scale.c
291290 int get_sws_cpuflags(void){
292− return
293− (gCpuCaps.hasMMX ? SWS_CPU_CAPS_MMX : 0)
294− | (gCpuCaps.hasMMX2 ? SWS_CPU_CAPS_MMX2 : 0)
295− | (gCpuCaps.has3DNow ? SWS_CPU_CAPS_3DNOW : 0)
296− | (gCpuCaps.hasAltiVec ? SWS_CPU_CAPS_ALTIVEC : 0);
291+ return 0;
297292 }
298293
299294 static void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam)
@@ -348,7 +343,7 @@ struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, · 48 unmodified lines
348343 if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = PIX_FMT_PAL8;
349344 sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam);
350345
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);
352347 }
353348
354349 typedef struct {
libavfilter/vsrc_buffer.h+1−0
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 * memory buffer source API for video
2828 */
2929
30+
3031 #include "avfilter.h"
3132
3233 /**
libavformat/ape.c+1−1
@@ -276,7 +276,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) · 275 unmodified lines
276276 ape->frames[0].nblocks = ape->blocksperframe;
277277 ape->frames[0].skip = 0;
278278 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;
280280 ape->frames[i].nblocks = ape->blocksperframe;
281281 ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos;
282282 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
3737 #include "config.h"
3838 #include "attributes.h"
3939 #include "timer.h"
40+#include "cpu.h"
4041
4142 #ifndef attribute_align_arg
4243 #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
@@ -222,4 +223,19 @@ · 179 unmodified lines
222223 # define ONLY_IF_THREADS_ENABLED(x) NULL
223224 #endif
224225
226+#if HAVE_MMX
227+/**
228+ * Empty mmx state.
229+ * this must be called between any dsp function and float/double code.
230+ * for example sin(); dsp->idct_put(); emms_c(); cos()
231+ */
232+static av_always_inline void emms_c(void)
233+{
234+ if(av_get_cpu_flags() & AV_CPU_FLAG_MMX)
235+ __asm__ volatile ("emms" ::: "memory");
236+}
237+#else /* HAVE_MMX */
238+#define emms_c()
239+#endif /* HAVE_MMX */
240+
225241 #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
7979 void ff_bfin_get_unscaled_swscale(SwsContext *c)
8080 {
8181 SwsFunc swScale = c->swScale;
82− if (c->flags & SWS_CPU_CAPS_BFIN)
83− if (c->dstFormat == PIX_FMT_YUV420P)
84− if (c->srcFormat == PIX_FMT_UYVY422) {
85− av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized uyvytoyv12_unscaled\n");
86− c->swScale = uyvytoyv12_unscaled;
87− }
88− if (c->dstFormat == PIX_FMT_YUV420P)
89− if (c->srcFormat == PIX_FMT_YUYV422) {
90− av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized yuyvtoyv12_unscaled\n");
91− c->swScale = yuyvtoyv12_unscaled;
92− }
82+
83+ if (c->dstFormat == PIX_FMT_YUV420P && c->srcFormat == PIX_FMT_UYVY422) {
84+ av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized uyvytoyv12_unscaled\n");
85+ c->swScale = uyvytoyv12_unscaled;
86+ }
87+ if (c->dstFormat == PIX_FMT_YUV420P && c->srcFormat == PIX_FMT_YUYV422) {
88+ av_log (NULL, AV_LOG_VERBOSE, "selecting Blackfin optimized yuyvtoyv12_unscaled\n");
89+ c->swScale = yuyvtoyv12_unscaled;
90+ }
9391 }
libswscale/colorspace-test.c+1−28
@@ -33,31 +33,6 @@ · 32 unmodified lines
3333
3434 #define FUNC(s,d,n) {s,d,#n,n}
3535
36−static int cpu_caps;
37−
38−static char *args_parse(int argc, char *argv[])
39−{
40− int o;
41−
42− while ((o = getopt(argc, argv, "m23")) != -1) {
43− switch (o) {
44− case 'm':
45− cpu_caps |= SWS_CPU_CAPS_MMX;
46− break;
47− case '2':
48− cpu_caps |= SWS_CPU_CAPS_MMX2;
49− break;
50− case '3':
51− cpu_caps |= SWS_CPU_CAPS_3DNOW;
52− break;
53− default:
54− av_log(NULL, AV_LOG_ERROR, "Unknown option %c\n", o);
55− }
56− }
57−
58− return argv[optind];
59−}
60−
6136 int main(int argc, char **argv)
6237 {
6338 int i, funcNum;
@@ -70,9 +45,7 @@ int main(int argc, char **argv) · 6 unmodified lines
7045 return -1;
7146
7247 av_log(NULL, AV_LOG_INFO, "memory corruption test ...\n");
73− args_parse(argc, argv);
74− av_log(NULL, AV_LOG_INFO, "CPU capabilities forced to %x\n", cpu_caps);
75− sws_rgb2rgb_init(cpu_caps);
48+ sws_rgb2rgb_init();
7649
7750 for(funcNum=0; ; funcNum++) {
7851 struct func_info_s {
libswscale/options.c+0−6
@@ -48,12 +48,6 @@ static const AVOption options[] = { · 47 unmodified lines
4848 { "spline", "natural bicubic spline", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_SPLINE }, INT_MIN, INT_MAX, VE, "sws_flags" },
4949 { "print_info", "print info", 0, FF_OPT_TYPE_CONST, {.dbl = SWS_PRINT_INFO }, INT_MIN, INT_MAX, VE, "sws_flags" },
5050 { "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" },
5751 { "full_chroma_int", "full chroma interpolation", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INT }, INT_MIN, INT_MAX, VE, "sws_flags" },
5852 { "full_chroma_inp", "full chroma input", 0 , FF_OPT_TYPE_CONST, {.dbl = SWS_FULL_CHR_H_INP }, INT_MIN, INT_MAX, VE, "sws_flags" },
5953 { "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
2323 #include "swscale_altivec_template.c"
2424 #endif
2525
26+#if COMPILE_TEMPLATE_ALTIVEC
2627 static inline void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
2728 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc,
2829 uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW)
2930 {
30−#if COMPILE_TEMPLATE_ALTIVEC
3131 yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize,
3232 chrFilter, chrSrc, chrFilterSize,
3333 dest, uDest, vDest, dstW, chrDstW);
34−#else //COMPILE_TEMPLATE_ALTIVEC
35− yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize,
36− chrFilter, chrSrc, chrFilterSize,
37− alpSrc, dest, uDest, vDest, aDest, dstW, chrDstW);
38−#endif //!COMPILE_TEMPLATE_ALTIVEC
39−}
40−
41−static inline void RENAME(yuv2nv12X)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
42− const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
43− uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, enum PixelFormat dstFormat)
44−{
45− yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize,
46− chrFilter, chrSrc, chrFilterSize,
47− dest, uDest, dstW, chrDstW, dstFormat);
4834 }
4935
50−static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const int16_t *chrSrc, const int16_t *alpSrc,
51− uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW)
52−{
53− int i;
54− for (i=0; i<dstW; i++) {
55− int val= (lumSrc[i]+64)>>7;
56−
57− if (val&256) {
58− if (val<0) val=0;
59− else val=255;
60− }
61−
62− dest[i]= val;
63− }
64−
65− if (uDest)
66− for (i=0; i<chrDstW; i++) {
67− int u=(chrSrc[i ]+64)>>7;
68− int v=(chrSrc[i + VOFW]+64)>>7;
69−
70− if ((u|v)&256) {
71− if (u<0) u=0;
72− else if (u>255) u=255;
73− if (v<0) v=0;
74− else if (v>255) v=255;
75− }
76−
77− uDest[i]= u;
78− vDest[i]= v;
79− }
80−
81− if (CONFIG_SWSCALE_ALPHA && aDest)
82− for (i=0; i<dstW; i++) {
83− int val= (alpSrc[i]+64)>>7;
84− aDest[i]= av_clip_uint8(val);
85− }
86−}
87−
88−
8936 /**
9037 * vertical scale YV12 to RGB
9138 */
@@ -93,7 +40,6 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 1 unmodified line
9340 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
9441 const int16_t **alpSrc, uint8_t *dest, long dstW, long dstY)
9542 {
96−#if COMPILE_TEMPLATE_ALTIVEC
9743 /* The following list of supported dstFormat values should
9844 match what's found in the body of ff_yuv2packedX_altivec() */
9945 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
10450 chrFilter, chrSrc, chrFilterSize,
10551 dest, dstW, dstY);
10652 else
107−#endif
10853 yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize,
10954 chrFilter, chrSrc, chrFilterSize,
11055 alpSrc, dest, dstW, dstY);
11156 }
57+#endif
11258
113−/**
114− * vertical bilinear scale YV12 to RGB
115− */
116−static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, const uint16_t *buf1, const uint16_t *uvbuf0, const uint16_t *uvbuf1,
117− const uint16_t *abuf0, const uint16_t *abuf1, uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
118−{
119− int yalpha1=4095- yalpha;
120− int uvalpha1=4095-uvalpha;
121− int i;
122−
123− YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C(void,0), YSCALE_YUV_2_GRAY16_2_C, YSCALE_YUV_2_MONO2_C)
124−}
125−
126−/**
127− * YV12 to RGB without scaling or interpolating
128− */
129−static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, const uint16_t *uvbuf0, const uint16_t *uvbuf1,
130− const uint16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, enum PixelFormat dstFormat, int flags, int y)
131−{
132− const int yalpha1=0;
133− int i;
134−
135− const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
136− const int yalpha= 4096; //FIXME ...
137−
138− if (flags&SWS_FULL_CHR_H_INT) {
139− c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y);
140− return;
141− }
142−
143− if (uvalpha < 2048) {
144− YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C, YSCALE_YUV_2_PACKED1_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C)
145− } else {
146− YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C, YSCALE_YUV_2_PACKED1B_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C)
147− }
148−}
149−
150−//FIXME yuy2* can read up to 7 samples too much
151−
152−static inline void RENAME(yuy2ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
153−{
154− int i;
155− for (i=0; i<width; i++)
156− dst[i]= src[2*i];
157−}
158−
159−static inline void RENAME(yuy2ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
160−{
161− int i;
162− for (i=0; i<width; i++) {
163− dstU[i]= src1[4*i + 1];
164− dstV[i]= src1[4*i + 3];
165− }
166− assert(src1 == src2);
167−}
168−
169−static inline void RENAME(LEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
170−{
171− int i;
172− for (i=0; i<width; i++) {
173− dstU[i]= src1[2*i + 1];
174− dstV[i]= src2[2*i + 1];
175− }
176−}
177−
178−/* This is almost identical to the previous, end exists only because
179− * yuy2ToY/UV)(dst, src+1, ...) would have 100% unaligned accesses. */
180−static inline void RENAME(uyvyToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
181−{
182− int i;
183− for (i=0; i<width; i++)
184− dst[i]= src[2*i+1];
185−}
186−
187−static inline void RENAME(uyvyToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
188−{
189− int i;
190− for (i=0; i<width; i++) {
191− dstU[i]= src1[4*i + 0];
192− dstV[i]= src1[4*i + 2];
193− }
194− assert(src1 == src2);
195−}
196−
197−static inline void RENAME(BEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
198−{
199− int i;
200− for (i=0; i<width; i++) {
201− dstU[i]= src1[2*i];
202− dstV[i]= src2[2*i];
203− }
204−}
205−
206−static inline void RENAME(nvXXtoUV)(uint8_t *dst1, uint8_t *dst2,
207− const uint8_t *src, long width)
208−{
209− int i;
210− for (i = 0; i < width; i++) {
211− dst1[i] = src[2*i+0];
212− dst2[i] = src[2*i+1];
213− }
214−}
215−
216−static inline void RENAME(nv12ToUV)(uint8_t *dstU, uint8_t *dstV,
217− const uint8_t *src1, const uint8_t *src2,
218− long width, uint32_t *unused)
219−{
220− RENAME(nvXXtoUV)(dstU, dstV, src1, width);
221−}
222−
223−static inline void RENAME(nv21ToUV)(uint8_t *dstU, uint8_t *dstV,
224− const uint8_t *src1, const uint8_t *src2,
225− long width, uint32_t *unused)
226−{
227− RENAME(nvXXtoUV)(dstV, dstU, src1, width);
228−}
229−
230−
231−static inline void RENAME(bgr24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
232−{
233− int i;
234− for (i=0; i<width; i++) {
235− int b= src[i*3+0];
236− int g= src[i*3+1];
237− int r= src[i*3+2];
238−
239− dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
240− }
241−}
242−
243−static inline void RENAME(bgr24ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
244−{
245− int i;
246− for (i=0; i<width; i++) {
247− int b= src1[3*i + 0];
248− int g= src1[3*i + 1];
249− int r= src1[3*i + 2];
250−
251− dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
252− dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
253− }
254− assert(src1 == src2);
255−}
256−
257−static inline void RENAME(bgr24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
258−{
259− int i;
260− for (i=0; i<width; i++) {
261− int b= src1[6*i + 0] + src1[6*i + 3];
262− int g= src1[6*i + 1] + src1[6*i + 4];
263− int r= src1[6*i + 2] + src1[6*i + 5];
264−
265− dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
266− dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
267− }
268− assert(src1 == src2);
269−}
270−
271−static inline void RENAME(rgb24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
272−{
273− int i;
274− for (i=0; i<width; i++) {
275− int r= src[i*3+0];
276− int g= src[i*3+1];
277− int b= src[i*3+2];
278−
279− dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
280− }
281−}
282−
283−static inline void RENAME(rgb24ToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
284−{
285− int i;
286− assert(src1==src2);
287− for (i=0; i<width; i++) {
288− int r= src1[3*i + 0];
289− int g= src1[3*i + 1];
290− int b= src1[3*i + 2];
291−
292− dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
293− dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
294− }
295−}
296−
297−static inline void RENAME(rgb24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
298−{
299− int i;
300− assert(src1==src2);
301− for (i=0; i<width; i++) {
302− int r= src1[6*i + 0] + src1[6*i + 3];
303− int g= src1[6*i + 1] + src1[6*i + 4];
304− int b= src1[6*i + 2] + src1[6*i + 5];
305−
306− dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
307− dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
308− }
309−}
310−
311−
312−// bilinear / bicubic scaling
313−static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW, int xInc,
314− const int16_t *filter, const int16_t *filterPos, long filterSize)
315−{
316−#if COMPILE_TEMPLATE_ALTIVEC
317− hScale_altivec_real(dst, dstW, src, srcW, xInc, filter, filterPos, filterSize);
318−#else
319− int i;
320− for (i=0; i<dstW; i++) {
321− int j;
322− int srcPos= filterPos[i];
323− int val=0;
324− //printf("filterPos: %d\n", filterPos[i]);
325− for (j=0; j<filterSize; j++) {
326− //printf("filter: %d, src: %d\n", filter[i], src[srcPos + j]);
327− val += ((int)src[srcPos + j])*filter[filterSize*i + j];
328− }
329− //filter += hFilterSize;
330− dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...
331− //dst[i] = val>>7;
332− }
333−#endif /* COMPILE_TEMPLATE_ALTIVEC */
334−}
335−
336−//FIXME all pal and rgb srcFormats could do this convertion as well
337−//FIXME all scalers more complex than bilinear could do half of this transform
338−static void RENAME(chrRangeToJpeg)(uint16_t *dst, int width)
339−{
340− int i;
341− for (i = 0; i < width; i++) {
342− dst[i ] = (FFMIN(dst[i ],30775)*4663 - 9289992)>>12; //-264
343− dst[i+VOFW] = (FFMIN(dst[i+VOFW],30775)*4663 - 9289992)>>12; //-264
344− }
345−}
346−static void RENAME(chrRangeFromJpeg)(uint16_t *dst, int width)
347−{
348− int i;
349− for (i = 0; i < width; i++) {
350− dst[i ] = (dst[i ]*1799 + 4081085)>>11; //1469
351− dst[i+VOFW] = (dst[i+VOFW]*1799 + 4081085)>>11; //1469
352− }
353−}
354−static void RENAME(lumRangeToJpeg)(uint16_t *dst, int width)
355−{
356− int i;
357− for (i = 0; i < width; i++)
358− dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
359−}
360−static void RENAME(lumRangeFromJpeg)(uint16_t *dst, int width)
361−{
362− int i;
363− for (i = 0; i < width; i++)
364− dst[i] = (dst[i]*14071 + 33561947)>>14;
365−}
366−
367−static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst,
368− long dstWidth, const uint8_t *src, int srcW,
369− int xInc)
370−{
371− int i;
372− unsigned int xpos=0;
373− for (i=0;i<dstWidth;i++) {
374− register unsigned int xx=xpos>>16;
375− register unsigned int xalpha=(xpos&0xFFFF)>>9;
376− dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
377− xpos+=xInc;
378− }
379−}
380−
381− // *** horizontal scale Y line to temp buffer
382−static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src, int srcW, int xInc,
383− const int16_t *hLumFilter,
384− const int16_t *hLumFilterPos, int hLumFilterSize,
385− uint8_t *formatConvBuffer,
386− uint32_t *pal, int isAlpha)
387−{
388− void (*toYV12)(uint8_t *, const uint8_t *, long, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
389− void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
390−
391− src += isAlpha ? c->alpSrcOffset : c->lumSrcOffset;
392−
393− if (toYV12) {
394− toYV12(formatConvBuffer, src, srcW, pal);
395− src= formatConvBuffer;
396− }
397−
398− if (c->hScale16) {
399− c->hScale16(dst, dstWidth, (uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1);
400− } else if (!c->hyscale_fast) {
401− c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
402− } else { // fast bilinear upscale / crap downscale
403− c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
404− }
405−
406− if (convertRange)
407− convertRange(dst, dstWidth);
408−}
409−
410−static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst,
411− long dstWidth, const uint8_t *src1,
412− const uint8_t *src2, int srcW, int xInc)
413−{
414− int i;
415− unsigned int xpos=0;
416− for (i=0;i<dstWidth;i++) {
417− register unsigned int xx=xpos>>16;
418− register unsigned int xalpha=(xpos&0xFFFF)>>9;
419− dst[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);
420− dst[i+VOFW]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
421− /* slower
422− dst[i]= (src1[xx]<<7) + (src1[xx+1] - src1[xx])*xalpha;
423− dst[i+VOFW]=(src2[xx]<<7) + (src2[xx+1] - src2[xx])*xalpha;
424− */
425− xpos+=xInc;
426− }
427−}
428−
429−inline static void RENAME(hcscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src1, const uint8_t *src2,
430− int srcW, int xInc, const int16_t *hChrFilter,
431− const int16_t *hChrFilterPos, int hChrFilterSize,
432− uint8_t *formatConvBuffer,
433− uint32_t *pal)
434−{
435−
436− src1 += c->chrSrcOffset;
437− src2 += c->chrSrcOffset;
438−
439− if (c->chrToYV12) {
440− c->chrToYV12(formatConvBuffer, formatConvBuffer+VOFW, src1, src2, srcW, pal);
441− src1= formatConvBuffer;
442− src2= formatConvBuffer+VOFW;
443− }
444−
445− if (c->hScale16) {
446− c->hScale16(dst , dstWidth, (uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1);
447− c->hScale16(dst+VOFW, dstWidth, (uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1);
448− } else if (!c->hcscale_fast) {
449− c->hScale(dst , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
450− c->hScale(dst+VOFW, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
451− } else { // fast bilinear upscale / crap downscale
452− c->hcscale_fast(c, dst, dstWidth, src1, src2, srcW, xInc);
453− }
454−
455− if (c->chrConvertRange)
456− c->chrConvertRange(dst, dstWidth);
457−}
458−
459−#define DEBUG_SWSCALE_BUFFERS 0
460−#define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
461−
462−static int RENAME(swScale)(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
463− int srcSliceH, uint8_t* dst[], int dstStride[])
464−{
465− /* load a few things into local vars to make the code more readable? and faster */
466− const int srcW= c->srcW;
467− const int dstW= c->dstW;
468− const int dstH= c->dstH;
469− const int chrDstW= c->chrDstW;
470− const int chrSrcW= c->chrSrcW;
471− const int lumXInc= c->lumXInc;
472− const int chrXInc= c->chrXInc;
473− const enum PixelFormat dstFormat= c->dstFormat;
474− const int flags= c->flags;
475− int16_t *vLumFilterPos= c->vLumFilterPos;
476− int16_t *vChrFilterPos= c->vChrFilterPos;
477− int16_t *hLumFilterPos= c->hLumFilterPos;
478− int16_t *hChrFilterPos= c->hChrFilterPos;
479− int16_t *vLumFilter= c->vLumFilter;
480− int16_t *vChrFilter= c->vChrFilter;
481− int16_t *hLumFilter= c->hLumFilter;
482− int16_t *hChrFilter= c->hChrFilter;
483− int32_t *lumMmxFilter= c->lumMmxFilter;
484− int32_t *chrMmxFilter= c->chrMmxFilter;
485− int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
486− const int vLumFilterSize= c->vLumFilterSize;
487− const int vChrFilterSize= c->vChrFilterSize;
488− const int hLumFilterSize= c->hLumFilterSize;
489− const int hChrFilterSize= c->hChrFilterSize;
490− int16_t **lumPixBuf= c->lumPixBuf;
491− int16_t **chrPixBuf= c->chrPixBuf;
492− int16_t **alpPixBuf= c->alpPixBuf;
493− const int vLumBufSize= c->vLumBufSize;
494− const int vChrBufSize= c->vChrBufSize;
495− uint8_t *formatConvBuffer= c->formatConvBuffer;
496− const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
497− const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
498− int lastDstY;
499− uint32_t *pal=c->pal_yuv;
500−
501− /* vars which will change and which we need to store back in the context */
502− int dstY= c->dstY;
503− int lumBufIndex= c->lumBufIndex;
504− int chrBufIndex= c->chrBufIndex;
505− int lastInLumBuf= c->lastInLumBuf;
506− int lastInChrBuf= c->lastInChrBuf;
507−
508− if (isPacked(c->srcFormat)) {
509− src[0]=
510− src[1]=
511− src[2]=
512− src[3]= src[0];
513− srcStride[0]=
514− srcStride[1]=
515− srcStride[2]=
516− srcStride[3]= srcStride[0];
517− }
518− srcStride[1]<<= c->vChrDrop;
519− srcStride[2]<<= c->vChrDrop;
520−
521− DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
522− src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
523− dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
524− DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
525− srcSliceY, srcSliceH, dstY, dstH);
526− DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
527− vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
528−
529− if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
530− static int warnedAlready=0; //FIXME move this into the context perhaps
531− if (flags & SWS_PRINT_INFO && !warnedAlready) {
532− av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
533− " ->cannot do aligned memory accesses anymore\n");
534− warnedAlready=1;
535− }
536− }
537−
538− /* Note the user might start scaling the picture in the middle so this
539− will not get executed. This is not really intended but works
540− currently, so people might do it. */
541− if (srcSliceY ==0) {
542− lumBufIndex=-1;
543− chrBufIndex=-1;
544− dstY=0;
545− lastInLumBuf= -1;
546− lastInChrBuf= -1;
547− }
548−
549− lastDstY= dstY;
550−
551− for (;dstY < dstH; dstY++) {
552− unsigned char *dest =dst[0]+dstStride[0]*dstY;
553− const int chrDstY= dstY>>c->chrDstVSubSample;
554− unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
555− unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
556− unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL;
557−
558− const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
559− const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
560− const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
561− int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
562− int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
563− int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
564− int enough_lines;
565−
566− //handle holes (FAST_BILINEAR & weird filters)
567− if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
568− if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
569− assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
570− assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
571−
572− DEBUG_BUFFERS("dstY: %d\n", dstY);
573− DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
574− firstLumSrcY, lastLumSrcY, lastInLumBuf);
575− DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
576− firstChrSrcY, lastChrSrcY, lastInChrBuf);
577−
578− // Do we have enough lines in this slice to output the dstY line
579− enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
580−
581− if (!enough_lines) {
582− lastLumSrcY = srcSliceY + srcSliceH - 1;
583− lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
584− DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
585− lastLumSrcY, lastChrSrcY);
586− }
587−
588− //Do horizontal scaling
589− while(lastInLumBuf < lastLumSrcY) {
590− const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
591− const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
592− lumBufIndex++;
593− assert(lumBufIndex < 2*vLumBufSize);
594− assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
595− assert(lastInLumBuf + 1 - srcSliceY >= 0);
596− RENAME(hyscale)(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
597− hLumFilter, hLumFilterPos, hLumFilterSize,
598− formatConvBuffer,
599− pal, 0);
600− if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
601− RENAME(hyscale)(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW, lumXInc,
602− hLumFilter, hLumFilterPos, hLumFilterSize,
603− formatConvBuffer,
604− pal, 1);
605− lastInLumBuf++;
606− DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
607− lumBufIndex, lastInLumBuf);
608− }
609− while(lastInChrBuf < lastChrSrcY) {
610− const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
611− const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
612− chrBufIndex++;
613− assert(chrBufIndex < 2*vChrBufSize);
614− assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
615− assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
616− //FIXME replace parameters through context struct (some at least)
617−
618− if (c->needs_hcscale)
619− RENAME(hcscale)(c, chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc,
620− hChrFilter, hChrFilterPos, hChrFilterSize,
621− formatConvBuffer,
622− pal);
623− lastInChrBuf++;
624− DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
625− chrBufIndex, lastInChrBuf);
626− }
627− //wrap buf index around to stay inside the ring buffer
628− if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
629− if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
630− if (!enough_lines)
631− break; //we can't output a dstY line so let's try with the next slice
632−
633− if (dstY < dstH-2) {
634− const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
635− const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
636− const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
637− if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
638− const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
639− if (dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi
640− c->yuv2nv12X(c,
641− vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
642− vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
643− dest, uDest, dstW, chrDstW, dstFormat);
644− } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
645− const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
646− if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
647− if (is16BPS(dstFormat) || isNBPS(dstFormat)) {
648− yuv2yuvX16inC(
649− vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
650− vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
651− alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW,
652− dstFormat);
653− } else if (vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
654− const int16_t *lumBuf = lumSrcPtr[0];
655− const int16_t *chrBuf= chrSrcPtr[0];
656− const int16_t *alpBuf= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? alpSrcPtr[0] : NULL;
657− c->yuv2yuv1(c, lumBuf, chrBuf, alpBuf, dest, uDest, vDest, aDest, dstW, chrDstW);
658− } else { //General YV12
659− c->yuv2yuvX(c,
660− vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
661− vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
662− alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
663− }
664− } else {
665− assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
666− assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2);
667− if (vLumFilterSize == 1 && vChrFilterSize == 2) { //unscaled RGB
668− int chrAlpha= vChrFilter[2*dstY+1];
669− if(flags & SWS_FULL_CHR_H_INT) {
670− yuv2rgbXinC_full(c, //FIXME write a packed1_full function
671− vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
672− vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
673− alpSrcPtr, dest, dstW, dstY);
674− } else {
675− c->yuv2packed1(c, *lumSrcPtr, *chrSrcPtr, *(chrSrcPtr+1),
676− alpPixBuf ? *alpSrcPtr : NULL,
677− dest, dstW, chrAlpha, dstFormat, flags, dstY);
678− }
679− } else if (vLumFilterSize == 2 && vChrFilterSize == 2) { //bilinear upscale RGB
680− int lumAlpha= vLumFilter[2*dstY+1];
681− int chrAlpha= vChrFilter[2*dstY+1];
682− lumMmxFilter[2]=
683− lumMmxFilter[3]= vLumFilter[2*dstY ]*0x10001;
684− chrMmxFilter[2]=
685− chrMmxFilter[3]= vChrFilter[2*chrDstY]*0x10001;
686− if(flags & SWS_FULL_CHR_H_INT) {
687− yuv2rgbXinC_full(c, //FIXME write a packed2_full function
688− vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
689− vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
690− alpSrcPtr, dest, dstW, dstY);
691− } else {
692− c->yuv2packed2(c, *lumSrcPtr, *(lumSrcPtr+1), *chrSrcPtr, *(chrSrcPtr+1),
693− alpPixBuf ? *alpSrcPtr : NULL, alpPixBuf ? *(alpSrcPtr+1) : NULL,
694− dest, dstW, lumAlpha, chrAlpha, dstY);
695− }
696− } else { //general RGB
697− if(flags & SWS_FULL_CHR_H_INT) {
698− yuv2rgbXinC_full(c,
699− vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
700− vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
701− alpSrcPtr, dest, dstW, dstY);
702− } else {
703− c->yuv2packedX(c,
704− vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
705− vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
706− alpSrcPtr, dest, dstW, dstY);
707− }
708− }
709− }
710− } else { // hmm looks like we can't use MMX here without overwriting this array's tail
711− const int16_t **lumSrcPtr= (const int16_t **)lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
712− const int16_t **chrSrcPtr= (const int16_t **)chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
713− const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **)alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
714− if (dstFormat == PIX_FMT_NV12 || dstFormat == PIX_FMT_NV21) {
715− const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
716− if (dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi
717− yuv2nv12XinC(
718− vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
719− vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
720− dest, uDest, dstW, chrDstW, dstFormat);
721− } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12
722− const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
723− if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
724− if (is16BPS(dstFormat) || isNBPS(dstFormat)) {
725− yuv2yuvX16inC(
726− vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
727− vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
728− alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW,
729− dstFormat);
730− } else {
731− yuv2yuvXinC(
732− vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
733− vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
734− alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW);
735− }
736− } else {
737− assert(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);
738− assert(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2);
739− if(flags & SWS_FULL_CHR_H_INT) {
740− yuv2rgbXinC_full(c,
741− vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
742− vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
743− alpSrcPtr, dest, dstW, dstY);
744− } else {
745− yuv2packedXinC(c,
746− vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,
747− vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
748− alpSrcPtr, dest, dstW, dstY);
749− }
750− }
751− }
752− }
753−
754− if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
755− fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
756−
757− /* store changed local vars back in the context */
758− c->dstY= dstY;
759− c->lumBufIndex= lumBufIndex;
760− c->chrBufIndex= chrBufIndex;
761− c->lastInLumBuf= lastInLumBuf;
762− c->lastInChrBuf= lastInChrBuf;
763−
764− return dstY - lastDstY;
765−}
76659
76760 static void RENAME(sws_init_swScale)(SwsContext *c)
76861 {
76962 enum PixelFormat srcFormat = c->srcFormat;
77063
771− c->yuv2nv12X = RENAME(yuv2nv12X );
772− c->yuv2yuv1 = RENAME(yuv2yuv1 );
77364 c->yuv2yuvX = RENAME(yuv2yuvX );
774− c->yuv2packed1 = RENAME(yuv2packed1 );
775− c->yuv2packed2 = RENAME(yuv2packed2 );
77665 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;
91866 }
libswscale/ppc/yuv2rgb_altivec.c+2−1
@@ -94,6 +94,7 @@ adjustment. · 93 unmodified lines
9494 #include "libswscale/rgb2rgb.h"
9595 #include "libswscale/swscale.h"
9696 #include "libswscale/swscale_internal.h"
97+#include "libavutil/cpu.h"
9798
9899 #undef PROFILE_THE_BEAST
99100 #undef INC_SCALING
@@ -692,7 +693,7 @@ static int altivec_uyvy_rgb32 (SwsContext *c, · 592 unmodified lines
692693 */
693694 SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c)
694695 {
695− if (!(c->flags & SWS_CPU_CAPS_ALTIVEC))
696+ if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
696697 return NULL;
697698
698699 /*
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
116116 32-bit C version, and and&add trick by Michael Niedermayer
117117 */
118118
119−void sws_rgb2rgb_init(int flags)
119+void sws_rgb2rgb_init(void)
120120 {
121121 rgb2rgb_init_c();
122−#if HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX
123− rgb2rgb_init_x86(flags);
124−#endif /* HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX */
122+ if (HAVE_MMX)
123+ rgb2rgb_init_x86();
125124 }
126125
127126 #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
166166 long width, long height,
167167 long lumStride, long chromStride, long srcStride);
168168
169−void sws_rgb2rgb_init(int flags);
169+void sws_rgb2rgb_init(void);
170170
171−void rgb2rgb_init_x86(int flags);
171+void rgb2rgb_init_x86(void);
172172
173173 #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
278278 }
279279 }
280280
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−
300281 static inline void rgb15to32_c(const uint8_t *src, uint8_t *dst, long src_size)
301282 {
302283 const uint16_t *end;
libswscale/swscale.c+18−131
@@ -63,6 +63,7 @@ untested special converters · 62 unmodified lines
6363 #include "libavutil/avassert.h"
6464 #include "libavutil/intreadwrite.h"
6565 #include "libavutil/x86_cpu.h"
66+#include "libavutil/cpu.h"
6667 #include "libavutil/avutil.h"
6768 #include "libavutil/mathematics.h"
6869 #include "libavutil/bswap.h"
@@ -71,10 +72,6 @@ untested special converters · 2 unmodified lines
7172 #undef MOVNTQ
7273 #undef PAVGB
7374
74−//#undef HAVE_MMX2
75−//#define HAVE_AMD3DNOW
76−//#undef HAVE_MMX
77−//#undef ARCH_X86
7875 #define DITHER1XBPP
7976
8077 #define isPacked(x) ( \
@@ -1262,57 +1259,13 @@ static inline void monoblack2Y(uint8_t *dst, const uint8_t *src, long width, uin · 1181 unmodified lines
12621259
12631260 //Note: we have C, MMX, MMX2, 3DNOW versions, there is no 3DNOW+MMX2 one
12641261 //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
13071262
1308−#define COMPILE_TEMPLATE_MMX 0
13091263 #define COMPILE_TEMPLATE_MMX2 0
1310−#define COMPILE_TEMPLATE_AMD3DNOW 0
13111264 #define COMPILE_TEMPLATE_ALTIVEC 0
13121265
13131266 #include "swscale_template.c"
13141267
1315−#if COMPILE_ALTIVEC
1268+#if HAVE_ALTIVEC
13161269 #undef RENAME
13171270 #undef COMPILE_TEMPLATE_ALTIVEC
13181271 #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
13201273 #include "ppc/swscale_template.c"
13211274 #endif
13221275
1323−#if ARCH_X86
1324−
13251276 //MMX versions
1326−#if COMPILE_MMX
1277+#if HAVE_MMX
13271278 #undef RENAME
1328−#undef COMPILE_TEMPLATE_MMX
13291279 #undef COMPILE_TEMPLATE_MMX2
1330−#undef COMPILE_TEMPLATE_AMD3DNOW
1331−#define COMPILE_TEMPLATE_MMX 1
13321280 #define COMPILE_TEMPLATE_MMX2 0
1333−#define COMPILE_TEMPLATE_AMD3DNOW 0
13341281 #define RENAME(a) a ## _MMX
13351282 #include "x86/swscale_template.c"
13361283 #endif
13371284
13381285 //MMX2 versions
1339−#if COMPILE_MMX2
1286+#if HAVE_MMX2
13401287 #undef RENAME
1341−#undef COMPILE_TEMPLATE_MMX
13421288 #undef COMPILE_TEMPLATE_MMX2
1343−#undef COMPILE_TEMPLATE_AMD3DNOW
1344−#define COMPILE_TEMPLATE_MMX 1
13451289 #define COMPILE_TEMPLATE_MMX2 1
1346−#define COMPILE_TEMPLATE_AMD3DNOW 0
13471290 #define RENAME(a) a ## _MMX2
13481291 #include "x86/swscale_template.c"
13491292 #endif
13501293
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−
13661294 SwsFunc ff_getSwsFunc(SwsContext *c)
13671295 {
1296+ int cpu_flags = av_get_cpu_flags();
1297+
13681298 sws_init_swScale_c(c);
13691299
1370−#if CONFIG_RUNTIME_CPUDETECT
1371−#if ARCH_X86
1372− // ordered per speed fastest first
1373− if (c->flags & SWS_CPU_CAPS_MMX2) {
1374− sws_init_swScale_MMX2(c);
1375− return swScale_MMX2;
1376− } else if (c->flags & SWS_CPU_CAPS_3DNOW) {
1377− sws_init_swScale_3DNow(c);
1378− return swScale_3DNow;
1379− } else if (c->flags & SWS_CPU_CAPS_MMX) {
1300+#if HAVE_MMX
1301+ if (cpu_flags & AV_CPU_FLAG_MMX)
13801302 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− }
13901303 #endif
1391−#endif /* ARCH_X86 */
1392−#else //CONFIG_RUNTIME_CPUDETECT
1393−#if COMPILE_TEMPLATE_MMX2
1394− sws_init_swScale_MMX2(c);
1395− return swScale_MMX2;
1396−#elif COMPILE_TEMPLATE_AMD3DNOW
1397− sws_init_swScale_3DNow(c);
1398− return swScale_3DNow;
1399−#elif COMPILE_TEMPLATE_MMX
1400− sws_init_swScale_MMX(c);
1401− return swScale_MMX;
1402−#elif COMPILE_TEMPLATE_ALTIVEC
1403− sws_init_swScale_altivec(c);
1404− return swScale_altivec;
1304+#if HAVE_MMX2
1305+ if (cpu_flags & AV_CPU_FLAG_MMX2)
1306+ sws_init_swScale_MMX2(c);
1307+#endif
1308+#if HAVE_ALTIVEC
1309+ if (cpu_flags & AV_CPU_FLAG_ALTIVEC)
1310+ sws_init_swScale_altivec(c);
14051311 #endif
1406−#endif //!CONFIG_RUNTIME_CPUDETECT
14071312
14081313 return swScale_c;
14091314 }
@@ -1900,23 +1805,6 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t* src[], int srcStride[ · 490 unmodified lines
19001805 return srcSliceH;
19011806 }
19021807
1903−int ff_hardcodedcpuflags(void)
1904−{
1905− int flags = 0;
1906−#if COMPILE_TEMPLATE_MMX2
1907− flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2;
1908−#elif COMPILE_TEMPLATE_AMD3DNOW
1909− flags |= SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_3DNOW;
1910−#elif COMPILE_TEMPLATE_MMX
1911− flags |= SWS_CPU_CAPS_MMX;
1912−#elif COMPILE_TEMPLATE_ALTIVEC
1913− flags |= SWS_CPU_CAPS_ALTIVEC;
1914−#elif ARCH_BFIN
1915− flags |= SWS_CPU_CAPS_BFIN;
1916−#endif
1917− return flags;
1918−}
1919−
19201808 void ff_get_unscaled_swscale(SwsContext *c)
19211809 {
19221810 const enum PixelFormat srcFormat = c->srcFormat;
@@ -2000,8 +1888,8 @@ void ff_get_unscaled_swscale(SwsContext *c) · 77 unmodified lines
20001888 if(srcFormat == PIX_FMT_UYVY422 && dstFormat == PIX_FMT_YUV422P)
20011889 c->swScale= uyvyToYuv422Wrapper;
20021890
2003−#if COMPILE_ALTIVEC
2004− if ((c->flags & SWS_CPU_CAPS_ALTIVEC) &&
1891+#if HAVE_ALTIVEC
1892+ if ((av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) &&
20051893 !(c->flags & SWS_BITEXACT) &&
20061894 srcFormat == PIX_FMT_YUV420P) {
20071895 // unscaled YV12 -> packed YUV, we want speed
@@ -2031,8 +1919,7 @@ void ff_get_unscaled_swscale(SwsContext *c) · 23 unmodified lines
20311919 c->swScale= planarCopyWrapper;
20321920 }
20331921 #if ARCH_BFIN
2034− if (flags & SWS_CPU_CAPS_BFIN)
2035− ff_bfin_get_unscaled_swscale (c);
1922+ ff_bfin_get_unscaled_swscale (c);
20361923 #endif
20371924 }
20381925
libswscale/swscale.h+0−7
@@ -95,13 +95,6 @@ const char *swscale_license(void); · 94 unmodified lines
9595 #define SWS_ACCURATE_RND 0x40000
9696 #define SWS_BITEXACT 0x80000
9797
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−
10598 #define SWS_MAX_REDUCE_CUTOFF 0.002
10699
107100 #define SWS_CS_ITU709 1
libswscale/swscale_internal.h+0−5
@@ -481,11 +481,6 @@ extern const AVClass sws_context_class; · 480 unmodified lines
481481 */
482482 void ff_get_unscaled_swscale(SwsContext *c);
483483
484−/**
485− * Returns the SWS_CPU_CAPS for the optimized code compiled into swscale.
486− */
487−int ff_hardcodedcpuflags(void);
488−
489484 /**
490485 * Returns function pointer to fastest main scaler path function depending
491486 * 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
363363 }
364364 }
365365
366−static inline void RENAME(hScale16)(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
366+static inline void hScale16_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
367367 const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
368368 {
369369 int i, j;
370−#if COMPILE_TEMPLATE_MMX
371− assert(filterSize % 4 == 0 && filterSize>0);
372− if (filterSize==4 && shift<15) { // Always true for upscaling, sometimes for down, too.
373− x86_reg counter= -2*dstW;
374− filter-= counter*2;
375− filterPos-= counter/2;
376− dst-= counter/2;
377− __asm__ volatile(
378− "movd %5, %%mm7 \n\t"
379−#if defined(PIC)
380− "push %%"REG_b" \n\t"
381−#endif
382− "push %%"REG_BP" \n\t" // we use 7 regs here ...
383− "mov %%"REG_a", %%"REG_BP" \n\t"
384− ".p2align 4 \n\t"
385− "1: \n\t"
386− "movzwl (%2, %%"REG_BP"), %%eax \n\t"
387− "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t"
388− "movq (%1, %%"REG_BP", 4), %%mm1 \n\t"
389− "movq 8(%1, %%"REG_BP", 4), %%mm3 \n\t"
390− "movq (%3, %%"REG_a", 2), %%mm0 \n\t"
391− "movq (%3, %%"REG_b", 2), %%mm2 \n\t"
392− "pmaddwd %%mm1, %%mm0 \n\t"
393− "pmaddwd %%mm2, %%mm3 \n\t"
394− "movq %%mm0, %%mm4 \n\t"
395− "punpckldq %%mm3, %%mm0 \n\t"
396− "punpckhdq %%mm3, %%mm4 \n\t"
397− "paddd %%mm4, %%mm0 \n\t"
398− "psrad %%mm7, %%mm0 \n\t"
399− "packssdw %%mm0, %%mm0 \n\t"
400− "movd %%mm0, (%4, %%"REG_BP") \n\t"
401− "add $4, %%"REG_BP" \n\t"
402− " jnc 1b \n\t"
403−
404− "pop %%"REG_BP" \n\t"
405−#if defined(PIC)
406− "pop %%"REG_b" \n\t"
407−#endif
408− : "+a" (counter)
409− : "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift)
410−#if !defined(PIC)
411− : "%"REG_b
412−#endif
413− );
414− } else if (filterSize==8 && shift<15) {
415− x86_reg counter= -2*dstW;
416− filter-= counter*4;
417− filterPos-= counter/2;
418− dst-= counter/2;
419− __asm__ volatile(
420− "movd %5, %%mm7 \n\t"
421−#if defined(PIC)
422− "push %%"REG_b" \n\t"
423−#endif
424− "push %%"REG_BP" \n\t" // we use 7 regs here ...
425− "mov %%"REG_a", %%"REG_BP" \n\t"
426− ".p2align 4 \n\t"
427− "1: \n\t"
428− "movzwl (%2, %%"REG_BP"), %%eax \n\t"
429− "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t"
430− "movq (%1, %%"REG_BP", 8), %%mm1 \n\t"
431− "movq 16(%1, %%"REG_BP", 8), %%mm3 \n\t"
432− "movq (%3, %%"REG_a", 2), %%mm0 \n\t"
433− "movq (%3, %%"REG_b", 2), %%mm2 \n\t"
434− "pmaddwd %%mm1, %%mm0 \n\t"
435− "pmaddwd %%mm2, %%mm3 \n\t"
436−
437− "movq 8(%1, %%"REG_BP", 8), %%mm1 \n\t"
438− "movq 24(%1, %%"REG_BP", 8), %%mm5 \n\t"
439− "movq 8(%3, %%"REG_a", 2), %%mm4 \n\t"
440− "movq 8(%3, %%"REG_b", 2), %%mm2 \n\t"
441− "pmaddwd %%mm1, %%mm4 \n\t"
442− "pmaddwd %%mm2, %%mm5 \n\t"
443− "paddd %%mm4, %%mm0 \n\t"
444− "paddd %%mm5, %%mm3 \n\t"
445− "movq %%mm0, %%mm4 \n\t"
446− "punpckldq %%mm3, %%mm0 \n\t"
447− "punpckhdq %%mm3, %%mm4 \n\t"
448− "paddd %%mm4, %%mm0 \n\t"
449− "psrad %%mm7, %%mm0 \n\t"
450− "packssdw %%mm0, %%mm0 \n\t"
451− "movd %%mm0, (%4, %%"REG_BP") \n\t"
452− "add $4, %%"REG_BP" \n\t"
453− " jnc 1b \n\t"
454−
455− "pop %%"REG_BP" \n\t"
456−#if defined(PIC)
457− "pop %%"REG_b" \n\t"
458−#endif
459− : "+a" (counter)
460− : "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift)
461−#if !defined(PIC)
462− : "%"REG_b
463−#endif
464− );
465− } else if (shift<15){
466− const uint16_t *offset = src+filterSize;
467− x86_reg counter= -2*dstW;
468− //filter-= counter*filterSize/2;
469− filterPos-= counter/2;
470− dst-= counter/2;
471− __asm__ volatile(
472− "movd %7, %%mm7 \n\t"
473− ".p2align 4 \n\t"
474− "1: \n\t"
475− "mov %2, %%"REG_c" \n\t"
476− "movzwl (%%"REG_c", %0), %%eax \n\t"
477− "movzwl 2(%%"REG_c", %0), %%edx \n\t"
478− "mov %5, %%"REG_c" \n\t"
479− "pxor %%mm4, %%mm4 \n\t"
480− "pxor %%mm5, %%mm5 \n\t"
481− "2: \n\t"
482− "movq (%1), %%mm1 \n\t"
483− "movq (%1, %6), %%mm3 \n\t"
484− "movq (%%"REG_c", %%"REG_a", 2), %%mm0 \n\t"
485− "movq (%%"REG_c", %%"REG_d", 2), %%mm2 \n\t"
486− "pmaddwd %%mm1, %%mm0 \n\t"
487− "pmaddwd %%mm2, %%mm3 \n\t"
488− "paddd %%mm3, %%mm5 \n\t"
489− "paddd %%mm0, %%mm4 \n\t"
490− "add $8, %1 \n\t"
491− "add $8, %%"REG_c" \n\t"
492− "cmp %4, %%"REG_c" \n\t"
493− " jb 2b \n\t"
494− "add %6, %1 \n\t"
495− "movq %%mm4, %%mm0 \n\t"
496− "punpckldq %%mm5, %%mm4 \n\t"
497− "punpckhdq %%mm5, %%mm0 \n\t"
498− "paddd %%mm0, %%mm4 \n\t"
499− "psrad %%mm7, %%mm4 \n\t"
500− "packssdw %%mm4, %%mm4 \n\t"
501− "mov %3, %%"REG_a" \n\t"
502− "movd %%mm4, (%%"REG_a", %0) \n\t"
503− "add $4, %0 \n\t"
504− " jnc 1b \n\t"
505−
506− : "+r" (counter), "+r" (filter)
507− : "m" (filterPos), "m" (dst), "m"(offset),
508− "m" (src), "r" ((x86_reg)filterSize*2), "m"(shift)
509− : "%"REG_a, "%"REG_c, "%"REG_d
510− );
511− } else
512−#endif
370+
513371 for (i=0; i<dstW; i++) {
514372 int srcPos= filterPos[i];
515373 int val=0;
@@ -520,7 +378,7 @@ static inline void RENAME(hScale16)(int16_t *dst, int dstW, const uint16_t *src, · 4 unmodified lines
520378 }
521379 }
522380
523−static inline void RENAME(hScale16X)(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
381+static inline void hScale16X_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
524382 const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
525383 {
526384 int i, j;
@@ -660,6 +518,11 @@ inline static void hcscale_c(SwsContext *c, uint16_t *dst, long dstWidth, · 133 unmodified lines
660518 #define DEBUG_SWSCALE_BUFFERS 0
661519 #define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
662520
521+#if HAVE_MMX
522+static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex,
523+ int lastInLumBuf, int lastInChrBuf);
524+#endif
525+
663526 static int swScale_c(SwsContext *c, const uint8_t* src[], int srcStride[],
664527 int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[])
665528 {
@@ -831,6 +694,9 @@ static int swScale_c(SwsContext *c, const uint8_t* src[], int srcStride[], · 165 unmodified lines
831694 if (!enough_lines)
832695 break; //we can't output a dstY line so let's try with the next slice
833696
697+#if HAVE_MMX
698+ updateMMXDitherTables(c, dstY, lumBufIndex, chrBufIndex, lastInLumBuf, lastInChrBuf);
699+#endif
834700 if (dstY < dstH-2) {
835701 const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
836702 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
955821 if ((dstFormat == PIX_FMT_YUVA420P) && !alpPixBuf)
956822 fillPlane(dst[3], dstStride[3], dstW, dstY-lastDstY, lastDstY, 255);
957823
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+
958830 /* store changed local vars back in the context */
959831 c->dstY= dstY;
960832 c->lumBufIndex= lumBufIndex;
@@ -1001,14 +873,14 @@ static void sws_init_swScale_c(SwsContext *c) · 40 unmodified lines
1001873 case PIX_FMT_YUV420P10BE:
1002874 case PIX_FMT_YUV420P16BE:
1003875 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;
1005877 case PIX_FMT_GRAY16LE :
1006878 case PIX_FMT_YUV420P9LE:
1007879 case PIX_FMT_YUV422P10LE:
1008880 case PIX_FMT_YUV420P10LE:
1009881 case PIX_FMT_YUV420P16LE:
1010882 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;
1012884 }
1013885 if (c->chrSrcHSubSample) {
1014886 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
185185 }
186186
187187 static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc,
188− int srcW, int dstW, int filterAlign, int one, int flags,
188+ int srcW, int dstW, int filterAlign, int one, int flags, int cpu_flags,
189189 SwsVector *srcFilter, SwsVector *dstFilter, double param[2])
190190 {
191191 int i;
@@ -196,10 +196,8 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi · 4 unmodified lines
196196 int64_t *filter2=NULL;
197197 const int64_t fone= 1LL<<54;
198198 int ret= -1;
199−#if ARCH_X86
200− if (flags & SWS_CPU_CAPS_MMX)
201− __asm__ volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions)
202−#endif
199+
200+ emms_c(); //FIXME this should not be required but it IS (even for non-MMX versions)
203201
204202 // NOTE: the +1 is for the MMX scaler which reads over the end
205203 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
416414 if (min>minFilterSize) minFilterSize= min;
417415 }
418416
419− if (flags & SWS_CPU_CAPS_ALTIVEC) {
417+ if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) {
420418 // we can handle the special case 4,
421419 // so we don't want to go to the full 8
422420 if (minFilterSize < 5)
@@ -431,7 +429,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi · 8 unmodified lines
431429 filterAlign = 1;
432430 }
433431
434− if (flags & SWS_CPU_CAPS_MMX) {
432+ if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
435433 // special case for unscaled vertical filtering
436434 if (minFilterSize == 1 && filterAlign == 2)
437435 filterAlign= 1;
@@ -521,7 +519,7 @@ fail: · 83 unmodified lines
521519 return ret;
522520 }
523521
524−#if ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT)
522+#if HAVE_MMX2
525523 static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *filter, int32_t *filterPos, int numSplits)
526524 {
527525 uint8_t *fragmentA;
@@ -679,7 +677,7 @@ static int initMMX2HScaler(int dstW, int xInc, uint8_t *filterCode, int16_t *fil · 151 unmodified lines
679677
680678 return fragmentPos + 1;
681679 }
682−#endif /* ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) */
680+#endif /* HAVE_MMX2 */
683681
684682 static void getSubSampleFactors(int *h, int *v, enum PixelFormat format)
685683 {
@@ -687,8 +685,6 @@ static void getSubSampleFactors(int *h, int *v, enum PixelFormat format) · 1 unmodified line
687685 *v = av_pix_fmt_descriptors[format].log2_chroma_h;
688686 }
689687
690−static int update_flags_cpu(int flags);
691−
692688 int sws_setColorspaceDetails(SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation)
693689 {
694690 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
703699
704700 c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->dstFormat]);
705701 c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[c->srcFormat]);
706− c->flags = update_flags_cpu(c->flags);
707702
708703 ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation);
709704 //FIXME factorize
710705
711−#if HAVE_ALTIVEC
712− if (c->flags & SWS_CPU_CAPS_ALTIVEC)
706+ if (HAVE_ALTIVEC && av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)
713707 ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness, contrast, saturation);
714−#endif
715708 return 0;
716709 }
717710
@@ -741,27 +734,6 @@ static int handle_jpeg(enum PixelFormat *format) · 23 unmodified lines
741734 }
742735 }
743736
744−static int update_flags_cpu(int flags)
745−{
746−#if !CONFIG_RUNTIME_CPUDETECT //ensure that the flags match the compiled variant if cpudetect is off
747− flags &= ~( SWS_CPU_CAPS_MMX
748− |SWS_CPU_CAPS_MMX2
749− |SWS_CPU_CAPS_3DNOW
750− |SWS_CPU_CAPS_SSE2
751− |SWS_CPU_CAPS_ALTIVEC
752− |SWS_CPU_CAPS_BFIN);
753− flags |= ff_hardcodedcpuflags();
754−#else /* !CONFIG_RUNTIME_CPUDETECT */
755− int cpuflags = av_get_cpu_flags();
756−
757− flags |= (cpuflags & AV_CPU_FLAG_SSE2 ? SWS_CPU_CAPS_SSE2 : 0);
758− flags |= (cpuflags & AV_CPU_FLAG_MMX ? SWS_CPU_CAPS_MMX : 0);
759− flags |= (cpuflags & AV_CPU_FLAG_MMX2 ? SWS_CPU_CAPS_MMX2 : 0);
760− flags |= (cpuflags & AV_CPU_FLAG_3DNOW ? SWS_CPU_CAPS_3DNOW : 0);
761−#endif /* CONFIG_RUNTIME_CPUDETECT */
762− return flags;
763−}
764−
765737 SwsContext *sws_alloc_context(void)
766738 {
767739 SwsContext *c= av_mallocz(sizeof(SwsContext));
@@ -782,16 +754,14 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 14 unmodified lines
782754 int srcH= c->srcH;
783755 int dstW= c->dstW;
784756 int dstH= c->dstH;
785− int flags;
757+ int flags, cpu_flags;
786758 enum PixelFormat srcFormat= c->srcFormat;
787759 enum PixelFormat dstFormat= c->dstFormat;
788760
789− flags= c->flags = update_flags_cpu(c->flags);
790−#if ARCH_X86
791− if (flags & SWS_CPU_CAPS_MMX)
792− __asm__ volatile("emms\n\t"::: "memory");
793−#endif
794− if (!rgb15to16) sws_rgb2rgb_init(flags);
761+ cpu_flags = av_get_cpu_flags();
762+ flags = c->flags;
763+ emms_c();
764+ if (!rgb15to16) sws_rgb2rgb_init();
795765
796766 unscaled = (srcW == dstW && srcH == dstH);
797767
@@ -884,7 +854,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 86 unmodified lines
884854 }
885855 }
886856
887− if (flags & SWS_CPU_CAPS_MMX2) {
857+ if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) {
888858 c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
889859 if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR)) {
890860 if (flags&SWS_PRINT_INFO)
@@ -910,7 +880,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 19 unmodified lines
910880 c->chrXInc+= 20;
911881 }
912882 //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) {
914884 c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;
915885 c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;
916886 }
@@ -918,7 +888,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 1 unmodified line
918888
919889 /* precalculate horizontal scaler filter coefficients */
920890 {
921−#if ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT)
891+#if HAVE_MMX2
922892 // can't downscale !!!
923893 if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR)) {
924894 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
954924 mprotect(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, PROT_EXEC | PROT_READ);
955925 #endif
956926 } else
957−#endif /* ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) */
927+#endif /* HAVE_MMX2 */
958928 {
959929 const int filterAlign=
960− (flags & SWS_CPU_CAPS_MMX) ? 4 :
961− (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 :
930+ (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 4 :
931+ (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
962932 1;
963933
964934 if (initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc,
965935 srcW , dstW, filterAlign, 1<<14,
966− (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags,
936+ (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, cpu_flags,
967937 srcFilter->lumH, dstFilter->lumH, c->param) < 0)
968938 goto fail;
969939 if (initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc,
970940 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,
972942 srcFilter->chrH, dstFilter->chrH, c->param) < 0)
973943 goto fail;
974944 }
@@ -977,18 +947,18 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 2 unmodified lines
977947 /* precalculate vertical scaler filter coefficients */
978948 {
979949 const int filterAlign=
980− (flags & SWS_CPU_CAPS_MMX) && (flags & SWS_ACCURATE_RND) ? 2 :
981− (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 :
950+ (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) && (flags & SWS_ACCURATE_RND) ? 2 :
951+ (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
982952 1;
983953
984954 if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc,
985955 srcH , dstH, filterAlign, (1<<12),
986− (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags,
956+ (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, cpu_flags,
987957 srcFilter->lumV, dstFilter->lumV, c->param) < 0)
988958 goto fail;
989959 if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc,
990960 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,
992962 srcFilter->chrV, dstFilter->chrV, c->param) < 0)
993963 goto fail;
994964
@@ -1082,13 +1052,13 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 87 unmodified lines
10821052 #endif
10831053 sws_format_name(dstFormat));
10841054
1085− if (flags & SWS_CPU_CAPS_MMX2) av_log(c, AV_LOG_INFO, "using MMX2\n");
1086− else if (flags & SWS_CPU_CAPS_3DNOW) av_log(c, AV_LOG_INFO, "using 3DNOW\n");
1087− else if (flags & SWS_CPU_CAPS_MMX) av_log(c, AV_LOG_INFO, "using MMX\n");
1088− else if (flags & SWS_CPU_CAPS_ALTIVEC) av_log(c, AV_LOG_INFO, "using AltiVec\n");
1055+ if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2) av_log(c, AV_LOG_INFO, "using MMX2\n");
1056+ else if (HAVE_AMD3DNOW && cpu_flags & AV_CPU_FLAG_3DNOW) av_log(c, AV_LOG_INFO, "using 3DNOW\n");
1057+ else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) av_log(c, AV_LOG_INFO, "using MMX\n");
1058+ else if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) av_log(c, AV_LOG_INFO, "using AltiVec\n");
10891059 else av_log(c, AV_LOG_INFO, "using C\n");
10901060
1091− if (flags & SWS_CPU_CAPS_MMX) {
1061+ if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
10921062 if (c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR))
10931063 av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR MMX2 scaler for horizontal scaling\n");
10941064 else {
@@ -1107,7 +1077,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 12 unmodified lines
11071077 av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal chrominance scaling\n");
11081078 }
11091079 } else {
1110−#if ARCH_X86
1080+#if HAVE_MMX
11111081 av_log(c, AV_LOG_VERBOSE, "using x86 asm scaler for horizontal scaling\n");
11121082 #else
11131083 if (flags & SWS_FAST_BILINEAR)
@@ -1118,31 +1088,41 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) · 4 unmodified lines
11181088 }
11191089 if (isPlanarYUV(dstFormat)) {
11201090 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");
11221093 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");
11241096 } else {
11251097 if (c->vLumFilterSize==1 && c->vChrFilterSize==2)
11261098 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");
11281101 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");
11301104 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");
11321107 }
11331108
11341109 if (dstFormat==PIX_FMT_BGR24)
11351110 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"));
11371113 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");
11391116 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");
11411119 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");
11431122 else if (dstFormat == PIX_FMT_RGB444BE || dstFormat == PIX_FMT_RGB444LE ||
11441123 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");
11461126
11471127 av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
11481128 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
15271507 av_freep(&c->hLumFilterPos);
15281508 av_freep(&c->hChrFilterPos);
15291509
1530−#if ARCH_X86
1510+#if HAVE_MMX
15311511 #ifdef MAP_ANONYMOUS
15321512 if (c->lumMmx2FilterCode) munmap(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize);
15331513 if (c->chrMmx2FilterCode) munmap(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize);
@@ -1540,7 +1520,7 @@ void sws_freeContext(SwsContext *c) · 6 unmodified lines
15401520 #endif
15411521 c->lumMmx2FilterCode=NULL;
15421522 c->chrMmx2FilterCode=NULL;
1543−#endif /* ARCH_X86 */
1523+#endif /* HAVE_MMX */
15441524
15451525 av_freep(&c->yuvTable);
15461526
@@ -1557,8 +1537,6 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context, · 10 unmodified lines
15571537 if (!param)
15581538 param = default_param;
15591539
1560− flags = update_flags_cpu(flags);
1561−
15621540 if (context &&
15631541 (context->srcW != srcW ||
15641542 context->srcH != srcH ||
libswscale/x86/rgb2rgb.c+11−10
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727
2828 #include "config.h"
2929 #include "libavutil/x86_cpu.h"
30+#include "libavutil/cpu.h"
3031 #include "libavutil/bswap.h"
3132 #include "libswscale/rgb2rgb.h"
3233 #include "libswscale/swscale.h"
@@ -122,16 +123,16 @@ DECLARE_ASM_CONST(8, uint64_t, blue_15mask) = 0x0000001f0000001fULL; · 89 unmodified lines
122123 32-bit C version, and and&add trick by Michael Niedermayer
123124 */
124125
125−void rgb2rgb_init_x86(int flags)
126+void rgb2rgb_init_x86(void)
126127 {
127−#if HAVE_MMX2 || HAVE_AMD3DNOW || HAVE_MMX
128− if (flags & SWS_CPU_CAPS_SSE2)
129− rgb2rgb_init_SSE2();
130− else if (flags & SWS_CPU_CAPS_MMX2)
131− rgb2rgb_init_MMX2();
132− else if (flags & SWS_CPU_CAPS_3DNOW)
133− rgb2rgb_init_3DNOW();
134− else if (flags & SWS_CPU_CAPS_MMX)
128+ int cpu_flags = av_get_cpu_flags();
129+
130+ if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX)
135131 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();
137138 }
libswscale/x86/swscale_template.c+204−678
@@ -22,23 +22,14 @@ · 21 unmodified lines
2222
2323 #undef REAL_MOVNTQ
2424 #undef MOVNTQ
25−#undef PAVGB
2625 #undef PREFETCH
2726
28−#if COMPILE_TEMPLATE_AMD3DNOW
29−#define PREFETCH "prefetch"
30−#elif COMPILE_TEMPLATE_MMX2
27+#if COMPILE_TEMPLATE_MMX2
3128 #define PREFETCH "prefetchnta"
3229 #else
3330 #define PREFETCH " # nop"
3431 #endif
3532
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−
4233 #if COMPILE_TEMPLATE_MMX2
4334 #define REAL_MOVNTQ(a,b) "movntq " #a ", " #b " \n\t"
4435 #else
@@ -709,62 +700,6 @@ · 664 unmodified lines
709700 " jb 1b \n\t"
710701 #define WRITERGB15(dst, dstw, index) REAL_WRITERGB15(dst, dstw, index)
711702
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−
768703 #define WRITEBGR24MMX(dst, dstw, index) \
769704 /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\
770705 "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
896831 const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize, const int16_t **alpSrc,
897832 uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW)
898833 {
899− if(!(c->flags & SWS_BITEXACT)) {
900834 if (c->flags & SWS_ACCURATE_RND) {
901835 if (uDest) {
902836 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
918852
919853 YSCALEYUV2YV12X("0", LUM_MMX_FILTER_OFFSET, dest, dstW)
920854 }
921− return;
922− }
923− yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize,
924− chrFilter, chrSrc, chrFilterSize,
925− alpSrc, dest, uDest, vDest, aDest, dstW, chrDstW);
926−}
927−
928−static inline void RENAME(yuv2nv12X)(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
929− const int16_t *chrFilter, const int16_t **chrSrc, int chrFilterSize,
930− uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, enum PixelFormat dstFormat)
931−{
932− yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize,
933− chrFilter, chrSrc, chrFilterSize,
934− dest, uDest, dstW, chrDstW, dstFormat);
935855 }
936856
937857 static inline void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const int16_t *chrSrc, const int16_t *alpSrc,
938858 uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, long dstW, long chrDstW)
939859 {
940− int i;
941− if(!(c->flags & SWS_BITEXACT)) {
942860 long p= 4;
943861 const int16_t *src[4]= {alpSrc + dstW, lumSrc + dstW, chrSrc + chrDstW, chrSrc + VOFW + chrDstW};
944862 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
967885 }
968886 }
969887 }
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− }
1004888 }
1005889
1006890
@@ -1013,7 +897,7 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 6 unmodified lines
1013897 {
1014898 x86_reg dummy=0;
1015899 x86_reg dstW_reg = dstW;
1016− if(!(c->flags & SWS_BITEXACT)) {
900+
1017901 if (c->flags & SWS_ACCURATE_RND) {
1018902 switch(c->dstFormat) {
1019903 case PIX_FMT_RGB32:
@@ -1170,7 +1054,7 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 150 unmodified lines
11701054 return;
11711055 }
11721056 }
1173− }
1057+
11741058 yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize,
11751059 chrFilter, chrSrc, chrFilterSize,
11761060 alpSrc, dest, dstW, dstY);
@@ -1182,11 +1066,6 @@ static inline void RENAME(yuv2packedX)(SwsContext *c, const int16_t *lumFilter, · 5 unmodified lines
11821066 static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, const uint16_t *buf1, const uint16_t *uvbuf0, const uint16_t *uvbuf1,
11831067 const uint16_t *abuf0, const uint16_t *abuf1, uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)
11841068 {
1185− int yalpha1=4095- yalpha;
1186− int uvalpha1=4095-uvalpha;
1187− int i;
1188−
1189− if(!(c->flags & SWS_BITEXACT)) {
11901069 switch(c->dstFormat) {
11911070 //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(
11921071 case PIX_FMT_RGB32:
@@ -1317,10 +1196,10 @@ static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, cons · 124 unmodified lines
13171196 "a" (&c->redDither)
13181197 );
13191198 return;
1320− default: break;
13211199 }
1322− }
1323− YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C(void,0), YSCALE_YUV_2_GRAY16_2_C, YSCALE_YUV_2_MONO2_C)
1200+
1201+ yuv2packed2_c(c, buf0, buf1, uvbuf0, uvbuf1, abuf0, abuf1,
1202+ dest, dstW, yalpha, uvalpha, y);
13241203 }
13251204
13261205 /**
@@ -1329,18 +1208,13 @@ static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, cons · 2 unmodified lines
13291208 static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, const uint16_t *uvbuf0, const uint16_t *uvbuf1,
13301209 const uint16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, enum PixelFormat dstFormat, int flags, int y)
13311210 {
1332− const int yalpha1=0;
1333− int i;
1334−
1335− const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
1336− const int yalpha= 4096; //FIXME ...
1211+ const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1
13371212
1338− if (flags&SWS_FULL_CHR_H_INT) {
1339− c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y);
1340− return;
1341− }
1213+ if (flags&SWS_FULL_CHR_H_INT) {
1214+ c->yuv2packed2(c, buf0, buf0, uvbuf0, uvbuf1, abuf0, abuf0, dest, dstW, 0, uvalpha, y);
1215+ return;
1216+ }
13421217
1343− if(!(flags & SWS_BITEXACT)) {
13441218 if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster
13451219 switch(dstFormat) {
13461220 case PIX_FMT_RGB32:
@@ -1554,12 +1428,9 @@ static inline void RENAME(yuv2packed1)(SwsContext *c, const uint16_t *buf0, cons · 207 unmodified lines
15541428 return;
15551429 }
15561430 }
1557− }
1558− if (uvalpha < 2048) {
1559− YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1_C, YSCALE_YUV_2_PACKED1_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C)
1560− } else {
1561− YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB1B_C, YSCALE_YUV_2_PACKED1B_C(void,0), YSCALE_YUV_2_GRAY16_1_C, YSCALE_YUV_2_MONO2_C)
1562− }
1431+
1432+ yuv2packed1_c(c, buf0, uvbuf0, uvbuf1, abuf0, dest,
1433+ dstW, uvalpha, dstFormat, flags, y);
15631434 }
15641435
15651436 //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
18661737 assert(src1 == src2);
18671738 }
18681739
1869−static inline void RENAME(bgr24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
1870−{
1871− int i;
1872− for (i=0; i<width; i++) {
1873− int b= src1[6*i + 0] + src1[6*i + 3];
1874− int g= src1[6*i + 1] + src1[6*i + 4];
1875− int r= src1[6*i + 2] + src1[6*i + 5];
1876−
1877− dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1878− dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1879− }
1880− assert(src1 == src2);
1881−}
1882−
18831740 static inline void RENAME(rgb24ToY)(uint8_t *dst, const uint8_t *src, long width, uint32_t *unused)
18841741 {
18851742 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
18911748 RENAME(bgr24ToUV_mmx)(dstU, dstV, src1, width, PIX_FMT_RGB24);
18921749 }
18931750
1894−static inline void RENAME(rgb24ToUV_half)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)
1895−{
1896− int i;
1897− assert(src1==src2);
1898− for (i=0; i<width; i++) {
1899− int r= src1[6*i + 0] + src1[6*i + 3];
1900− int g= src1[6*i + 1] + src1[6*i + 4];
1901− int b= src1[6*i + 2] + src1[6*i + 5];
1902−
1903− dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1904− dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
1905− }
1906−}
1907−
19081751
19091752 // bilinear / bicubic scaling
19101753 static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW, int xInc,
@@ -2061,50 +1904,168 @@ static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, in · 150 unmodified lines
20611904 }
20621905 }
20631906
2064−//FIXME all pal and rgb srcFormats could do this convertion as well
2065−//FIXME all scalers more complex than bilinear could do half of this transform
2066−static void RENAME(chrRangeToJpeg)(int16_t *dst, int width)
1907+static inline void RENAME(hScale16)(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
1908+ const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
20671909 {
2068− int i;
2069− for (i = 0; i < width; i++) {
2070− dst[i ] = (FFMIN(dst[i ],30775)*4663 - 9289992)>>12; //-264
2071− dst[i+VOFW] = (FFMIN(dst[i+VOFW],30775)*4663 - 9289992)>>12; //-264
2072− }
2073−}
2074−static void RENAME(chrRangeFromJpeg)(int16_t *dst, int width)
2075−{
2076− int i;
2077− for (i = 0; i < width; i++) {
2078− dst[i ] = (dst[i ]*1799 + 4081085)>>11; //1469
2079− dst[i+VOFW] = (dst[i+VOFW]*1799 + 4081085)>>11; //1469
1910+ int i, j;
1911+
1912+ assert(filterSize % 4 == 0 && filterSize>0);
1913+ if (filterSize==4 && shift<15) { // Always true for upscaling, sometimes for down, too.
1914+ x86_reg counter= -2*dstW;
1915+ filter-= counter*2;
1916+ filterPos-= counter/2;
1917+ dst-= counter/2;
1918+ __asm__ volatile(
1919+ "movd %5, %%mm7 \n\t"
1920+#if defined(PIC)
1921+ "push %%"REG_b" \n\t"
1922+#endif
1923+ "push %%"REG_BP" \n\t" // we use 7 regs here ...
1924+ "mov %%"REG_a", %%"REG_BP" \n\t"
1925+ ".p2align 4 \n\t"
1926+ "1: \n\t"
1927+ "movzwl (%2, %%"REG_BP"), %%eax \n\t"
1928+ "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t"
1929+ "movq (%1, %%"REG_BP", 4), %%mm1 \n\t"
1930+ "movq 8(%1, %%"REG_BP", 4), %%mm3 \n\t"
1931+ "movq (%3, %%"REG_a", 2), %%mm0 \n\t"
1932+ "movq (%3, %%"REG_b", 2), %%mm2 \n\t"
1933+ "pmaddwd %%mm1, %%mm0 \n\t"
1934+ "pmaddwd %%mm2, %%mm3 \n\t"
1935+ "movq %%mm0, %%mm4 \n\t"
1936+ "punpckldq %%mm3, %%mm0 \n\t"
1937+ "punpckhdq %%mm3, %%mm4 \n\t"
1938+ "paddd %%mm4, %%mm0 \n\t"
1939+ "psrad %%mm7, %%mm0 \n\t"
1940+ "packssdw %%mm0, %%mm0 \n\t"
1941+ "movd %%mm0, (%4, %%"REG_BP") \n\t"
1942+ "add $4, %%"REG_BP" \n\t"
1943+ " jnc 1b \n\t"
1944+
1945+ "pop %%"REG_BP" \n\t"
1946+#if defined(PIC)
1947+ "pop %%"REG_b" \n\t"
1948+#endif
1949+ : "+a" (counter)
1950+ : "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift)
1951+#if !defined(PIC)
1952+ : "%"REG_b
1953+#endif
1954+ );
1955+ } else if (filterSize==8 && shift<15) {
1956+ x86_reg counter= -2*dstW;
1957+ filter-= counter*4;
1958+ filterPos-= counter/2;
1959+ dst-= counter/2;
1960+ __asm__ volatile(
1961+ "movd %5, %%mm7 \n\t"
1962+#if defined(PIC)
1963+ "push %%"REG_b" \n\t"
1964+#endif
1965+ "push %%"REG_BP" \n\t" // we use 7 regs here ...
1966+ "mov %%"REG_a", %%"REG_BP" \n\t"
1967+ ".p2align 4 \n\t"
1968+ "1: \n\t"
1969+ "movzwl (%2, %%"REG_BP"), %%eax \n\t"
1970+ "movzwl 2(%2, %%"REG_BP"), %%ebx \n\t"
1971+ "movq (%1, %%"REG_BP", 8), %%mm1 \n\t"
1972+ "movq 16(%1, %%"REG_BP", 8), %%mm3 \n\t"
1973+ "movq (%3, %%"REG_a", 2), %%mm0 \n\t"
1974+ "movq (%3, %%"REG_b", 2), %%mm2 \n\t"
1975+ "pmaddwd %%mm1, %%mm0 \n\t"
1976+ "pmaddwd %%mm2, %%mm3 \n\t"
1977+
1978+ "movq 8(%1, %%"REG_BP", 8), %%mm1 \n\t"
1979+ "movq 24(%1, %%"REG_BP", 8), %%mm5 \n\t"
1980+ "movq 8(%3, %%"REG_a", 2), %%mm4 \n\t"
1981+ "movq 8(%3, %%"REG_b", 2), %%mm2 \n\t"
1982+ "pmaddwd %%mm1, %%mm4 \n\t"
1983+ "pmaddwd %%mm2, %%mm5 \n\t"
1984+ "paddd %%mm4, %%mm0 \n\t"
1985+ "paddd %%mm5, %%mm3 \n\t"
1986+ "movq %%mm0, %%mm4 \n\t"
1987+ "punpckldq %%mm3, %%mm0 \n\t"
1988+ "punpckhdq %%mm3, %%mm4 \n\t"
1989+ "paddd %%mm4, %%mm0 \n\t"
1990+ "psrad %%mm7, %%mm0 \n\t"
1991+ "packssdw %%mm0, %%mm0 \n\t"
1992+ "movd %%mm0, (%4, %%"REG_BP") \n\t"
1993+ "add $4, %%"REG_BP" \n\t"
1994+ " jnc 1b \n\t"
1995+
1996+ "pop %%"REG_BP" \n\t"
1997+#if defined(PIC)
1998+ "pop %%"REG_b" \n\t"
1999+#endif
2000+ : "+a" (counter)
2001+ : "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift)
2002+#if !defined(PIC)
2003+ : "%"REG_b
2004+#endif
2005+ );
2006+ } else if (shift<15){
2007+ const uint16_t *offset = src+filterSize;
2008+ x86_reg counter= -2*dstW;
2009+ //filter-= counter*filterSize/2;
2010+ filterPos-= counter/2;
2011+ dst-= counter/2;
2012+ __asm__ volatile(
2013+ "movd %7, %%mm7 \n\t"
2014+ ".p2align 4 \n\t"
2015+ "1: \n\t"
2016+ "mov %2, %%"REG_c" \n\t"
2017+ "movzwl (%%"REG_c", %0), %%eax \n\t"
2018+ "movzwl 2(%%"REG_c", %0), %%edx \n\t"
2019+ "mov %5, %%"REG_c" \n\t"
2020+ "pxor %%mm4, %%mm4 \n\t"
2021+ "pxor %%mm5, %%mm5 \n\t"
2022+ "2: \n\t"
2023+ "movq (%1), %%mm1 \n\t"
2024+ "movq (%1, %6), %%mm3 \n\t"
2025+ "movq (%%"REG_c", %%"REG_a", 2), %%mm0 \n\t"
2026+ "movq (%%"REG_c", %%"REG_d", 2), %%mm2 \n\t"
2027+ "pmaddwd %%mm1, %%mm0 \n\t"
2028+ "pmaddwd %%mm2, %%mm3 \n\t"
2029+ "paddd %%mm3, %%mm5 \n\t"
2030+ "paddd %%mm0, %%mm4 \n\t"
2031+ "add $8, %1 \n\t"
2032+ "add $8, %%"REG_c" \n\t"
2033+ "cmp %4, %%"REG_c" \n\t"
2034+ " jb 2b \n\t"
2035+ "add %6, %1 \n\t"
2036+ "movq %%mm4, %%mm0 \n\t"
2037+ "punpckldq %%mm5, %%mm4 \n\t"
2038+ "punpckhdq %%mm5, %%mm0 \n\t"
2039+ "paddd %%mm0, %%mm4 \n\t"
2040+ "psrad %%mm7, %%mm4 \n\t"
2041+ "packssdw %%mm4, %%mm4 \n\t"
2042+ "mov %3, %%"REG_a" \n\t"
2043+ "movd %%mm4, (%%"REG_a", %0) \n\t"
2044+ "add $4, %0 \n\t"
2045+ " jnc 1b \n\t"
2046+
2047+ : "+r" (counter), "+r" (filter)
2048+ : "m" (filterPos), "m" (dst), "m"(offset),
2049+ "m" (src), "r" ((x86_reg)filterSize*2), "m"(shift)
2050+ : "%"REG_a, "%"REG_c, "%"REG_d
2051+ );
2052+ } else
2053+ for (i=0; i<dstW; i++) {
2054+ int srcPos= filterPos[i];
2055+ int val=0;
2056+ for (j=0; j<filterSize; j++) {
2057+ val += ((int)src[srcPos + j])*filter[filterSize*i + j];
2058+ }
2059+ dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
20802060 }
20812061 }
2082−static void RENAME(lumRangeToJpeg)(int16_t *dst, int width)
2083−{
2084− int i;
2085− for (i = 0; i < width; i++)
2086− dst[i] = (FFMIN(dst[i],30189)*19077 - 39057361)>>14;
2087−}
2088−static void RENAME(lumRangeFromJpeg)(int16_t *dst, int width)
2089−{
2090− int i;
2091− for (i = 0; i < width; i++)
2092− dst[i] = (dst[i]*14071 + 33561947)>>14;
2093−}
20942062
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" \
21022063
2064+#if COMPILE_TEMPLATE_MMX2
21032065 static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst,
21042066 long dstWidth, const uint8_t *src, int srcW,
21052067 int xInc)
21062068 {
2107−#if COMPILE_TEMPLATE_MMX2
21082069 int32_t *filterPos = c->hLumFilterPos;
21092070 int16_t *filter = c->hLumFilter;
21102071 int canMMX2BeUsed = c->canMMX2BeUsed;
@@ -2113,7 +2074,7 @@ static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, · 2 unmodified lines
21132074 #if defined(PIC)
21142075 DECLARE_ALIGNED(8, uint64_t, ebxsave);
21152076 #endif
2116− if (canMMX2BeUsed) {
2077+
21172078 __asm__ volatile(
21182079 #if defined(PIC)
21192080 "mov %%"REG_b", %5 \n\t"
@@ -2172,80 +2133,12 @@ static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, · 52 unmodified lines
21722133 #endif
21732134 );
21742135 for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128;
2175− } else {
2176−#endif /* COMPILE_TEMPLATE_MMX2 */
2177− x86_reg xInc_shr16 = xInc >> 16;
2178− uint16_t xInc_mask = xInc & 0xffff;
2179− x86_reg dstWidth_reg = dstWidth;
2180− //NO MMX just normal asm ...
2181− __asm__ volatile(
2182− "xor %%"REG_a", %%"REG_a" \n\t" // i
2183− "xor %%"REG_d", %%"REG_d" \n\t" // xx
2184− "xorl %%ecx, %%ecx \n\t" // xalpha
2185− ".p2align 4 \n\t"
2186− "1: \n\t"
2187− "movzbl (%0, %%"REG_d"), %%edi \n\t" //src[xx]
2188− "movzbl 1(%0, %%"REG_d"), %%esi \n\t" //src[xx+1]
2189− FAST_BILINEAR_X86
2190− "movw %%si, (%%"REG_D", %%"REG_a", 2) \n\t"
2191− "addw %4, %%cx \n\t" //xalpha += xInc&0xFFFF
2192− "adc %3, %%"REG_d" \n\t" //xx+= xInc>>16 + carry
2193−
2194− "movzbl (%0, %%"REG_d"), %%edi \n\t" //src[xx]
2195− "movzbl 1(%0, %%"REG_d"), %%esi \n\t" //src[xx+1]
2196− FAST_BILINEAR_X86
2197− "movw %%si, 2(%%"REG_D", %%"REG_a", 2) \n\t"
2198− "addw %4, %%cx \n\t" //xalpha += xInc&0xFFFF
2199− "adc %3, %%"REG_d" \n\t" //xx+= xInc>>16 + carry
2200−
2201−
2202− "add $2, %%"REG_a" \n\t"
2203− "cmp %2, %%"REG_a" \n\t"
2204− " jb 1b \n\t"
2205−
2206−
2207− :: "r" (src), "m" (dst), "m" (dstWidth_reg), "m" (xInc_shr16), "m" (xInc_mask)
2208− : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi"
2209− );
2210−#if COMPILE_TEMPLATE_MMX2
2211− } //if MMX2 can't be used
2212−#endif
2213−}
2214−
2215− // *** horizontal scale Y line to temp buffer
2216−static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src, int srcW, int xInc,
2217− const int16_t *hLumFilter,
2218− const int16_t *hLumFilterPos, int hLumFilterSize,
2219− uint8_t *formatConvBuffer,
2220− uint32_t *pal, int isAlpha)
2221−{
2222− void (*toYV12)(uint8_t *, const uint8_t *, long, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
2223− void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
2224−
2225− src += isAlpha ? c->alpSrcOffset : c->lumSrcOffset;
2226−
2227− if (toYV12) {
2228− toYV12(formatConvBuffer, src, srcW, pal);
2229− src= formatConvBuffer;
2230− }
2231−
2232− if (c->hScale16) {
2233− c->hScale16(dst, dstWidth, (uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1);
2234− } else if (!c->hyscale_fast) {
2235− c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);
2236− } else { // fast bilinear upscale / crap downscale
2237− c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
2238− }
2239−
2240− if (convertRange)
2241− convertRange(dst, dstWidth);
22422136 }
22432137
22442138 static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst,
22452139 long dstWidth, const uint8_t *src1,
22462140 const uint8_t *src2, int srcW, int xInc)
22472141 {
2248−#if COMPILE_TEMPLATE_MMX2
22492142 int32_t *filterPos = c->hChrFilterPos;
22502143 int16_t *filter = c->hChrFilter;
22512144 int canMMX2BeUsed = c->canMMX2BeUsed;
@@ -2254,7 +2147,7 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, · 2 unmodified lines
22542147 #if defined(PIC)
22552148 DECLARE_ALIGNED(8, uint64_t, ebxsave);
22562149 #endif
2257− if (canMMX2BeUsed) {
2150+
22582151 __asm__ volatile(
22592152 #if defined(PIC)
22602153 "mov %%"REG_b", %6 \n\t"
@@ -2304,252 +2197,32 @@ static inline void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst, · 43 unmodified lines
23042197 dst[i] = src1[srcW-1]*128;
23052198 dst[i+VOFW] = src2[srcW-1]*128;
23062199 }
2307− } else {
2308−#endif /* COMPILE_TEMPLATE_MMX2 */
2309− x86_reg xInc_shr16 = (x86_reg) (xInc >> 16);
2310− uint16_t xInc_mask = xInc & 0xffff;
2311− x86_reg dstWidth_reg = dstWidth;
2312− __asm__ volatile(
2313− "xor %%"REG_a", %%"REG_a" \n\t" // i
2314− "xor %%"REG_d", %%"REG_d" \n\t" // xx
2315− "xorl %%ecx, %%ecx \n\t" // xalpha
2316− ".p2align 4 \n\t"
2317− "1: \n\t"
2318− "mov %0, %%"REG_S" \n\t"
2319− "movzbl (%%"REG_S", %%"REG_d"), %%edi \n\t" //src[xx]
2320− "movzbl 1(%%"REG_S", %%"REG_d"), %%esi \n\t" //src[xx+1]
2321− FAST_BILINEAR_X86
2322− "movw %%si, (%%"REG_D", %%"REG_a", 2) \n\t"
2323−
2324− "movzbl (%5, %%"REG_d"), %%edi \n\t" //src[xx]
2325− "movzbl 1(%5, %%"REG_d"), %%esi \n\t" //src[xx+1]
2326− FAST_BILINEAR_X86
2327− "movw %%si, "AV_STRINGIFY(VOF)"(%%"REG_D", %%"REG_a", 2) \n\t"
2328−
2329− "addw %4, %%cx \n\t" //xalpha += xInc&0xFFFF
2330− "adc %3, %%"REG_d" \n\t" //xx+= xInc>>16 + carry
2331− "add $1, %%"REG_a" \n\t"
2332− "cmp %2, %%"REG_a" \n\t"
2333− " jb 1b \n\t"
2334−
2335−/* GCC 3.3 makes MPlayer crash on IA-32 machines when using "g" operand here,
2336−which is needed to support GCC 4.0. */
2337−#if ARCH_X86_64 && AV_GCC_VERSION_AT_LEAST(3,4)
2338− :: "m" (src1), "m" (dst), "g" (dstWidth_reg), "m" (xInc_shr16), "m" (xInc_mask),
2339−#else
2340− :: "m" (src1), "m" (dst), "m" (dstWidth_reg), "m" (xInc_shr16), "m" (xInc_mask),
2341−#endif
2342− "r" (src2)
2343− : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi"
2344− );
2345−#if COMPILE_TEMPLATE_MMX2
2346− } //if MMX2 can't be used
2347−#endif
2348−}
2349−
2350−inline static void RENAME(hcscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src1, const uint8_t *src2,
2351− int srcW, int xInc, const int16_t *hChrFilter,
2352− const int16_t *hChrFilterPos, int hChrFilterSize,
2353− uint8_t *formatConvBuffer,
2354− uint32_t *pal)
2355−{
2356−
2357− src1 += c->chrSrcOffset;
2358− src2 += c->chrSrcOffset;
2359−
2360− if (c->chrToYV12) {
2361− c->chrToYV12(formatConvBuffer, formatConvBuffer+VOFW, src1, src2, srcW, pal);
2362− src1= formatConvBuffer;
2363− src2= formatConvBuffer+VOFW;
2364− }
2365−
2366− if (c->hScale16) {
2367− c->hScale16(dst , dstWidth, (uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1);
2368− c->hScale16(dst+VOFW, dstWidth, (uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1);
2369− } else if (!c->hcscale_fast) {
2370− c->hScale(dst , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
2371− c->hScale(dst+VOFW, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);
2372− } else { // fast bilinear upscale / crap downscale
2373− c->hcscale_fast(c, dst, dstWidth, src1, src2, srcW, xInc);
2374− }
2375−
2376− if (c->chrConvertRange)
2377− c->chrConvertRange(dst, dstWidth);
23782200 }
2201+#endif /* COMPILE_TEMPLATE_MMX2 */
23792202
2380−#define DEBUG_SWSCALE_BUFFERS 0
2381−#define DEBUG_BUFFERS(...) if (DEBUG_SWSCALE_BUFFERS) av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
2382−
2383−static int RENAME(swScale)(SwsContext *c, const uint8_t* src[], int srcStride[], int srcSliceY,
2384− int srcSliceH, uint8_t* dst[], int dstStride[])
2203+#if !COMPILE_TEMPLATE_MMX2
2204+static void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex,
2205+ int lastInLumBuf, int lastInChrBuf)
23852206 {
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;
23892207 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;
23952208 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;
23962214 int16_t *vLumFilterPos= c->vLumFilterPos;
23972215 int16_t *vChrFilterPos= c->vChrFilterPos;
2398− int16_t *hLumFilterPos= c->hLumFilterPos;
2399− int16_t *hChrFilterPos= c->hChrFilterPos;
24002216 int16_t *vLumFilter= c->vLumFilter;
24012217 int16_t *vChrFilter= c->vChrFilter;
2402− int16_t *hLumFilter= c->hLumFilter;
2403− int16_t *hChrFilter= c->hChrFilter;
24042218 int32_t *lumMmxFilter= c->lumMmxFilter;
24052219 int32_t *chrMmxFilter= c->chrMmxFilter;
24062220 int32_t av_unused *alpMmxFilter= c->alpMmxFilter;
24072221 const int vLumFilterSize= c->vLumFilterSize;
24082222 const int vChrFilterSize= c->vChrFilterSize;
2409− const int hLumFilterSize= c->hLumFilterSize;
2410− const int hChrFilterSize= c->hChrFilterSize;
2411− int16_t **lumPixBuf= c->lumPixBuf;
2412− int16_t **chrPixBuf= c->chrPixBuf;
2413− int16_t **alpPixBuf= c->alpPixBuf;
2414− const int vLumBufSize= c->vLumBufSize;
2415− const int vChrBufSize= c->vChrBufSize;
2416− uint8_t *formatConvBuffer= c->formatConvBuffer;
2417− const int chrSrcSliceY= srcSliceY >> c->chrSrcVSubSample;
2418− const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
2419− int lastDstY;
2420− uint32_t *pal=c->pal_yuv;
2421−
2422− /* vars which will change and which we need to store back in the context */
2423− int dstY= c->dstY;
2424− int lumBufIndex= c->lumBufIndex;
2425− int chrBufIndex= c->chrBufIndex;
2426− int lastInLumBuf= c->lastInLumBuf;
2427− int lastInChrBuf= c->lastInChrBuf;
2428−
2429− if (isPacked(c->srcFormat)) {
2430− src[0]=
2431− src[1]=
2432− src[2]=
2433− src[3]= src[0];
2434− srcStride[0]=
2435− srcStride[1]=
2436− srcStride[2]=
2437− srcStride[3]= srcStride[0];
2438− }
2439− srcStride[1]<<= c->vChrDrop;
2440− srcStride[2]<<= c->vChrDrop;
2441−
2442− DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
2443− src[0], srcStride[0], src[1], srcStride[1], src[2], srcStride[2], src[3], srcStride[3],
2444− dst[0], dstStride[0], dst[1], dstStride[1], dst[2], dstStride[2], dst[3], dstStride[3]);
2445− DEBUG_BUFFERS("srcSliceY: %d srcSliceH: %d dstY: %d dstH: %d\n",
2446− srcSliceY, srcSliceH, dstY, dstH);
2447− DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
2448− vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
2449−
2450− if (dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0 || dstStride[3]%8 != 0) {
2451− static int warnedAlready=0; //FIXME move this into the context perhaps
2452− if (flags & SWS_PRINT_INFO && !warnedAlready) {
2453− av_log(c, AV_LOG_WARNING, "Warning: dstStride is not aligned!\n"
2454− " ->cannot do aligned memory accesses anymore\n");
2455− warnedAlready=1;
2456− }
2457− }
2458−
2459− /* Note the user might start scaling the picture in the middle so this
2460− will not get executed. This is not really intended but works
2461− currently, so people might do it. */
2462− if (srcSliceY ==0) {
2463− lumBufIndex=-1;
2464− chrBufIndex=-1;
2465− dstY=0;
2466− lastInLumBuf= -1;
2467− lastInChrBuf= -1;
2468− }
2469−
2470− lastDstY= dstY;
2471−
2472− for (;dstY < dstH; dstY++) {
2473− unsigned char *dest =dst[0]+dstStride[0]*dstY;
2474− const int chrDstY= dstY>>c->chrDstVSubSample;
2475− unsigned char *uDest=dst[1]+dstStride[1]*chrDstY;
2476− unsigned char *vDest=dst[2]+dstStride[2]*chrDstY;
2477− unsigned char *aDest=(CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3]+dstStride[3]*dstY : NULL;
2478−
2479− const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
2480− const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<<c->chrDstVSubSample) - 1), dstH-1)];
2481− const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
2482− int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input
2483− int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input
2484− int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input
2485− int enough_lines;
2486−
2487− //handle holes (FAST_BILINEAR & weird filters)
2488− if (firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;
2489− if (firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;
2490− assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
2491− assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
2492−
2493− DEBUG_BUFFERS("dstY: %d\n", dstY);
2494− DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
2495− firstLumSrcY, lastLumSrcY, lastInLumBuf);
2496− DEBUG_BUFFERS("\tfirstChrSrcY: %d lastChrSrcY: %d lastInChrBuf: %d\n",
2497− firstChrSrcY, lastChrSrcY, lastInChrBuf);
2498−
2499− // Do we have enough lines in this slice to output the dstY line
2500− enough_lines = lastLumSrcY2 < srcSliceY + srcSliceH && lastChrSrcY < -((-srcSliceY - srcSliceH)>>c->chrSrcVSubSample);
2501−
2502− if (!enough_lines) {
2503− lastLumSrcY = srcSliceY + srcSliceH - 1;
2504− lastChrSrcY = chrSrcSliceY + chrSrcSliceH - 1;
2505− DEBUG_BUFFERS("buffering slice: lastLumSrcY %d lastChrSrcY %d\n",
2506− lastLumSrcY, lastChrSrcY);
2507− }
2508−
2509− //Do horizontal scaling
2510− while(lastInLumBuf < lastLumSrcY) {
2511− const uint8_t *src1= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];
2512− const uint8_t *src2= src[3]+(lastInLumBuf + 1 - srcSliceY)*srcStride[3];
2513− lumBufIndex++;
2514− assert(lumBufIndex < 2*vLumBufSize);
2515− assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
2516− assert(lastInLumBuf + 1 - srcSliceY >= 0);
2517− RENAME(hyscale)(c, lumPixBuf[ lumBufIndex ], dstW, src1, srcW, lumXInc,
2518− hLumFilter, hLumFilterPos, hLumFilterSize,
2519− formatConvBuffer,
2520− pal, 0);
2521− if (CONFIG_SWSCALE_ALPHA && alpPixBuf)
2522− RENAME(hyscale)(c, alpPixBuf[ lumBufIndex ], dstW, src2, srcW, lumXInc,
2523− hLumFilter, hLumFilterPos, hLumFilterSize,
2524− formatConvBuffer,
2525− pal, 1);
2526− lastInLumBuf++;
2527− DEBUG_BUFFERS("\t\tlumBufIndex %d: lastInLumBuf: %d\n",
2528− lumBufIndex, lastInLumBuf);
2529− }
2530− while(lastInChrBuf < lastChrSrcY) {
2531− const uint8_t *src1= src[1]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[1];
2532− const uint8_t *src2= src[2]+(lastInChrBuf + 1 - chrSrcSliceY)*srcStride[2];
2533− chrBufIndex++;
2534− assert(chrBufIndex < 2*vChrBufSize);
2535− assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
2536− assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
2537− //FIXME replace parameters through context struct (some at least)
2538−
2539− if (c->needs_hcscale)
2540− RENAME(hcscale)(c, chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, chrSrcW, chrXInc,
2541− hChrFilter, hChrFilterPos, hChrFilterSize,
2542− formatConvBuffer,
2543− pal);
2544− lastInChrBuf++;
2545− DEBUG_BUFFERS("\t\tchrBufIndex %d: lastInChrBuf: %d\n",
2546− chrBufIndex, lastInChrBuf);
2547− }
2548− //wrap buf index around to stay inside the ring buffer
2549− if (lumBufIndex >= vLumBufSize) lumBufIndex-= vLumBufSize;
2550− if (chrBufIndex >= vChrBufSize) chrBufIndex-= vChrBufSize;
2551− if (!enough_lines)
2552− break; //we can't output a dstY line so let's try with the next slice
2223+ const int chrDstY= dstY>>c->chrDstVSubSample;
2224+ const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input
2225+ const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input
25532226
25542227 c->blueDither= ff_dither8[dstY&1];
25552228 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
25572230 else
25582231 c->greenDither= ff_dither4[dstY&1];
25592232 c->redDither= ff_dither8[(dstY+1)&1];
2560− if (dstY < dstH-2) {
2233+ if (dstY < dstH - 2) {
25612234 const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
25622235 const int16_t **chrSrcPtr= (const int16_t **) chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
25632236 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
26062279 ((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001;
26072280 }
26082281 }
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− }
27232282 }
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;
27412283 }
2284+#endif /* !COMPILE_TEMPLATE_MMX2 */
27422285
27432286 static void RENAME(sws_init_swScale)(SwsContext *c)
27442287 {
27452288 enum PixelFormat srcFormat = c->srcFormat;
27462289
2747− c->yuv2nv12X = RENAME(yuv2nv12X );
2748− c->yuv2yuv1 = RENAME(yuv2yuv1 );
2749− c->yuv2yuvX = RENAME(yuv2yuvX );
2750− c->yuv2packed1 = RENAME(yuv2packed1 );
2751− c->yuv2packed2 = RENAME(yuv2packed2 );
2752− c->yuv2packedX = RENAME(yuv2packedX );
2290+ if (!(c->flags & SWS_BITEXACT)) {
2291+ c->yuv2yuv1 = RENAME(yuv2yuv1 );
2292+ c->yuv2yuvX = RENAME(yuv2yuvX );
2293+ c->yuv2packed1 = RENAME(yuv2packed1 );
2294+ c->yuv2packed2 = RENAME(yuv2packed2 );
2295+ c->yuv2packedX = RENAME(yuv2packedX );
2296+ }
27532297
27542298 c->hScale = RENAME(hScale );
27552299
27562300 // 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
27572302 if (c->flags & SWS_FAST_BILINEAR && c->canMMX2BeUsed)
27582303 {
27592304 c->hyscale_fast = RENAME(hyscale_fast);
27602305 c->hcscale_fast = RENAME(hcscale_fast);
27612306 } else {
2307+#endif /* COMPILE_TEMPLATE_MMX2 */
27622308 c->hyscale_fast = NULL;
27632309 c->hcscale_fast = NULL;
2310+#if COMPILE_TEMPLATE_MMX2
27642311 }
2312+#endif /* COMPILE_TEMPLATE_MMX2 */
27652313
2766− switch(srcFormat) {
2314+ switch(srcFormat) {
27672315 case PIX_FMT_YUYV422 : c->chrToYV12 = RENAME(yuy2ToUV); break;
27682316 case PIX_FMT_UYVY422 : c->chrToYV12 = RENAME(uyvyToUV); break;
27692317 case PIX_FMT_NV12 : c->chrToYV12 = RENAME(nv12ToUV); break;
27702318 case PIX_FMT_NV21 : c->chrToYV12 = RENAME(nv21ToUV); break;
2771− case PIX_FMT_YUV420P16BE:
2772− case PIX_FMT_YUV422P16BE:
2773− case PIX_FMT_YUV444P16BE: c->chrToYV12 = RENAME(BEToUV); break;
2319+ case PIX_FMT_GRAY16LE :
2320+ case PIX_FMT_YUV420P9LE:
2321+ case PIX_FMT_YUV422P10LE:
2322+ case PIX_FMT_YUV420P10LE:
27742323 case PIX_FMT_YUV420P16LE:
27752324 case PIX_FMT_YUV422P16LE:
2776− case PIX_FMT_YUV444P16LE: c->chrToYV12 = RENAME(LEToUV); break;
2777− default: break;
2778− }
2779− if (c->chrSrcHSubSample) {
2780− switch(srcFormat) {
2781− case PIX_FMT_BGR24 : c->chrToYV12 = RENAME(bgr24ToUV_half); break;
2782− case PIX_FMT_RGB24 : c->chrToYV12 = RENAME(rgb24ToUV_half); break;
2783− default: break;
2784− }
2785− } else {
2325+ case PIX_FMT_YUV444P16LE: c->hScale16= RENAME(hScale16); break;
2326+ }
2327+ if (!c->chrSrcHSubSample) {
27862328 switch(srcFormat) {
27872329 case PIX_FMT_BGR24 : c->chrToYV12 = RENAME(bgr24ToUV); break;
27882330 case PIX_FMT_RGB24 : c->chrToYV12 = RENAME(rgb24ToUV); break;
@@ -2792,16 +2334,10 @@ static void RENAME(sws_init_swScale)(SwsContext *c) · 3 unmodified lines
27922334
27932335 switch (srcFormat) {
27942336 case PIX_FMT_YUYV422 :
2795− case PIX_FMT_YUV420P16BE:
2796− case PIX_FMT_YUV422P16BE:
2797− case PIX_FMT_YUV444P16BE:
27982337 case PIX_FMT_Y400A :
2799− case PIX_FMT_GRAY16BE : c->lumToYV12 = RENAME(yuy2ToY); break;
2338+ c->lumToYV12 = RENAME(yuy2ToY); break;
28002339 case PIX_FMT_UYVY422 :
2801− case PIX_FMT_YUV420P16LE:
2802− case PIX_FMT_YUV422P16LE:
2803− case PIX_FMT_YUV444P16LE:
2804− case PIX_FMT_GRAY16LE : c->lumToYV12 = RENAME(uyvyToY); break;
2340+ c->lumToYV12 = RENAME(uyvyToY); break;
28052341 case PIX_FMT_BGR24 : c->lumToYV12 = RENAME(bgr24ToY); break;
28062342 case PIX_FMT_RGB24 : c->lumToYV12 = RENAME(rgb24ToY); break;
28072343 default: break;
@@ -2812,14 +2348,4 @@ static void RENAME(sws_init_swScale)(SwsContext *c) · 4 unmodified lines
28122348 default: break;
28132349 }
28142350 }
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− }
28252351 }
libswscale/x86/yuv2rgb_mmx.c+36−34
@@ -34,6 +34,7 @@ · 33 unmodified lines
3434 #include "libswscale/swscale.h"
3535 #include "libswscale/swscale_internal.h"
3636 #include "libavutil/x86_cpu.h"
37+#include "libavutil/cpu.h"
3738
3839 #define DITHER1XBPP // only for MMX
3940
@@ -46,57 +47,58 @@ DECLARE_ASM_CONST(8, uint64_t, pb_03) = 0x0303030303030303ULL; · 6 unmodified lines
4647 DECLARE_ASM_CONST(8, uint64_t, pb_07) = 0x0707070707070707ULL;
4748
4849 //MMX versions
50+#if HAVE_MMX
4951 #undef RENAME
50−#undef HAVE_MMX2
51−#undef HAVE_AMD3DNOW
52−#define HAVE_MMX2 0
53−#define HAVE_AMD3DNOW 0
52+#undef COMPILE_TEMPLATE_MMX2
53+#define COMPILE_TEMPLATE_MMX2 0
5454 #define RENAME(a) a ## _MMX
5555 #include "yuv2rgb_template.c"
56+#endif /* HAVE_MMX */
5657
5758 //MMX2 versions
59+#if HAVE_MMX2
5860 #undef RENAME
59−#undef HAVE_MMX2
60−#define HAVE_MMX2 1
61+#undef COMPILE_TEMPLATE_MMX2
62+#define COMPILE_TEMPLATE_MMX2 1
6163 #define RENAME(a) a ## _MMX2
6264 #include "yuv2rgb_template.c"
65+#endif /* HAVE_MMX2 */
6366
6467 SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c)
6568 {
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) {
6776 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;
7877 case PIX_FMT_RGB24: return yuv420_rgb24_MMX2;
7978 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;
8279 }
8380 }
84− if (c->flags & SWS_CPU_CAPS_MMX) {
81+
82+ if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
8583 switch (c->dstFormat) {
86− case PIX_FMT_RGB32:
87− if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) {
88− if (HAVE_7REGS) return yuva420_rgb32_MMX;
89− break;
90− } else return yuv420_rgb32_MMX;
91− case PIX_FMT_BGR32:
92− if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) {
93− if (HAVE_7REGS) return yuva420_bgr32_MMX;
94− break;
95− } else return yuv420_bgr32_MMX;
96− case PIX_FMT_RGB24: return yuv420_rgb24_MMX;
97− case PIX_FMT_BGR24: return yuv420_bgr24_MMX;
98− case PIX_FMT_RGB565: return yuv420_rgb16_MMX;
99− case PIX_FMT_RGB555: return yuv420_rgb15_MMX;
84+ case PIX_FMT_RGB32:
85+ if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) {
86+#if HAVE_7REGS
87+ return yuva420_rgb32_MMX;
88+#endif
89+ break;
90+ } else return yuv420_rgb32_MMX;
91+ case PIX_FMT_BGR32:
92+ if (CONFIG_SWSCALE_ALPHA && c->srcFormat == PIX_FMT_YUVA420P) {
93+#if HAVE_7REGS
94+ return yuva420_bgr32_MMX;
95+#endif
96+ break;
97+ } else return yuv420_bgr32_MMX;
98+ case PIX_FMT_RGB24: return yuv420_rgb24_MMX;
99+ case PIX_FMT_BGR24: return yuv420_bgr24_MMX;
100+ case PIX_FMT_RGB565: return yuv420_rgb16_MMX;
101+ case PIX_FMT_RGB555: return yuv420_rgb15_MMX;
100102 }
101103 }
102104
libswscale/x86/yuv2rgb_template.c+13−16
@@ -25,14 +25,7 @@ · 24 unmodified lines
2525 #undef EMMS
2626 #undef SFENCE
2727
28−#if HAVE_AMD3DNOW
29−/* On K6 femms is faster than emms. On K7 femms is directly mapped to emms. */
30−#define EMMS "femms"
31−#else
32−#define EMMS "emms"
33−#endif
34−
35−#if HAVE_MMX2
28+#if COMPILE_TEMPLATE_MMX2
3629 #define MOVNTQ "movntq"
3730 #define SFENCE "sfence"
3831 #else
@@ -159,7 +152,8 @@ · 120 unmodified lines
159152 } \
160153
161154 #define YUV2RGB_ENDFUNC \
162− __asm__ volatile (SFENCE"\n\t"EMMS); \
155+ __asm__ volatile (SFENCE"\n\t" \
156+ "emms \n\t"); \
163157 return srcSliceH; \
164158
165159 #define IF0(x)
@@ -188,6 +182,7 @@ · 22 unmodified lines
188182 "paddusb "GREEN_DITHER"(%4), %%mm2\n\t" \
189183 "paddusb "RED_DITHER"(%4), %%mm1\n\t" \
190184
185+#if !COMPILE_TEMPLATE_MMX2
191186 static inline int RENAME(yuv420_rgb15)(SwsContext *c, const uint8_t *src[],
192187 int srcStride[],
193188 int srcSliceY, int srcSliceH,
@@ -243,6 +238,7 @@ static inline int RENAME(yuv420_rgb16)(SwsContext *c, const uint8_t *src[], · 49 unmodified lines
243238 YUV2RGB_OPERANDS
244239 YUV2RGB_ENDFUNC
245240 }
241+#endif /* !COMPILE_TEMPLATE_MMX2 */
246242
247243 #define RGB_PACK24(blue, red)\
248244 "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
259255 "punpckhwd %%mm6, %%mm5 \n" /* R4 G4 B4 R5 R6 G6 B6 R7 */\
260256 RGB_PACK24_B
261257
262−#if HAVE_MMX2
258+#if COMPILE_TEMPLATE_MMX2
263259 DECLARE_ASM_CONST(8, int16_t, mask1101[4]) = {-1,-1, 0,-1};
264260 DECLARE_ASM_CONST(8, int16_t, mask0010[4]) = { 0, 0,-1, 0};
265261 DECLARE_ASM_CONST(8, int16_t, mask0110[4]) = { 0,-1,-1, 0};
@@ -366,6 +362,7 @@ static inline int RENAME(yuv420_bgr24)(SwsContext *c, const uint8_t *src[], · 100 unmodified lines
366362 MOVNTQ " %%mm5, 16(%1)\n\t" \
367363 MOVNTQ " %%mm"alpha", 24(%1)\n\t" \
368364
365+#if !COMPILE_TEMPLATE_MMX2
369366 static inline int RENAME(yuv420_rgb32)(SwsContext *c, const uint8_t *src[],
370367 int srcStride[],
371368 int srcSliceY, int srcSliceH,
@@ -386,12 +383,12 @@ static inline int RENAME(yuv420_rgb32)(SwsContext *c, const uint8_t *src[], · 14 unmodified lines
386383 YUV2RGB_ENDFUNC
387384 }
388385
386+#if HAVE_7REGS && CONFIG_SWSCALE_ALPHA
389387 static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[],
390388 int srcStride[],
391389 int srcSliceY, int srcSliceH,
392390 uint8_t *dst[], int dstStride[])
393391 {
394−#if HAVE_7REGS
395392 int y, h_size;
396393
397394 YUV2RGB_LOOP(4)
@@ -406,9 +403,8 @@ static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[], · 8 unmodified lines
406403 YUV2RGB_ENDLOOP(4)
407404 YUV2RGB_OPERANDS_ALPHA
408405 YUV2RGB_ENDFUNC
409−#endif
410− return 0;
411406 }
407+#endif
412408
413409 static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[],
414410 int srcStride[],
@@ -430,12 +426,12 @@ static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[], · 15 unmodified lines
430426 YUV2RGB_ENDFUNC
431427 }
432428
429+#if HAVE_7REGS && CONFIG_SWSCALE_ALPHA
433430 static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[],
434431 int srcStride[],
435432 int srcSliceY, int srcSliceH,
436433 uint8_t *dst[], int dstStride[])
437434 {
438−#if HAVE_7REGS
439435 int y, h_size;
440436
441437 YUV2RGB_LOOP(4)
@@ -450,6 +446,7 @@ static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[], · 8 unmodified lines
450446 YUV2RGB_ENDLOOP(4)
451447 YUV2RGB_OPERANDS_ALPHA
452448 YUV2RGB_ENDFUNC
453−#endif
454− return 0;
455449 }
450+#endif
451+
452+#endif /* !COMPILE_TEMPLATE_MMX2 */
libswscale/yuv2rgb.c+11−17
@@ -32,7 +32,7 @@ · 31 unmodified lines
3232 #include "rgb2rgb.h"
3333 #include "swscale.h"
3434 #include "swscale_internal.h"
35−#include "libavutil/x86_cpu.h"
35+#include "libavutil/cpu.h"
3636 #include "libavutil/bswap.h"
3737
3838 extern const uint8_t dither_4x4_16[4][8];
@@ -579,24 +579,18 @@ CLOSEYUV2RGBFUNC(1) · 540 unmodified lines
579579 SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
580580 {
581581 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
595582
596−#if ARCH_BFIN
597− if (c->flags & SWS_CPU_CAPS_BFIN)
583+ if (HAVE_MMX) {
584+ t = ff_yuv2rgb_init_mmx(c);
585+ } else if (HAVE_VIS) {
586+ t = ff_yuv2rgb_init_vis(c);
587+ } else if (CONFIG_MLIB) {
588+ t = ff_yuv2rgb_init_mlib(c);
589+ } else if (HAVE_ALTIVEC) {
590+ t = ff_yuv2rgb_init_altivec(c);
591+ } else if (ARCH_BFIN) {
598592 t = ff_yuv2rgb_get_func_ptr_bfin(c);
599−#endif
593+ }
600594
601595 if (t)
602596 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