Commit be7bd626 authored by Justin Ruggles's avatar Justin Ruggles

eac3enc: use different numbers of blocks per frame to allow higher bitrates

parent 4555874a
This diff is collapsed.
......@@ -151,6 +151,8 @@ typedef struct AC3EncodeContext {
int bit_rate; ///< target bit rate, in bits-per-second
int sample_rate; ///< sampling frequency, in Hz
int num_blks_code; ///< number of blocks code (numblkscod)
int num_blocks; ///< number of blocks per frame
int frame_size_min; ///< minimum frame size in case rounding is necessary
int frame_size; ///< current frame size in bytes
int frame_size_code; ///< frame size code (frmsizecod)
......
......@@ -93,7 +93,7 @@ static void scale_coefficients(AC3EncodeContext *s)
{
int blk, ch;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->channels; ch++) {
s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
......
......@@ -103,7 +103,7 @@ static int normalize_samples(AC3EncodeContext *s)
*/
static void scale_coefficients(AC3EncodeContext *s)
{
int chan_size = AC3_MAX_COEFS * AC3_MAX_BLOCKS;
int chan_size = AC3_MAX_COEFS * s->num_blocks;
s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + chan_size,
s->mdct_coef_buffer + chan_size,
chan_size * s->channels);
......
......@@ -79,13 +79,13 @@ static void deinterleave_input_samples(AC3EncodeContext *s,
int sinc;
/* copy last 256 samples of previous frame to the start of the current frame */
memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_FRAME_SIZE],
memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_BLOCK_SIZE * s->num_blocks],
AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0]));
/* deinterleave */
sinc = s->channels;
sptr = samples + s->channel_map[ch];
for (i = AC3_BLOCK_SIZE; i < AC3_FRAME_SIZE+AC3_BLOCK_SIZE; i++) {
for (i = AC3_BLOCK_SIZE; i < AC3_BLOCK_SIZE * (s->num_blocks + 1); i++) {
s->planar_samples[ch][i] = *sptr;
sptr += sinc;
}
......@@ -103,7 +103,7 @@ static void apply_mdct(AC3EncodeContext *s)
int blk, ch;
for (ch = 0; ch < s->channels; ch++) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
......@@ -159,7 +159,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
cpl_start = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs;
/* calculate coupling channel from fbw channels */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start];
if (!block->cpl_in_use)
......@@ -188,7 +188,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
while (i < s->cpl_end_freq) {
int band_size = s->cpl_band_sizes[bnd];
for (ch = CPL_CH; ch <= s->fbw_channels; ch++) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch]))
continue;
......@@ -203,7 +203,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
}
/* determine which blocks to send new coupling coordinates for */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL;
int new_coords = 0;
......@@ -261,7 +261,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
coordinates in successive blocks */
for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
blk = 0;
while (blk < AC3_MAX_BLOCKS) {
while (blk < s->num_blocks) {
int blk1;
CoefSumType energy_cpl;
AC3Block *block = &s->blocks[blk];
......@@ -273,7 +273,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
energy_cpl = energy[blk][CPL_CH][bnd];
blk1 = blk+1;
while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) {
while (!s->blocks[blk1].new_cpl_coords && blk1 < s->num_blocks) {
if (s->blocks[blk1].cpl_in_use)
energy_cpl += energy[blk1][CPL_CH][bnd];
blk1++;
......@@ -285,7 +285,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
continue;
energy_ch = energy[blk][ch][bnd];
blk1 = blk+1;
while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) {
while (!s->blocks[blk1].new_cpl_coords && blk1 < s->num_blocks) {
if (s->blocks[blk1].cpl_in_use)
energy_ch += energy[blk1][ch][bnd];
blk1++;
......@@ -297,7 +297,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
}
/* calculate exponents/mantissas for coupling coordinates */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use || !block->new_cpl_coords)
continue;
......@@ -362,7 +362,7 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s)
if (s->channel_mode != AC3_CHMODE_STEREO)
return;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
block = &s->blocks[blk];
block->new_rematrixing_strategy = !blk;
......@@ -440,7 +440,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, unsigned char *frame,
scale_coefficients(s);
clip_coefficients(&s->dsp, s->blocks[0].mdct_coef[1],
AC3_MAX_COEFS * AC3_MAX_BLOCKS * s->channels);
AC3_MAX_COEFS * s->num_blocks * s->channels);
s->cpl_on = s->cpl_enabled;
ff_ac3_compute_coupling_strategy(s);
......
......@@ -63,6 +63,11 @@ void ff_eac3_get_frame_exp_strategy(AC3EncodeContext *s)
{
int ch;
if (s->num_blocks < 6) {
s->use_frame_exp_strategy = 0;
return;
}
s->use_frame_exp_strategy = 1;
for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) {
int expstr = eac3_frame_expstr_index_tab[s->exp_strategy[ch][0]-1]
......@@ -89,7 +94,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s)
/* set first cpl coords */
for (ch = 1; ch <= s->fbw_channels; ch++)
first_cpl_coords[ch] = 1;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) {
......@@ -104,7 +109,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s)
}
/* set first cpl leak */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
if (block->cpl_in_use) {
block->new_cpl_leak = 2;
......@@ -130,7 +135,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
put_bits(&s->pb, 2, s->bit_alloc.sr_code); /* sample rate code */
} else {
put_bits(&s->pb, 2, s->bit_alloc.sr_code); /* sample rate code */
put_bits(&s->pb, 2, 0x3); /* number of blocks = 6 */
put_bits(&s->pb, 2, s->num_blks_code); /* number of blocks */
}
put_bits(&s->pb, 3, s->channel_mode); /* audio coding mode */
put_bits(&s->pb, 1, s->lfe_on); /* LFE channel indicator */
......@@ -141,11 +146,15 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
/* TODO: mixing metadata */
put_bits(&s->pb, 1, 0); /* no info metadata */
/* TODO: info metadata */
if (s->num_blocks != 6)
put_bits(&s->pb, 1, !(s->avctx->frame_number % 6)); /* converter sync flag */
put_bits(&s->pb, 1, 0); /* no additional bit stream info */
/* frame header */
if (s->num_blocks == 6) {
put_bits(&s->pb, 1, !s->use_frame_exp_strategy);/* exponent strategy syntax */
put_bits(&s->pb, 1, 0); /* aht enabled = no */
}
put_bits(&s->pb, 2, 0); /* snr offset strategy = 1 */
put_bits(&s->pb, 1, 0); /* transient pre-noise processing enabled = no */
put_bits(&s->pb, 1, 0); /* block switch syntax enabled = no */
......@@ -158,7 +167,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
/* coupling strategy use flags */
if (s->channel_mode > AC3_CHMODE_MONO) {
put_bits(&s->pb, 1, s->blocks[0].cpl_in_use);
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) {
for (blk = 1; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
put_bits(&s->pb, 1, block->new_cpl_strategy);
if (block->new_cpl_strategy)
......@@ -170,26 +179,31 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++)
put_bits(&s->pb, 5, s->frame_exp_strategy[ch]);
} else {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
for (blk = 0; blk < s->num_blocks; blk++)
for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++)
put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
}
if (s->lfe_on) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
for (blk = 0; blk < s->num_blocks; blk++)
put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);
}
/* E-AC-3 to AC-3 converter exponent strategy (unfortunately not optional...) */
/* E-AC-3 to AC-3 converter exponent strategy (not optional when num blocks == 6) */
if (s->num_blocks != 6) {
put_bits(&s->pb, 1, 0);
} else {
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (s->use_frame_exp_strategy)
put_bits(&s->pb, 5, s->frame_exp_strategy[ch]);
else
put_bits(&s->pb, 5, 0);
}
}
/* snr offsets */
put_bits(&s->pb, 6, s->coarse_snr_offset);
put_bits(&s->pb, 4, s->fine_snr_offset[1]);
/* block start info */
put_bits(&s->pb, 1, 0);
if (s->num_blocks > 1)
put_bits(&s->pb, 1, 0);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment