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:
parent
bbd8f5477d
commit
171bc51c9b
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user