}
+/**
+ * Count exponent bits based on bandwidth, coupling, and exponent strategies.
+ */
+static int count_exponent_bits(AC3EncodeContext *s)
+{
+ int blk, ch;
+ int nb_groups, bit_count;
+
+ bit_count = 0;
+ for (blk = 0; blk < s->num_blocks; blk++) {
+ AC3Block *block = &s->blocks[blk];
+ for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
+ int exp_strategy = s->exp_strategy[ch][blk];
+ int cpl = (ch == CPL_CH);
+ int nb_coefs = block->end_freq[ch] - s->start_freq[ch];
+
+ if (exp_strategy == EXP_REUSE)
+ continue;
+
+ nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_coefs];
+ bit_count += 4 + (nb_groups * 7);
+ }
+ }
+
+ return bit_count;
+}
+
+
/**
* Group exponents.
* 3 delta-encoded exponents are in each 7-bit group. The number of groups
* varies depending on exponent strategy and bandwidth.
*/
-static void group_exponents(AC3EncodeContext *s)
+void ff_ac3_group_exponents(AC3EncodeContext *s)
{
int blk, ch, i, cpl;
- int group_size, nb_groups, bit_count;
+ int group_size, nb_groups;
uint8_t *p;
int delta0, delta1, delta2;
int exp0, exp1;
- bit_count = 0;
for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk];
for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
cpl = (ch == CPL_CH);
group_size = exp_strategy + (exp_strategy == EXP_D45);
nb_groups = exponent_group_tab[cpl][exp_strategy-1][block->end_freq[ch]-s->start_freq[ch]];
- bit_count += 4 + (nb_groups * 7);
p = block->exp[ch] + s->start_freq[ch] - cpl;
/* DC exponent */
}
}
}
-
- s->exponent_bits = bit_count;
}
encode_exponents(s);
- group_exponents(s);
-
emms_c();
}
/* header */
if (s->eac3) {
+ if (opt->eac3_mixing_metadata) {
+ if (s->channel_mode > AC3_CHMODE_STEREO)
+ frame_bits += 2;
+ if (s->has_center)
+ frame_bits += 6;
+ if (s->has_surround)
+ frame_bits += 6;
+ frame_bits += s->lfe_on;
+ frame_bits += 1 + 1 + 2;
+ if (s->channel_mode < AC3_CHMODE_STEREO)
+ frame_bits++;
+ frame_bits++;
+ }
+ if (opt->eac3_info_metadata) {
+ frame_bits += 3 + 1 + 1;
+ if (s->channel_mode == AC3_CHMODE_STEREO)
+ frame_bits += 2 + 2;
+ if (s->channel_mode >= AC3_CHMODE_2F2R)
+ frame_bits += 2;
+ frame_bits++;
+ if (opt->audio_production_info)
+ frame_bits += 5 + 2 + 1;
+ frame_bits++;
+ }
/* coupling */
if (s->channel_mode > AC3_CHMODE_MONO) {
frame_bits++;
if (block->cpl_in_use) {
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) {
- if (!s->eac3 || block->new_cpl_coords != 2)
+ if (!s->eac3 || block->new_cpl_coords[ch] != 2)
frame_bits++;
- if (block->new_cpl_coords) {
+ if (block->new_cpl_coords[ch]) {
frame_bits += 2;
frame_bits += (4 + 4) * s->num_cpl_bands;
}
{
count_frame_bits(s);
+ s->exponent_bits = count_exponent_bits(s);
+
bit_alloc_masking(s);
return cbr_bit_allocation(s);
if (block->cpl_in_use) {
for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) {
- if (!s->eac3 || block->new_cpl_coords != 2)
- put_bits(&s->pb, 1, block->new_cpl_coords);
- if (block->new_cpl_coords) {
+ if (!s->eac3 || block->new_cpl_coords[ch] != 2)
+ put_bits(&s->pb, 1, block->new_cpl_coords[ch]);
+ if (block->new_cpl_coords[ch]) {
put_bits(&s->pb, 2, block->cpl_master_exp[ch]);
for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]);
if (opt->audio_production_info) {
av_dlog(avctx, "mixing_level: %ddB\n", opt->mixing_level);
switch (opt->room_type) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "large", 32); break;
- case 2: av_strlcpy(strbuf, "small", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_LARGE_ROOM: av_strlcpy(strbuf, "large", 32); break;
+ case AC3ENC_OPT_SMALL_ROOM: av_strlcpy(strbuf, "small", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->room_type);
}
av_dlog(avctx, "room_type: %s\n", strbuf);
av_dlog(avctx, "dialnorm: %ddB\n", opt->dialogue_level);
if (s->channel_mode == AC3_CHMODE_STEREO) {
switch (opt->dolby_surround_mode) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "on", 32); break;
- case 2: av_strlcpy(strbuf, "off", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break;
+ case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_surround_mode);
}
av_dlog(avctx, "dsur_mode: %s\n", strbuf);
if (s->bitstream_id == 6) {
if (opt->extended_bsi_1) {
switch (opt->preferred_stereo_downmix) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "ltrt", 32); break;
- case 2: av_strlcpy(strbuf, "loro", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_DOWNMIX_LTRT: av_strlcpy(strbuf, "ltrt", 32); break;
+ case AC3ENC_OPT_DOWNMIX_LORO: av_strlcpy(strbuf, "loro", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->preferred_stereo_downmix);
}
av_dlog(avctx, "dmix_mode: %s\n", strbuf);
}
if (opt->extended_bsi_2) {
switch (opt->dolby_surround_ex_mode) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "on", 32); break;
- case 2: av_strlcpy(strbuf, "off", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break;
+ case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_surround_ex_mode);
}
av_dlog(avctx, "dsurex_mode: %s\n", strbuf);
switch (opt->dolby_headphone_mode) {
- case 0: av_strlcpy(strbuf, "notindicated", 32); break;
- case 1: av_strlcpy(strbuf, "on", 32); break;
- case 2: av_strlcpy(strbuf, "off", 32); break;
+ case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 32); break;
+ case AC3ENC_OPT_MODE_ON: av_strlcpy(strbuf, "on", 32); break;
+ case AC3ENC_OPT_MODE_OFF: av_strlcpy(strbuf, "off", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->dolby_headphone_mode);
}
av_dlog(avctx, "dheadphone_mode: %s\n", strbuf);
switch (opt->ad_converter_type) {
- case 0: av_strlcpy(strbuf, "standard", 32); break;
- case 1: av_strlcpy(strbuf, "hdcd", 32); break;
+ case AC3ENC_OPT_ADCONV_STANDARD: av_strlcpy(strbuf, "standard", 32); break;
+ case AC3ENC_OPT_ADCONV_HDCD: av_strlcpy(strbuf, "hdcd", 32); break;
default: snprintf(strbuf, 32, "ERROR (%d)", opt->ad_converter_type);
}
av_dlog(avctx, "ad_conv_type: %s\n", strbuf);
AVCodecContext *avctx = s->avctx;
AC3EncOptions *opt = &s->options;
- /* validate mixing levels */
- if (s->has_center) {
- validate_mix_level(avctx, "center_mix_level", &opt->center_mix_level,
- cmixlev_options, CMIXLEV_NUM_OPTIONS, 1, 0,
- &s->center_mix_level);
+ opt->audio_production_info = 0;
+ opt->extended_bsi_1 = 0;
+ opt->extended_bsi_2 = 0;
+ opt->eac3_mixing_metadata = 0;
+ opt->eac3_info_metadata = 0;
+
+ /* determine mixing metadata / xbsi1 use */
+ if (s->channel_mode > AC3_CHMODE_STEREO && opt->preferred_stereo_downmix != AC3ENC_OPT_NONE) {
+ opt->extended_bsi_1 = 1;
+ opt->eac3_mixing_metadata = 1;
+ }
+ if (s->has_center &&
+ (opt->ltrt_center_mix_level >= 0 || opt->loro_center_mix_level >= 0)) {
+ opt->extended_bsi_1 = 1;
+ opt->eac3_mixing_metadata = 1;
+ }
+ if (s->has_surround &&
+ (opt->ltrt_surround_mix_level >= 0 || opt->loro_surround_mix_level >= 0)) {
+ opt->extended_bsi_1 = 1;
+ opt->eac3_mixing_metadata = 1;
+ }
+
+ if (s->eac3) {
+ /* determine info metadata use */
+ if (avctx->audio_service_type != AV_AUDIO_SERVICE_TYPE_MAIN)
+ opt->eac3_info_metadata = 1;
+ if (opt->copyright != AC3ENC_OPT_NONE || opt->original != AC3ENC_OPT_NONE)
+ opt->eac3_info_metadata = 1;
+ if (s->channel_mode == AC3_CHMODE_STEREO &&
+ (opt->dolby_headphone_mode != AC3ENC_OPT_NONE || opt->dolby_surround_mode != AC3ENC_OPT_NONE))
+ opt->eac3_info_metadata = 1;
+ if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode != AC3ENC_OPT_NONE)
+ opt->eac3_info_metadata = 1;
+ if (opt->mixing_level != AC3ENC_OPT_NONE || opt->room_type != AC3ENC_OPT_NONE ||
+ opt->ad_converter_type != AC3ENC_OPT_NONE) {
+ opt->audio_production_info = 1;
+ opt->eac3_info_metadata = 1;
+ }
+ } else {
+ /* determine audio production info use */
+ if (opt->mixing_level != AC3ENC_OPT_NONE || opt->room_type != AC3ENC_OPT_NONE)
+ opt->audio_production_info = 1;
+
+ /* determine xbsi2 use */
+ if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode != AC3ENC_OPT_NONE)
+ opt->extended_bsi_2 = 1;
+ if (s->channel_mode == AC3_CHMODE_STEREO && opt->dolby_headphone_mode != AC3ENC_OPT_NONE)
+ opt->extended_bsi_2 = 1;
+ if (opt->ad_converter_type != AC3ENC_OPT_NONE)
+ opt->extended_bsi_2 = 1;
+ }
+
+ /* validate AC-3 mixing levels */
+ if (!s->eac3) {
+ if (s->has_center) {
+ validate_mix_level(avctx, "center_mix_level", &opt->center_mix_level,
+ cmixlev_options, CMIXLEV_NUM_OPTIONS, 1, 0,
+ &s->center_mix_level);
+ }
+ if (s->has_surround) {
+ validate_mix_level(avctx, "surround_mix_level", &opt->surround_mix_level,
+ surmixlev_options, SURMIXLEV_NUM_OPTIONS, 1, 0,
+ &s->surround_mix_level);
+ }
+ }
+
+ /* validate extended bsi 1 / mixing metadata */
+ if (opt->extended_bsi_1 || opt->eac3_mixing_metadata) {
+ /* default preferred stereo downmix */
+ if (opt->preferred_stereo_downmix == AC3ENC_OPT_NONE)
+ opt->preferred_stereo_downmix = AC3ENC_OPT_NOT_INDICATED;
+ if (!s->eac3 || s->has_center) {
+ /* validate Lt/Rt center mix level */
+ validate_mix_level(avctx, "ltrt_center_mix_level",
+ &opt->ltrt_center_mix_level, extmixlev_options,
+ EXTMIXLEV_NUM_OPTIONS, 5, 0,
+ &s->ltrt_center_mix_level);
+ /* validate Lo/Ro center mix level */
+ validate_mix_level(avctx, "loro_center_mix_level",
+ &opt->loro_center_mix_level, extmixlev_options,
+ EXTMIXLEV_NUM_OPTIONS, 5, 0,
+ &s->loro_center_mix_level);
+ }
+ if (!s->eac3 || s->has_surround) {
+ /* validate Lt/Rt surround mix level */
+ validate_mix_level(avctx, "ltrt_surround_mix_level",
+ &opt->ltrt_surround_mix_level, extmixlev_options,
+ EXTMIXLEV_NUM_OPTIONS, 6, 3,
+ &s->ltrt_surround_mix_level);
+ /* validate Lo/Ro surround mix level */
+ validate_mix_level(avctx, "loro_surround_mix_level",
+ &opt->loro_surround_mix_level, extmixlev_options,
+ EXTMIXLEV_NUM_OPTIONS, 6, 3,
+ &s->loro_surround_mix_level);
+ }
+ }
+
+ /* validate audio service type / channels combination */
+ if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE &&
+ avctx->channels == 1) ||
+ ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY ||
+ avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY ||
+ avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER)
+ && avctx->channels > 1)) {
+ av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the "
+ "specified number of channels\n");
+ return AVERROR(EINVAL);
+ }
+
+ /* validate extended bsi 2 / info metadata */
+ if (opt->extended_bsi_2 || opt->eac3_info_metadata) {
+ /* default dolby headphone mode */
+ if (opt->dolby_headphone_mode == AC3ENC_OPT_NONE)
+ opt->dolby_headphone_mode = AC3ENC_OPT_NOT_INDICATED;
+ /* default dolby surround ex mode */
+ if (opt->dolby_surround_ex_mode == AC3ENC_OPT_NONE)
+ opt->dolby_surround_ex_mode = AC3ENC_OPT_NOT_INDICATED;
+ /* default A/D converter type */
+ if (opt->ad_converter_type == AC3ENC_OPT_NONE)
+ opt->ad_converter_type = AC3ENC_OPT_ADCONV_STANDARD;
}
- if (s->has_surround) {
- validate_mix_level(avctx, "surround_mix_level", &opt->surround_mix_level,
- surmixlev_options, SURMIXLEV_NUM_OPTIONS, 1, 0,
- &s->surround_mix_level);
+
+ /* copyright & original defaults */
+ if (!s->eac3 || opt->eac3_info_metadata) {
+ /* default copyright */
+ if (opt->copyright == AC3ENC_OPT_NONE)
+ opt->copyright = AC3ENC_OPT_OFF;
+ /* default original */
+ if (opt->original == AC3ENC_OPT_NONE)
+ opt->original = AC3ENC_OPT_ON;
}
- /* set audio production info flag */
- if (opt->mixing_level >= 0 || opt->room_type >= 0) {
- if (opt->mixing_level < 0) {
+ /* dolby surround mode default */
+ if (!s->eac3 || opt->eac3_info_metadata) {
+ if (opt->dolby_surround_mode == AC3ENC_OPT_NONE)
+ opt->dolby_surround_mode = AC3ENC_OPT_NOT_INDICATED;
+ }
+
+ /* validate audio production info */
+ if (opt->audio_production_info) {
+ if (opt->mixing_level == AC3ENC_OPT_NONE) {
av_log(avctx, AV_LOG_ERROR, "mixing_level must be set if "
"room_type is set\n");
return AVERROR(EINVAL);
return AVERROR(EINVAL);
}
/* default room type */
- if (opt->room_type < 0)
- opt->room_type = 0;
- opt->audio_production_info = 1;
- } else {
- opt->audio_production_info = 0;
- }
-
- /* set extended bsi 1 flag */
- if ((s->has_center || s->has_surround) &&
- (opt->preferred_stereo_downmix >= 0 ||
- opt->ltrt_center_mix_level >= 0 ||
- opt->ltrt_surround_mix_level >= 0 ||
- opt->loro_center_mix_level >= 0 ||
- opt->loro_surround_mix_level >= 0)) {
- /* default preferred stereo downmix */
- if (opt->preferred_stereo_downmix < 0)
- opt->preferred_stereo_downmix = 0;
- /* validate Lt/Rt center mix level */
- validate_mix_level(avctx, "ltrt_center_mix_level",
- &opt->ltrt_center_mix_level, extmixlev_options,
- EXTMIXLEV_NUM_OPTIONS, 5, 0,
- &s->ltrt_center_mix_level);
- /* validate Lt/Rt surround mix level */
- validate_mix_level(avctx, "ltrt_surround_mix_level",
- &opt->ltrt_surround_mix_level, extmixlev_options,
- EXTMIXLEV_NUM_OPTIONS, 6, 3,
- &s->ltrt_surround_mix_level);
- /* validate Lo/Ro center mix level */
- validate_mix_level(avctx, "loro_center_mix_level",
- &opt->loro_center_mix_level, extmixlev_options,
- EXTMIXLEV_NUM_OPTIONS, 5, 0,
- &s->loro_center_mix_level);
- /* validate Lo/Ro surround mix level */
- validate_mix_level(avctx, "loro_surround_mix_level",
- &opt->loro_surround_mix_level, extmixlev_options,
- EXTMIXLEV_NUM_OPTIONS, 6, 3,
- &s->loro_surround_mix_level);
- opt->extended_bsi_1 = 1;
- } else {
- opt->extended_bsi_1 = 0;
- }
-
- /* set extended bsi 2 flag */
- if (opt->dolby_surround_ex_mode >= 0 ||
- opt->dolby_headphone_mode >= 0 ||
- opt->ad_converter_type >= 0) {
- /* default dolby surround ex mode */
- if (opt->dolby_surround_ex_mode < 0)
- opt->dolby_surround_ex_mode = 0;
- /* default dolby headphone mode */
- if (opt->dolby_headphone_mode < 0)
- opt->dolby_headphone_mode = 0;
- /* default A/D converter type */
- if (opt->ad_converter_type < 0)
- opt->ad_converter_type = 0;
- opt->extended_bsi_2 = 1;
- } else {
- opt->extended_bsi_2 = 0;
+ if (opt->room_type == AC3ENC_OPT_NONE)
+ opt->room_type = AC3ENC_OPT_NOT_INDICATED;
}
/* set bitstream id for alternate bitstream syntax */
- if (opt->extended_bsi_1 || opt->extended_bsi_2) {
+ if (!s->eac3 && (opt->extended_bsi_1 || opt->extended_bsi_2)) {
if (s->bitstream_id > 8 && s->bitstream_id < 11) {
static int warn_once = 1;
if (warn_once) {
if (s->cutoff > (s->sample_rate >> 1))
s->cutoff = s->sample_rate >> 1;
- /* validate audio service type / channels combination */
- if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE &&
- avctx->channels == 1) ||
- ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY ||
- avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY ||
- avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER)
- && avctx->channels > 1)) {
- av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the "
- "specified number of channels\n");
- return AVERROR(EINVAL);
- }
-
- if (!s->eac3) {
- ret = ff_ac3_validate_metadata(s);
- if (ret)
- return ret;
- }
+ ret = ff_ac3_validate_metadata(s);
+ if (ret)
+ return ret;
s->rematrixing_enabled = s->options.stereo_rematrixing &&
(s->channel_mode == AC3_CHMODE_STEREO);
/* initialize coupling strategy */
if (s->cpl_enabled) {
- if (s->options.cpl_start >= 0) {
+ if (s->options.cpl_start != AC3ENC_OPT_AUTO) {
cpl_start = s->options.cpl_start;
} else {
cpl_start = ac3_coupling_start_tab[s->channel_mode-2][s->bit_alloc.sr_code][s->frame_size_code/2];
- if (cpl_start < 0)
- s->cpl_enabled = 0;
+ if (cpl_start < 0) {
+ if (s->options.channel_coupling == AC3ENC_OPT_AUTO)
+ s->cpl_enabled = 0;
+ else
+ cpl_start = 15;
+ }
}
}
if (s->cpl_enabled) {