Allocate bap and bap1 buffers using av_malloc().

This reduces the memory footprint when using less than 6 channels.
Modify bit allocation to swap the 2 buffers instead of using memcpy() and use
per-block pointers for bap. This is slightly faster (0.3%) in function
cbr_bit_allocation().

Originally committed as revision 26023 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Justin Ruggles 2010-12-15 21:12:28 +00:00
parent bbd8f5477d
commit 171bc51c9b

View File

@ -59,6 +59,7 @@ typedef struct IComplex {
* Data for a single audio block. * Data for a single audio block.
*/ */
typedef struct AC3Block { typedef struct AC3Block {
uint8_t **bap; ///< bap for each channel in this block
int32_t mdct_coef[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; int32_t mdct_coef[AC3_MAX_CHANNELS][AC3_MAX_COEFS];
uint8_t exp[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; uint8_t exp[AC3_MAX_CHANNELS][AC3_MAX_COEFS];
uint8_t exp_strategy[AC3_MAX_CHANNELS]; uint8_t exp_strategy[AC3_MAX_CHANNELS];
@ -121,8 +122,8 @@ typedef struct AC3EncodeContext {
int16_t planar_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE+AC3_FRAME_SIZE]; int16_t planar_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE+AC3_FRAME_SIZE];
int16_t windowed_samples[AC3_WINDOW_SIZE]; int16_t windowed_samples[AC3_WINDOW_SIZE];
uint8_t bap[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS]; uint8_t *bap_buffer;
uint8_t bap1[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS]; uint8_t *bap1_buffer;
} AC3EncodeContext; } AC3EncodeContext;
@ -907,6 +908,23 @@ static void bit_alloc_masking(AC3EncodeContext *s)
} }
/**
* Ensure that bap for each block and channel point to the current bap_buffer.
* They may have been switched during the bit allocation search.
*/
static void reset_block_bap(AC3EncodeContext *s)
{
int blk, ch;
if (s->blocks[0].bap[0] == s->bap_buffer)
return;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (ch = 0; ch < s->channels; ch++) {
s->blocks[blk].bap[ch] = &s->bap_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)];
}
}
}
/** /**
* Run the bit allocation with a given SNR offset. * Run the bit allocation with a given SNR offset.
* This calculates the bit allocation pointers that will be used to determine * This calculates the bit allocation pointers that will be used to determine
@ -915,7 +933,6 @@ static void bit_alloc_masking(AC3EncodeContext *s)
* is used. * is used.
*/ */
static int bit_alloc(AC3EncodeContext *s, static int bit_alloc(AC3EncodeContext *s,
uint8_t bap[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS],
int snr_offset) int snr_offset)
{ {
int blk, ch; int blk, ch;
@ -923,6 +940,7 @@ static int bit_alloc(AC3EncodeContext *s,
snr_offset = (snr_offset - 240) << 2; snr_offset = (snr_offset - 240) << 2;
reset_block_bap(s);
mantissa_bits = 0; mantissa_bits = 0;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
@ -933,8 +951,8 @@ static int bit_alloc(AC3EncodeContext *s,
ff_ac3_bit_alloc_calc_bap(block->mask[ch], block->psd[ch], 0, ff_ac3_bit_alloc_calc_bap(block->mask[ch], block->psd[ch], 0,
s->nb_coefs[ch], snr_offset, s->nb_coefs[ch], snr_offset,
s->bit_alloc.floor, ff_ac3_bap_tab, s->bit_alloc.floor, ff_ac3_bap_tab,
bap[blk][ch]); block->bap[ch]);
mantissa_bits += compute_mantissa_size(s, bap[blk][ch], s->nb_coefs[ch]); mantissa_bits += compute_mantissa_size(s, block->bap[ch], s->nb_coefs[ch]);
} }
} }
return mantissa_bits; return mantissa_bits;
@ -956,32 +974,35 @@ static int cbr_bit_allocation(AC3EncodeContext *s)
snr_offset = s->coarse_snr_offset << 4; snr_offset = s->coarse_snr_offset << 4;
while (snr_offset >= 0 && while (snr_offset >= 0 &&
bit_alloc(s, s->bap, snr_offset) > bits_left) { bit_alloc(s, snr_offset) > bits_left) {
snr_offset -= 64; snr_offset -= 64;
} }
if (snr_offset < 0) if (snr_offset < 0)
return AVERROR(EINVAL); return AVERROR(EINVAL);
FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer);
while (snr_offset + 64 <= 1023 && while (snr_offset + 64 <= 1023 &&
bit_alloc(s, s->bap1, snr_offset + 64) <= bits_left) { bit_alloc(s, snr_offset + 64) <= bits_left) {
snr_offset += 64; snr_offset += 64;
memcpy(s->bap, s->bap1, sizeof(s->bap1)); FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer);
} }
while (snr_offset + 16 <= 1023 && while (snr_offset + 16 <= 1023 &&
bit_alloc(s, s->bap1, snr_offset + 16) <= bits_left) { bit_alloc(s, snr_offset + 16) <= bits_left) {
snr_offset += 16; snr_offset += 16;
memcpy(s->bap, s->bap1, sizeof(s->bap1)); FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer);
} }
while (snr_offset + 4 <= 1023 && while (snr_offset + 4 <= 1023 &&
bit_alloc(s, s->bap1, snr_offset + 4) <= bits_left) { bit_alloc(s, snr_offset + 4) <= bits_left) {
snr_offset += 4; snr_offset += 4;
memcpy(s->bap, s->bap1, sizeof(s->bap1)); FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer);
} }
while (snr_offset + 1 <= 1023 && while (snr_offset + 1 <= 1023 &&
bit_alloc(s, s->bap1, snr_offset + 1) <= bits_left) { bit_alloc(s, snr_offset + 1) <= bits_left) {
snr_offset++; snr_offset++;
memcpy(s->bap, s->bap1, sizeof(s->bap1)); FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer);
} }
FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer);
reset_block_bap(s);
s->coarse_snr_offset = snr_offset >> 4; s->coarse_snr_offset = snr_offset >> 4;
for (ch = 0; ch < s->channels; ch++) for (ch = 0; ch < s->channels; ch++)
@ -1160,7 +1181,7 @@ static void quantize_mantissas(AC3EncodeContext *s)
for (ch = 0; ch < s->channels; ch++) { for (ch = 0; ch < s->channels; ch++) {
quantize_mantissas_blk_ch(s, block->mdct_coef[ch], block->exp_shift[ch], quantize_mantissas_blk_ch(s, block->mdct_coef[ch], block->exp_shift[ch],
block->encoded_exp[ch], s->bap[blk][ch], block->encoded_exp[ch], block->bap[ch],
block->qmant[ch], s->nb_coefs[ch]); block->qmant[ch], s->nb_coefs[ch]);
} }
} }
@ -1299,7 +1320,7 @@ static void output_audio_block(AC3EncodeContext *s,
int b, q; int b, q;
for (i = 0; i < s->nb_coefs[ch]; i++) { for (i = 0; i < s->nb_coefs[ch]; i++) {
q = block->qmant[ch][i]; q = block->qmant[ch][i];
b = s->bap[block_num][ch][i]; b = block->bap[ch][i];
switch (b) { switch (b) {
case 0: break; case 0: break;
case 1: if (q != 128) put_bits(&s->pb, 5, q); break; case 1: if (q != 128) put_bits(&s->pb, 5, q); break;
@ -1443,6 +1464,16 @@ static int ac3_encode_frame(AVCodecContext *avctx,
*/ */
static av_cold int ac3_encode_close(AVCodecContext *avctx) static av_cold int ac3_encode_close(AVCodecContext *avctx)
{ {
int blk;
AC3EncodeContext *s = avctx->priv_data;
av_freep(&s->bap_buffer);
av_freep(&s->bap1_buffer);
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
AC3Block *block = &s->blocks[blk];
av_freep(&block->bap);
}
av_freep(&avctx->coded_frame); av_freep(&avctx->coded_frame);
return 0; return 0;
} }
@ -1573,6 +1604,29 @@ static av_cold void set_bandwidth(AC3EncodeContext *s, int cutoff)
} }
static av_cold int allocate_buffers(AVCodecContext *avctx)
{
int blk;
AC3EncodeContext *s = avctx->priv_data;
FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * s->channels *
AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * s->channels *
AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail);
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
AC3Block *block = &s->blocks[blk];
FF_ALLOC_OR_GOTO(avctx, block->bap, s->channels * sizeof(*block->bap),
alloc_fail);
}
s->blocks[0].bap[0] = NULL;
reset_block_bap(s);
return 0;
alloc_fail:
return AVERROR(ENOMEM);
}
/** /**
* Initialize the encoder. * Initialize the encoder.
*/ */
@ -1603,6 +1657,12 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx)
mdct_init(9); mdct_init(9);
ret = allocate_buffers(avctx);
if (ret) {
ac3_encode_close(avctx);
return ret;
}
avctx->coded_frame= avcodec_alloc_frame(); avctx->coded_frame= avcodec_alloc_frame();
return 0; return 0;