From 9c4e69b8eac8955ce65df2fba2addaeefe81784f Mon Sep 17 00:00:00 2001 From: Daniil Cherednik Date: Thu, 11 May 2017 21:12:07 +0000 Subject: [PATCH] avcodec/dcaenc: Do not abort process in case of bitrate deficit Old behaviour - abort if at least one subband has 1bit quantizer and consumed_bits still greater than frame_bits size. It was a bit strange - we still could reduce bits consumption by reducing SNR for other subbands. Same strange logic with upper threshold - stop bits allocation if at least one subband reach 26bits. New behaviour - if consumed_bits greater than frame_bits and all subbands has 1 bit quantizer we restart bits allocation and allow zero subbands. --- libavcodec/dcaenc.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c index 3af0ec1e75f..c1d72bfd16b 100644 --- a/libavcodec/dcaenc.c +++ b/libavcodec/dcaenc.c @@ -656,7 +656,6 @@ static void adpcm_analysis(DCAEncContext *c) static const int snr_fudge = 128; #define USED_1ABITS 1 -#define USED_NABITS 2 #define USED_26ABITS 4 static inline int32_t get_step_size(const DCAEncContext *c, int ch, int band) @@ -794,7 +793,7 @@ static uint32_t set_best_abits_code(int abits[DCAENC_SUBBANDS], int bands, int32 /* Check do we have subband which cannot be encoded by Huffman tables */ for (i = 0; i < bands; i++) { - if (abits[i] > 12) { + if (abits[i] > 12 || abits[i] == 0) { *res = best_sel; return best_bits; } @@ -812,9 +811,9 @@ static uint32_t set_best_abits_code(int abits[DCAENC_SUBBANDS], int bands, int32 return best_bits; } -static int init_quantization_noise(DCAEncContext *c, int noise) +static int init_quantization_noise(DCAEncContext *c, int noise, int forbid_zero) { - int ch, band, ret = 0; + int ch, band, ret = USED_26ABITS | USED_1ABITS; uint32_t huff_bit_count_accum[MAX_CHANNELS][DCA_CODE_BOOKS][7]; uint32_t clc_bit_count_accum[MAX_CHANNELS][DCA_CODE_BOOKS]; uint32_t bits_counter = 0; @@ -831,16 +830,19 @@ static int init_quantization_noise(DCAEncContext *c, int noise) if (snr_cb >= 1312) { c->abits[ch][band] = 26; - ret |= USED_26ABITS; + ret &= ~USED_1ABITS; } else if (snr_cb >= 222) { c->abits[ch][band] = 8 + mul32(snr_cb - 222, 69000000); - ret |= USED_NABITS; + ret &= ~(USED_26ABITS | USED_1ABITS); } else if (snr_cb >= 0) { c->abits[ch][band] = 2 + mul32(snr_cb, 106000000); - ret |= USED_NABITS; - } else { + ret &= ~(USED_26ABITS | USED_1ABITS); + } else if (forbid_zero || snr_cb >= -140) { c->abits[ch][band] = 1; - ret |= USED_1ABITS; + ret &= ~USED_26ABITS; + } else { + c->abits[ch][band] = 0; + ret &= ~(USED_26ABITS | USED_1ABITS); } } c->consumed_bits += set_best_abits_code(c->abits[ch], 32, &c->bit_allocation_sel[ch]); @@ -888,15 +890,19 @@ static void assign_bits(DCAEncContext *c) /* Find the bounds where the binary search should work */ int low, high, down; int used_abits = 0; - - init_quantization_noise(c, c->worst_quantization_noise); + int forbid_zero = 1; +restart: + init_quantization_noise(c, c->worst_quantization_noise, forbid_zero); low = high = c->worst_quantization_noise; if (c->consumed_bits > c->frame_bits) { while (c->consumed_bits > c->frame_bits) { - av_assert0(used_abits != USED_1ABITS); + if (used_abits == USED_1ABITS && forbid_zero) { + forbid_zero = 0; + goto restart; + } low = high; high += snr_fudge; - used_abits = init_quantization_noise(c, high); + used_abits = init_quantization_noise(c, high, forbid_zero); } } else { while (c->consumed_bits <= c->frame_bits) { @@ -904,17 +910,17 @@ static void assign_bits(DCAEncContext *c) if (used_abits == USED_26ABITS) goto out; /* The requested bitrate is too high, pad with zeros */ low -= snr_fudge; - used_abits = init_quantization_noise(c, low); + used_abits = init_quantization_noise(c, low, forbid_zero); } } /* Now do a binary search between low and high to see what fits */ for (down = snr_fudge >> 1; down; down >>= 1) { - init_quantization_noise(c, high - down); + init_quantization_noise(c, high - down, forbid_zero); if (c->consumed_bits <= c->frame_bits) high -= down; } - init_quantization_noise(c, high); + init_quantization_noise(c, high, forbid_zero); out: c->worst_quantization_noise = high; if (high > c->worst_noise_ever) @@ -1173,13 +1179,15 @@ static void put_subframe(DCAEncContext *c, int subframe) /* Transition mode: none for each channel and subband */ for (ch = 0; ch < c->fullband_channels; ch++) for (band = 0; band < DCAENC_SUBBANDS; band++) - put_bits(&c->pb, 1, 0); /* codebook A4 */ + if (c->abits[ch][band]) + put_bits(&c->pb, 1, 0); /* codebook A4 */ } /* Scale factors */ for (ch = 0; ch < c->fullband_channels; ch++) for (band = 0; band < DCAENC_SUBBANDS; band++) - put_bits(&c->pb, 7, c->scale_factor[ch][band]); + if (c->abits[ch][band]) + put_bits(&c->pb, 7, c->scale_factor[ch][band]); /* Joint subband scale factor codebook select: not transmitted */ /* Scale factors for joint subband coding: not transmitted */ @@ -1199,6 +1207,7 @@ static void put_subframe(DCAEncContext *c, int subframe) for (ss = 0; ss < SUBSUBFRAMES ; ss++) for (ch = 0; ch < c->fullband_channels; ch++) for (band = 0; band < DCAENC_SUBBANDS; band++) + if (c->abits[ch][band]) put_subframe_samples(c, ss, band, ch); /* DSYNC */ -- 2.39.2