mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
eac3enc: use frame exponent strategy when applicable.
This checks if the set of selected exponent strategies for all blocks in a channel are in the frame exponent strategy table, and if so, writes the table index instead of each strategy. This saves up to 7 bits per channel per frame, so the overall effect on quality is small.
This commit is contained in:
parent
31b69928e5
commit
08a747afb9
@ -124,7 +124,7 @@ OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o dvdata.o
|
||||
OBJS-$(CONFIG_DXA_DECODER) += dxa.o
|
||||
OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_data.o
|
||||
OBJS-$(CONFIG_EAC3_ENCODER) += eac3enc.o ac3enc.o ac3enc_float.o \
|
||||
ac3tab.o ac3.o kbdwin.o
|
||||
ac3tab.o ac3.o kbdwin.o eac3_data.o
|
||||
OBJS-$(CONFIG_EACMV_DECODER) += eacmv.o
|
||||
OBJS-$(CONFIG_EAMAD_DECODER) += eamad.o eaidct.o mpeg12.o \
|
||||
mpeg12data.o mpegvideo.o \
|
||||
|
@ -194,6 +194,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
|
||||
{
|
||||
int blk, ch;
|
||||
int got_cpl_snr;
|
||||
int num_cpl_blocks;
|
||||
|
||||
/* set coupling use flags for each block/channel */
|
||||
/* TODO: turn coupling on/off and adjust start band based on bit usage */
|
||||
@ -206,12 +207,14 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
|
||||
/* enable coupling for each block if at least 2 channels have coupling
|
||||
enabled for that block */
|
||||
got_cpl_snr = 0;
|
||||
num_cpl_blocks = 0;
|
||||
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
||||
AC3Block *block = &s->blocks[blk];
|
||||
block->num_cpl_channels = 0;
|
||||
for (ch = 1; ch <= s->fbw_channels; ch++)
|
||||
block->num_cpl_channels += block->channel_in_cpl[ch];
|
||||
block->cpl_in_use = block->num_cpl_channels > 1;
|
||||
num_cpl_blocks += block->cpl_in_use;
|
||||
if (!block->cpl_in_use) {
|
||||
block->num_cpl_channels = 0;
|
||||
for (ch = 1; ch <= s->fbw_channels; ch++)
|
||||
@ -237,6 +240,8 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
|
||||
block->new_snr_offsets = 0;
|
||||
}
|
||||
}
|
||||
if (!num_cpl_blocks)
|
||||
s->cpl_on = 0;
|
||||
|
||||
/* set bandwidth for each channel */
|
||||
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
||||
@ -301,6 +306,9 @@ static av_cold void exponent_init(AC3EncodeContext *s)
|
||||
}
|
||||
/* LFE */
|
||||
exponent_group_tab[0][0][7] = 2;
|
||||
|
||||
if (CONFIG_EAC3_ENCODER && s->eac3)
|
||||
ff_eac3_exponent_init();
|
||||
}
|
||||
|
||||
|
||||
@ -342,8 +350,15 @@ static void compute_exp_strategy(AC3EncodeContext *s)
|
||||
exp_strategy[0] = EXP_NEW;
|
||||
exp += AC3_MAX_COEFS;
|
||||
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++, exp += AC3_MAX_COEFS) {
|
||||
if ((ch == CPL_CH && (!s->blocks[blk].cpl_in_use || !s->blocks[blk-1].cpl_in_use)) ||
|
||||
(ch > CPL_CH && (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]))) {
|
||||
if (ch == CPL_CH) {
|
||||
if (!s->blocks[blk-1].cpl_in_use) {
|
||||
exp_strategy[blk] = EXP_NEW;
|
||||
continue;
|
||||
} else if (!s->blocks[blk].cpl_in_use) {
|
||||
exp_strategy[blk] = EXP_REUSE;
|
||||
continue;
|
||||
}
|
||||
} else if (s->blocks[blk].channel_in_cpl[ch] != s->blocks[blk-1].channel_in_cpl[ch]) {
|
||||
exp_strategy[blk] = EXP_NEW;
|
||||
continue;
|
||||
}
|
||||
@ -377,6 +392,10 @@ static void compute_exp_strategy(AC3EncodeContext *s)
|
||||
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++)
|
||||
s->exp_strategy[ch][blk] = EXP_REUSE;
|
||||
}
|
||||
|
||||
/* for E-AC-3, determine frame exponent strategy */
|
||||
if (CONFIG_EAC3_ENCODER && s->eac3)
|
||||
ff_eac3_get_frame_exp_strategy(s);
|
||||
}
|
||||
|
||||
|
||||
@ -611,8 +630,12 @@ static void count_frame_bits_fixed(AC3EncodeContext *s)
|
||||
frame_bits += 2;
|
||||
frame_bits += 10;
|
||||
/* exponent strategy */
|
||||
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
|
||||
frame_bits += 2 * s->fbw_channels + s->lfe_on;
|
||||
if (s->use_frame_exp_strategy)
|
||||
frame_bits += 5 * s->fbw_channels;
|
||||
else
|
||||
frame_bits += AC3_MAX_BLOCKS * 2 * s->fbw_channels;
|
||||
if (s->lfe_on)
|
||||
frame_bits += AC3_MAX_BLOCKS;
|
||||
/* converter exponent strategy */
|
||||
frame_bits += s->fbw_channels * 5;
|
||||
/* snr offsets */
|
||||
@ -735,8 +758,14 @@ static void count_frame_bits(AC3EncodeContext *s)
|
||||
}
|
||||
}
|
||||
/* coupling exponent strategy */
|
||||
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
|
||||
frame_bits += 2 * s->blocks[blk].cpl_in_use;
|
||||
if (s->cpl_on) {
|
||||
if (s->use_frame_exp_strategy) {
|
||||
frame_bits += 5 * s->cpl_on;
|
||||
} else {
|
||||
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++)
|
||||
frame_bits += 2 * s->blocks[blk].cpl_in_use;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (opt->audio_production_info)
|
||||
frame_bits += 7;
|
||||
|
@ -217,6 +217,8 @@ typedef struct AC3EncodeContext {
|
||||
uint8_t *cpl_coord_mant_buffer;
|
||||
|
||||
uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies
|
||||
uint8_t frame_exp_strategy[AC3_MAX_CHANNELS]; ///< frame exp strategy index
|
||||
int use_frame_exp_strategy; ///< indicates use of frame exp strategy
|
||||
uint8_t exp_ref_block[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< reference blocks for EXP_REUSE
|
||||
uint8_t *ref_bap [AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< bit allocation pointers (bap)
|
||||
int ref_bap_set; ///< indicates if ref_bap pointers have been set
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define CONFIG_AC3ENC_FLOAT 1
|
||||
#include "ac3enc.h"
|
||||
#include "eac3enc.h"
|
||||
#include "eac3_data.h"
|
||||
|
||||
|
||||
#define AC3ENC_TYPE AC3ENC_TYPE_EAC3
|
||||
@ -35,6 +36,51 @@ static const AVClass eac3enc_class = { "E-AC-3 Encoder", av_default_item_name,
|
||||
eac3_options, LIBAVUTIL_VERSION_INT };
|
||||
|
||||
|
||||
/**
|
||||
* LUT for finding a matching frame exponent strategy index from a set of
|
||||
* exponent strategies for a single channel across all 6 blocks.
|
||||
*/
|
||||
static int8_t eac3_frame_expstr_index_tab[3][4][4][4][4][4];
|
||||
|
||||
|
||||
void ff_eac3_exponent_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(eac3_frame_expstr_index_tab, -1, sizeof(eac3_frame_expstr_index_tab));
|
||||
for (i = 0; i < 32; i++) {
|
||||
eac3_frame_expstr_index_tab[ff_eac3_frm_expstr[i][0]-1]
|
||||
[ff_eac3_frm_expstr[i][1]]
|
||||
[ff_eac3_frm_expstr[i][2]]
|
||||
[ff_eac3_frm_expstr[i][3]]
|
||||
[ff_eac3_frm_expstr[i][4]]
|
||||
[ff_eac3_frm_expstr[i][5]] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ff_eac3_get_frame_exp_strategy(AC3EncodeContext *s)
|
||||
{
|
||||
int ch;
|
||||
|
||||
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]
|
||||
[s->exp_strategy[ch][1]]
|
||||
[s->exp_strategy[ch][2]]
|
||||
[s->exp_strategy[ch][3]]
|
||||
[s->exp_strategy[ch][4]]
|
||||
[s->exp_strategy[ch][5]];
|
||||
if (expstr < 0) {
|
||||
s->use_frame_exp_strategy = 0;
|
||||
break;
|
||||
}
|
||||
s->frame_exp_strategy[ch] = expstr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ff_eac3_set_cpl_states(AC3EncodeContext *s)
|
||||
{
|
||||
int ch, blk;
|
||||
@ -98,7 +144,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
|
||||
put_bits(&s->pb, 1, 0); /* no additional bit stream info */
|
||||
|
||||
/* frame header */
|
||||
put_bits(&s->pb, 1, 1); /* exponent strategy syntax = each block */
|
||||
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 */
|
||||
@ -120,16 +166,25 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
|
||||
}
|
||||
}
|
||||
/* exponent strategy */
|
||||
if (s->use_frame_exp_strategy) {
|
||||
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 (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++)
|
||||
put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);
|
||||
}
|
||||
/* E-AC-3 to AC-3 converter exponent strategy (unfortunately not optional...) */
|
||||
for (ch = 1; ch <= s->fbw_channels; ch++)
|
||||
put_bits(&s->pb, 5, 0);
|
||||
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]);
|
||||
|
@ -29,6 +29,16 @@
|
||||
|
||||
#include "ac3enc.h"
|
||||
|
||||
/**
|
||||
* Initialize E-AC-3 exponent tables.
|
||||
*/
|
||||
void ff_eac3_exponent_init(void);
|
||||
|
||||
/**
|
||||
* Determine frame exponent strategy use and indices.
|
||||
*/
|
||||
void ff_eac3_get_frame_exp_strategy(AC3EncodeContext *s);
|
||||
|
||||
/**
|
||||
* Set coupling states.
|
||||
* This determines whether certain flags must be written to the bitstream or
|
||||
|
Loading…
Reference in New Issue
Block a user