diff --git a/doc/encoders.texi b/doc/encoders.texi index 2f347f4fb1..2855d89f7a 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -353,4 +353,16 @@ HDCD A/D Converter @end table +@subheading Other AC-3 Encoding Options + +@table @option + +@item -stereo_rematrixing @var{boolean} +Stereo Rematrixing. Enables/Disables use of rematrixing for stereo input. This +is an optional AC-3 feature that increases quality by selectively encoding +the left/right channels as mid/side. This option is enabled by default, and it +is highly recommended that it be left as enabled except for testing purposes. + +@end table + @c man end ENCODERS diff --git a/doc/fate.txt b/doc/fate.txt index a074ed1e5d..f8ce68ea77 100644 --- a/doc/fate.txt +++ b/doc/fate.txt @@ -8,6 +8,7 @@ that is provided separately from the actual source distribution. Use the following command to get the fate test samples # rsync -aL rsync://rsync.mplayerhq.hu:/samples/fate-suite/ fate/fate-suite +# rsync -aL rsync://fate-suite.libav.org:/fate-suite/ fate-suite To inform the build system about the testsuite location, pass `--samples=` to configure or set the SAMPLES Make diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index 6baf989394..fcb401c238 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -158,6 +158,7 @@ typedef struct AC3EncOptions { /* other encoding options */ int allow_per_frame_metadata; + int stereo_rematrixing; } AC3EncOptions; diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index 0b5b501a27..4ec0f2a19c 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -164,8 +164,10 @@ static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs) if (e >= 24) { e = 24; coef[i] = 0; + } else if (e < 0) { + e = 0; + coef[i] = av_clip(coef[i], -16777215, 16777215); } - av_assert2(e >= 0); } exp[i] = e; } diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index 4f922198e1..48df4b7e6b 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -52,12 +52,6 @@ /** Maximum number of exponent groups. +1 for separate DC exponent. */ #define AC3_MAX_EXP_GROUPS 85 -/* stereo rematrixing algorithms */ -#define AC3_REMATRIXING_IS_STATIC 0x1 -#define AC3_REMATRIXING_SUMS 0 -#define AC3_REMATRIXING_NONE 1 -#define AC3_REMATRIXING_ALWAYS 3 - #if CONFIG_AC3ENC_FLOAT #define MAC_COEF(d,a,b) ((d)+=(a)*(b)) typedef float SampleType; @@ -137,10 +131,10 @@ typedef struct AC3EncodeContext { int loro_surround_mix_level; ///< Lo/Ro surround mix level code int cutoff; ///< user-specified cutoff frequency, in Hz - int bandwidth_code[AC3_MAX_CHANNELS]; ///< bandwidth code (0 to 60) (chbwcod) + int bandwidth_code; ///< bandwidth code (0 to 60) (chbwcod) int nb_coefs[AC3_MAX_CHANNELS]; - int rematrixing; ///< determines how rematrixing strategy is calculated + int rematrixing_enabled; ///< stereo rematrixing enabled int num_rematrixing_bands; ///< number of rematrixing bands /* bitrate allocation control */ @@ -240,6 +234,8 @@ const AVOption ff_ac3_options[] = { {"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 1, AC3ENC_PARAM, "ad_conv_type"}, {"standard", "Standard (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, +/* Other Encoding Options */ +{"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM}, {NULL} }; #endif @@ -404,28 +400,6 @@ static void apply_mdct(AC3EncodeContext *s) } -/** - * Initialize stereo rematrixing. - * If the strategy does not change for each frame, set the rematrixing flags. - */ -static void rematrixing_init(AC3EncodeContext *s) -{ - if (s->channel_mode == AC3_CHMODE_STEREO) - s->rematrixing = AC3_REMATRIXING_SUMS; - else - s->rematrixing = AC3_REMATRIXING_NONE; - /* NOTE: AC3_REMATRIXING_ALWAYS might be used in - the future in conjunction with channel coupling. */ - - if (s->rematrixing & AC3_REMATRIXING_IS_STATIC) { - int flag = (s->rematrixing == AC3_REMATRIXING_ALWAYS); - s->blocks[0].new_rematrixing_strategy = 1; - memset(s->blocks[0].rematrixing_flags, flag, - sizeof(s->blocks[0].rematrixing_flags)); - } -} - - /** * Determine rematrixing flags for each block and band. */ @@ -435,16 +409,18 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) int blk, bnd, i; AC3Block *block, *block0; - s->num_rematrixing_bands = 4; - - if (s->rematrixing & AC3_REMATRIXING_IS_STATIC) + if (s->channel_mode != AC3_CHMODE_STEREO) return; + s->num_rematrixing_bands = 4; + nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { block = &s->blocks[blk]; block->new_rematrixing_strategy = !blk; + if (!s->rematrixing_enabled) + continue; for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) { /* calculate calculate sum of squared coeffs for one band in one block */ int start = ff_ac3_rematrix_band_tab[bnd]; @@ -488,7 +464,7 @@ static void apply_rematrixing(AC3EncodeContext *s) int start, end; uint8_t *flags; - if (s->rematrixing == AC3_REMATRIXING_NONE) + if (!s->rematrixing_enabled) return; nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); @@ -518,11 +494,13 @@ static void apply_rematrixing(AC3EncodeContext *s) */ static av_cold void exponent_init(AC3EncodeContext *s) { - int i; - for (i = 73; i < 256; i++) { - exponent_group_tab[0][i] = (i - 1) / 3; - exponent_group_tab[1][i] = (i + 2) / 6; - exponent_group_tab[2][i] = (i + 8) / 12; + int expstr, i, grpsize; + + for (expstr = EXP_D15-1; expstr <= EXP_D45-1; expstr++) { + grpsize = 3 << expstr; + for (i = 73; i < 256; i++) { + exponent_group_tab[expstr][i] = (i + grpsize - 4) / grpsize; + } } /* LFE */ exponent_group_tab[0][7] = 2; @@ -555,56 +533,47 @@ static void extract_exponents(AC3EncodeContext *s) #define EXP_DIFF_THRESHOLD 500 -/** - * Calculate exponent strategies for all blocks in a single channel. - */ -static void compute_exp_strategy_ch(AC3EncodeContext *s, uint8_t *exp_strategy, - uint8_t *exp) -{ - int blk, blk1; - int exp_diff; - - /* estimate if the exponent variation & decide if they should be - reused in the next frame */ - exp_strategy[0] = EXP_NEW; - exp += AC3_MAX_COEFS; - for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { - exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16); - if (exp_diff > EXP_DIFF_THRESHOLD) - exp_strategy[blk] = EXP_NEW; - else - exp_strategy[blk] = EXP_REUSE; - exp += AC3_MAX_COEFS; - } - - /* now select the encoding strategy type : if exponents are often - recoded, we use a coarse encoding */ - blk = 0; - while (blk < AC3_MAX_BLOCKS) { - blk1 = blk + 1; - while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) - blk1++; - switch (blk1 - blk) { - case 1: exp_strategy[blk] = EXP_D45; break; - case 2: - case 3: exp_strategy[blk] = EXP_D25; break; - default: exp_strategy[blk] = EXP_D15; break; - } - blk = blk1; - } -} - - /** * Calculate exponent strategies for all channels. * Array arrangement is reversed to simplify the per-channel calculation. */ static void compute_exp_strategy(AC3EncodeContext *s) { - int ch, blk; + int ch, blk, blk1; for (ch = 0; ch < s->fbw_channels; ch++) { - compute_exp_strategy_ch(s, s->exp_strategy[ch], s->blocks[0].exp[ch]); + uint8_t *exp_strategy = s->exp_strategy[ch]; + uint8_t *exp = s->blocks[0].exp[ch]; + int exp_diff; + + /* estimate if the exponent variation & decide if they should be + reused in the next frame */ + exp_strategy[0] = EXP_NEW; + exp += AC3_MAX_COEFS; + for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { + exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16); + if (exp_diff > EXP_DIFF_THRESHOLD) + exp_strategy[blk] = EXP_NEW; + else + exp_strategy[blk] = EXP_REUSE; + exp += AC3_MAX_COEFS; + } + + /* now select the encoding strategy type : if exponents are often + recoded, we use a coarse encoding */ + blk = 0; + while (blk < AC3_MAX_BLOCKS) { + blk1 = blk + 1; + while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) + blk1++; + switch (blk1 - blk) { + case 1: exp_strategy[blk] = EXP_D45; break; + case 2: + case 3: exp_strategy[blk] = EXP_D25; break; + default: exp_strategy[blk] = EXP_D15; break; + } + blk = blk1; + } } if (s->lfe_on) { ch = s->lfe_channel; @@ -1005,7 +974,8 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset) reset_block_bap(s); mantissa_bits = 0; for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { - AC3Block *block; + AC3Block *block = &s->blocks[blk]; + AC3Block *ref_block; // initialize grouped mantissa counts. these are set so that they are // padded to the next whole group size when bits are counted in // compute_mantissa_size_final @@ -1017,14 +987,17 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset) blocks within a frame are the exponent values. We can take advantage of that by reusing the bit allocation pointers whenever we reuse exponents. */ - block = s->blocks[blk].exp_ref_block[ch]; + ref_block = block->exp_ref_block[ch]; if (s->exp_strategy[ch][blk] != EXP_REUSE) { - s->ac3dsp.bit_alloc_calc_bap(block->mask[ch], block->psd[ch], 0, - s->nb_coefs[ch], snr_offset, - s->bit_alloc.floor, ff_ac3_bap_tab, - block->bap[ch]); + s->ac3dsp.bit_alloc_calc_bap(ref_block->mask[ch], + ref_block->psd[ch], 0, + s->nb_coefs[ch], snr_offset, + s->bit_alloc.floor, ff_ac3_bap_tab, + ref_block->bap[ch]); } - mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt, block->bap[ch], s->nb_coefs[ch]); + mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt, + ref_block->bap[ch], + s->nb_coefs[ch]); } mantissa_bits += compute_mantissa_size_final(mant_cnt); } @@ -1043,7 +1016,8 @@ static int cbr_bit_allocation(AC3EncodeContext *s) int snr_offset, snr_incr; bits_left = 8 * s->frame_size - (s->frame_bits + s->exponent_bits); - av_assert2(bits_left >= 0); + if (bits_left < 0) + return AVERROR(EINVAL); snr_offset = s->coarse_snr_offset << 4; @@ -1121,27 +1095,6 @@ static int downgrade_exponents(AC3EncodeContext *s) } -/** - * Reduce the bandwidth to reduce the number of bits used for a given SNR offset. - * This is a second fallback for when bit allocation still fails after exponents - * have been downgraded. - * @return non-zero if bandwidth reduction was unsuccessful - */ -static int reduce_bandwidth(AC3EncodeContext *s, int min_bw_code) -{ - int ch; - - if (s->bandwidth_code[0] > min_bw_code) { - for (ch = 0; ch < s->fbw_channels; ch++) { - s->bandwidth_code[ch]--; - s->nb_coefs[ch] = s->bandwidth_code[ch] * 3 + 73; - } - return 0; - } - return -1; -} - - /** * Perform bit allocation search. * Finds the SNR offset value that maximizes quality and fits in the specified @@ -1167,15 +1120,6 @@ static int compute_bit_allocation(AC3EncodeContext *s) continue; } - /* fallback 2: reduce bandwidth */ - /* only do this if the user has not specified a specific cutoff - frequency */ - if (!s->cutoff && !reduce_bandwidth(s, 0)) { - process_exponents(s); - ret = compute_bit_allocation(s); - continue; - } - /* fallbacks were not enough... */ break; } @@ -1436,7 +1380,7 @@ static void output_audio_block(AC3EncodeContext *s, int blk) /* bandwidth */ for (ch = 0; ch < s->fbw_channels; ch++) { if (s->exp_strategy[ch][blk] != EXP_REUSE) - put_bits(&s->pb, 6, s->bandwidth_code[ch]); + put_bits(&s->pb, 6, s->bandwidth_code); } /* exponents */ @@ -2062,6 +2006,9 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) if (ret) return ret; + s->rematrixing_enabled = s->options.stereo_rematrixing && + (s->channel_mode == AC3_CHMODE_STEREO); + return 0; } @@ -2073,22 +2020,21 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) */ static av_cold void set_bandwidth(AC3EncodeContext *s) { - int ch, bw_code; + int ch; if (s->cutoff) { /* calculate bandwidth based on user-specified cutoff frequency */ int fbw_coeffs; fbw_coeffs = s->cutoff * 2 * AC3_MAX_COEFS / s->sample_rate; - bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); + s->bandwidth_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); } else { /* use default bandwidth setting */ - bw_code = ac3_bandwidth_tab[s->fbw_channels-1][s->bit_alloc.sr_code][s->frame_size_code/2]; + s->bandwidth_code = ac3_bandwidth_tab[s->fbw_channels-1][s->bit_alloc.sr_code][s->frame_size_code/2]; } /* set number of coefficients for each channel */ for (ch = 0; ch < s->fbw_channels; ch++) { - s->bandwidth_code[ch] = bw_code; - s->nb_coefs[ch] = bw_code * 3 + 73; + s->nb_coefs[ch] = s->bandwidth_code * 3 + 73; } if (s->lfe_on) s->nb_coefs[s->lfe_channel] = 7; /* LFE channel always has 7 coefs */ @@ -2220,8 +2166,6 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx) set_bandwidth(s); - rematrixing_init(s); - exponent_init(s); bit_alloc_init(s); diff --git a/libavcodec/alpha/simple_idct_alpha.c b/libavcodec/alpha/simple_idct_alpha.c index 7f396bfe5f..522efd2b4d 100644 --- a/libavcodec/alpha/simple_idct_alpha.c +++ b/libavcodec/alpha/simple_idct_alpha.c @@ -46,7 +46,7 @@ /* 0: all entries 0, 1: only first entry nonzero, 2: otherwise */ static inline int idct_row(DCTELEM *row) { - int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3, t; + int a0, a1, a2, a3, b0, b1, b2, b3, t; uint64_t l, r, t2; l = ldq(row); r = ldq(row + 4); @@ -154,7 +154,7 @@ static inline int idct_row(DCTELEM *row) static inline void idct_col(DCTELEM *col) { - int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3; + int a0, a1, a2, a3, b0, b1, b2, b3; col[0] += (1 << (COL_SHIFT - 1)) / W4; @@ -235,7 +235,7 @@ static inline void idct_col2(DCTELEM *col) uint64_t l, r; for (i = 0; i < 8; ++i) { - int_fast32_t a0 = col[i] + (1 << (COL_SHIFT - 1)) / W4; + int a0 = col[i] + (1 << (COL_SHIFT - 1)) / W4; a0 *= W4; col[i] = a0 >> COL_SHIFT; diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c index 1d637b4e81..7cf9d50835 100644 --- a/libavcodec/dpxenc.c +++ b/libavcodec/dpxenc.c @@ -136,7 +136,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, switch(s->bits_per_component) { case 8: case 16: - size = avpicture_layout((AVPicture*)data, avctx->pix_fmt, + size = avpicture_layout(data, avctx->pix_fmt, avctx->width, avctx->height, buf + HEADER_SIZE, buf_size - HEADER_SIZE); if (size < 0) @@ -146,7 +146,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, size = avctx->height * avctx->width * 4; if (buf_size < HEADER_SIZE + size) return -1; - encode_rgb48_10bit(avctx, (AVPicture*)data, buf + HEADER_SIZE); + encode_rgb48_10bit(avctx, data, buf + HEADER_SIZE); break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", s->bits_per_component); @@ -160,13 +160,13 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, } AVCodec ff_dpx_encoder = { - "dpx", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_DPX, - sizeof(DPXContext), - encode_init, - encode_frame, - .pix_fmts= (const enum PixelFormat[]){ + .name = "dpx", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_DPX, + .priv_data_size = sizeof(DPXContext), + .init = encode_init, + .encode = encode_frame, + .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_RGB48LE,