LEVEL_MINUS_3DB, LEVEL_MINUS_4POINT5DB, LEVEL_MINUS_6DB, LEVEL_ZERO
};
+/* The first two options apply only to the AC-3 encoders;
+ * the rest is also valid for EAC-3. When modifying it,
+ * it might be necessary to adapt said offset in eac3enc.c. */
+#define OFFSET(param) offsetof(AC3EncodeContext, options.param)
+#define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
+const AVOption ff_ac3_enc_options[] = {
+/* AC-3 downmix levels */
+{"center_mixlev", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_4POINT5DB }, 0.0, 1.0, AC3ENC_PARAM},
+{"surround_mixlev", "Surround Mix Level", OFFSET(surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = LEVEL_MINUS_6DB }, 0.0, 1.0, AC3ENC_PARAM},
+/* audio production information */
+{"mixing_level", "Mixing Level", OFFSET(mixing_level), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 111, AC3ENC_PARAM},
+{"room_type", "Room Type", OFFSET(room_type), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_SMALL_ROOM, AC3ENC_PARAM, "room_type"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
+ {"large", "Large Room", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_LARGE_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
+ {"small", "Small Room", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_SMALL_ROOM }, INT_MIN, INT_MAX, AC3ENC_PARAM, "room_type"},
+/* Metadata Options */
+{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AC3ENC_PARAM},
+{"copyright", "Copyright Bit", OFFSET(copyright), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM},
+{"dialnorm", "Dialogue Level (dB)", OFFSET(dialogue_level), AV_OPT_TYPE_INT, {.i64 = -31 }, -31, -1, AC3ENC_PARAM},
+{"dsur_mode", "Dolby Surround Mode", OFFSET(dolby_surround_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dsur_mode"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
+ {"on", "Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
+ {"off", "Not Dolby Surround Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsur_mode"},
+{"original", "Original Bit Stream", OFFSET(original), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, 1, AC3ENC_PARAM},
+/* extended bitstream information */
+{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DOWNMIX_DPLII, AC3ENC_PARAM, "dmix_mode"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
+ {"ltrt", "Lt/Rt Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LTRT }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
+ {"loro", "Lo/Ro Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_LORO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
+ {"dplii", "Dolby Pro Logic II Downmix Preferred", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DOWNMIX_DPLII }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dmix_mode"},
+{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
+{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
+{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
+{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, AC3ENC_PARAM},
+{"dsurex_mode", "Dolby Surround EX Mode", OFFSET(dolby_surround_ex_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_DSUREX_DPLIIZ, AC3ENC_PARAM, "dsurex_mode"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
+ {"on", "Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
+ {"off", "Not Dolby Surround EX Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
+ {"dpliiz", "Dolby Pro Logic IIz-encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_DSUREX_DPLIIZ }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dsurex_mode"},
+{"dheadphone_mode", "Dolby Headphone Mode", OFFSET(dolby_headphone_mode), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_MODE_ON, AC3ENC_PARAM, "dheadphone_mode"},
+ {"notindicated", "Not Indicated (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_NOT_INDICATED }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
+ {"on", "Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_ON }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
+ {"off", "Not Dolby Headphone Encoded", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_MODE_OFF }, INT_MIN, INT_MAX, AC3ENC_PARAM, "dheadphone_mode"},
+{"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_NONE }, AC3ENC_OPT_NONE, AC3ENC_OPT_ADCONV_HDCD, AC3ENC_PARAM, "ad_conv_type"},
+ {"standard", "Standard (default)", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_ADCONV_STANDARD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
+ {"hdcd", "HDCD", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_ADCONV_HDCD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
+/* Other Encoding Options */
+{"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, AC3ENC_PARAM},
+{"channel_coupling", "Channel Coupling", OFFSET(channel_coupling), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, AC3ENC_OPT_ON, AC3ENC_PARAM, "channel_coupling"},
+ {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"},
+{"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), AV_OPT_TYPE_INT, {.i64 = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, 15, AC3ENC_PARAM, "cpl_start_band"},
+ {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"},
+{NULL}
+};
+
+const AVCodecDefault ff_ac3_enc_defaults[] = {
+ { "b", "0" },
+ { NULL }
+};
/**
* LUT for number of exponent groups.
0
};
+/**
+ * Table to remap channels from SMPTE order to AC-3 order.
+ * [channel_mode][lfe][ch]
+ */
+static const uint8_t ac3_enc_channel_map[8][2][6] = {
+ COMMON_CHANNEL_MAP
+ { { 0, 1, 2, 3, }, { 0, 1, 3, 4, 2, } },
+ { { 0, 2, 1, 3, 4, }, { 0, 2, 1, 4, 5, 3 } },
+};
/**
* LUT to select the bandwidth code based on the bit rate, sample rate, and
if (s->eac3)
frame_bits++;
+ /* coupling strategy exists: cplstre */
+ if (!s->eac3)
+ frame_bits++;
+
if (!s->eac3) {
/* exponent strategy */
frame_bits += 2 * s->fbw_channels;
frame_bits += 2 + 2 + 2 + 2 + 3;
}
- /* converter snr offset */
- if (s->eac3)
- frame_bits++;
+ /* snroffste for AC-3, convsnroffste for E-AC-3 */
+ frame_bits++;
if (!s->eac3) {
/* delta bit allocation */
/* coupling exponent strategy */
if (s->cpl_on) {
if (s->use_frame_exp_strategy) {
- frame_bits += 5 * s->cpl_on;
+ frame_bits += 5;
} else {
for (blk = 0; blk < s->num_blocks; blk++)
frame_bits += 2 * s->blocks[blk].cpl_in_use;
AC3Block *block = &s->blocks[blk];
/* coupling strategy */
- if (!s->eac3)
- frame_bits++;
if (block->new_cpl_strategy) {
if (!s->eac3)
frame_bits++;
/* snr offsets and fast gain codes */
if (!s->eac3) {
- frame_bits++;
if (block->new_snr_offsets)
frame_bits += 6 + (s->channels + block->cpl_in_use) * (4 + 3);
}
int c = fixed_coef[i];
int e = exp[i];
int v = bap[i];
- if (v)
switch (v) {
+ case 0:
+ break;
case 1:
v = sym_quant(c, e, 3);
switch (s->mant1_cnt) {
put_bits(&s->pb, 9, 0); /* xbsi2 and encinfo : reserved */
}
} else {
- put_bits(&s->pb, 1, 0); /* no time code 1 */
- put_bits(&s->pb, 1, 0); /* no time code 2 */
+ put_bits(&s->pb, 1, 0); /* no time code 1 */
+ put_bits(&s->pb, 1, 0); /* no time code 2 */
}
put_bits(&s->pb, 1, 0); /* no additional bit stream info */
}
/* compute crc2 */
crc2_partial = av_crc(crc_ctx, 0, frame + 2, s->frame_size - 5);
} else {
- /* compute crc1 */
- /* this is not so easy because it is at the beginning of the data... */
- crc1 = av_bswap16(av_crc(crc_ctx, 0, frame + 4, frame_size_58 - 4));
- crc_inv = s->crc_inv[s->frame_size > s->frame_size_min];
- crc1 = mul_poly(crc_inv, crc1, CRC16_POLY);
- AV_WB16(frame + 2, crc1);
+ /* compute crc1 */
+ /* this is not so easy because it is at the beginning of the data... */
+ crc1 = av_bswap16(av_crc(crc_ctx, 0, frame + 4, frame_size_58 - 4));
+ crc_inv = s->crc_inv[s->frame_size > s->frame_size_min];
+ crc1 = mul_poly(crc_inv, crc1, CRC16_POLY);
+ AV_WB16(frame + 2, crc1);
- /* compute crc2 */
- crc2_partial = av_crc(crc_ctx, 0, frame + frame_size_58,
- s->frame_size - frame_size_58 - 3);
+ /* compute crc2 */
+ crc2_partial = av_crc(crc_ctx, 0, frame + frame_size_58,
+ s->frame_size - frame_size_58 - 3);
}
crc2 = av_crc(crc_ctx, crc2_partial, frame + s->frame_size - 3, 1);
/* ensure crc2 does not match sync word by flipping crcrsv bit if needed */
{
int blk;
- init_put_bits(&s->pb, frame, AC3_MAX_CODED_FRAME_SIZE);
+ init_put_bits(&s->pb, frame, s->frame_size);
s->output_frame_header(s);
ac3_quantize_mantissas(s);
- if ((ret = ff_alloc_packet2(avctx, avpkt, s->frame_size, 0)) < 0)
+ ret = ff_alloc_packet2(avctx, avpkt, s->frame_size, s->frame_size);
+ if (ret < 0)
return ret;
ac3_output_frame(s, avpkt->data);
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);
+ 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);
+ surmixlev_options, SURMIXLEV_NUM_OPTIONS, 1, 0,
+ &s->surround_mix_level);
}
}
av_freep(&s->mdct_window);
av_freep(&s->windowed_samples);
if (s->planar_samples)
- for (ch = 0; ch < s->channels; ch++)
- av_freep(&s->planar_samples[ch]);
+ for (ch = 0; ch < s->channels; ch++)
+ av_freep(&s->planar_samples[ch]);
av_freep(&s->planar_samples);
av_freep(&s->bap_buffer);
av_freep(&s->bap1_buffer);
s->has_center = (s->channel_mode & 0x01) && s->channel_mode != AC3_CHMODE_MONO;
s->has_surround = s->channel_mode & 0x04;
- s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe_on];
+ s->channel_map = ac3_enc_channel_map[s->channel_mode][s->lfe_on];
*channel_layout = ch_layout;
if (s->lfe_on)
*channel_layout |= AV_CH_LOW_FREQUENCY;
}
if (CONFIG_EAC3_ENCODER && s->eac3) {
- static AVOnce init_static_once = AV_ONCE_INIT;
- ff_thread_once(&init_static_once, ff_eac3_exponent_init);
+ static AVOnce init_static_once_eac3 = AV_ONCE_INIT;
+ ff_thread_once(&init_static_once_eac3, ff_eac3_exponent_init);
s->output_frame_header = ff_eac3_output_frame_header;
} else
s->output_frame_header = ac3_output_frame_header;