/**
* List of supported channel layouts.
*/
-const int64_t ff_ac3_channel_layouts[19] = {
+const uint64_t ff_ac3_channel_layouts[19] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_2_1,
/**
* Adjust the frame size to make the average bit rate match the target bit rate.
* This is only needed for 11025, 22050, and 44100 sample rates or any E-AC-3.
+ *
+ * @param s AC-3 encoder private context
*/
void ff_ac3_adjust_frame_size(AC3EncodeContext *s)
{
}
+/**
+ * Set the initial coupling strategy parameters prior to coupling analysis.
+ *
+ * @param s AC-3 encoder private context
+ */
void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
{
int blk, ch;
/**
* Apply stereo rematrixing to coefficients based on rematrixing flags.
+ *
+ * @param s AC-3 encoder private context
*/
void ff_ac3_apply_rematrixing(AC3EncodeContext *s)
{
}
-/**
+/*
* Initialize exponent tables.
*/
static av_cold void exponent_init(AC3EncodeContext *s)
}
-/**
+/*
* Extract exponents from the MDCT coefficients.
*/
static void extract_exponents(AC3EncodeContext *s)
{ EXP_D45, EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15 }
};
-/**
+/*
* Calculate exponent strategies for all channels.
* Array arrangement is reversed to simplify the per-channel calculation.
*/
/**
* Update the exponents so that they are the ones the decoder will decode.
+ *
+ * @param[in,out] exp array of exponents for 1 block in 1 channel
+ * @param nb_exps number of exponents in active bandwidth
+ * @param exp_strategy exponent strategy for the block
+ * @param cpl indicates if the block is in the coupling channel
*/
static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy,
int cpl)
}
-/**
+/*
* Encode exponents from original extracted form to what the decoder will see.
* This copies and groups exponents based on exponent strategy and reduces
* deltas between adjacent exponent groups so that they can be differentially
}
-/**
+/*
* Count exponent bits based on bandwidth, coupling, and exponent strategies.
*/
static int count_exponent_bits(AC3EncodeContext *s)
* Group exponents.
* 3 delta-encoded exponents are in each 7-bit group. The number of groups
* varies depending on exponent strategy and bandwidth.
+ *
+ * @param s AC-3 encoder private context
*/
void ff_ac3_group_exponents(AC3EncodeContext *s)
{
* Calculate final exponents from the supplied MDCT coefficients and exponent shift.
* Extract exponents from MDCT coefficients, calculate exponent strategies,
* and encode final exponents.
+ *
+ * @param s AC-3 encoder private context
*/
void ff_ac3_process_exponents(AC3EncodeContext *s)
{
}
-/**
+/*
* Count frame bits that are based solely on fixed parameters.
* This only has to be run once when the encoder is initialized.
*/
}
-/**
+/*
* Initialize bit allocation.
* Set default parameter codes and calculate parameter values.
*/
}
-/**
+/*
* Count the bits used to encode the frame, minus exponents and mantissas.
* Bits based on fixed parameters have already been counted, so now we just
* have to add the bits based on parameters that change during encoding.
}
-/**
+/*
* Calculate masking curve based on the final exponents.
* Also calculate the power spectral densities to use in future calculations.
*/
}
-/**
+/*
* Ensure that bap for each block and channel point to the current bap_buffer.
* They may have been switched during the bit allocation search.
*/
* Initialize mantissa counts.
* These are set so that they are padded to the next whole group size when bits
* are counted in compute_mantissa_size.
+ *
+ * @param[in,out] mant_cnt running counts for each bap value for each block
*/
static void count_mantissa_bits_init(uint16_t mant_cnt[AC3_MAX_BLOCKS][16])
{
/**
* Update mantissa bit counts for all blocks in 1 channel in a given bandwidth
* range.
+ *
+ * @param s AC-3 encoder private context
+ * @param ch channel index
+ * @param[in,out] mant_cnt running counts for each bap value for each block
+ * @param start starting coefficient bin
+ * @param end ending coefficient bin
*/
static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch,
uint16_t mant_cnt[AC3_MAX_BLOCKS][16],
}
-/**
+/*
* Count the number of mantissa bits in the frame based on the bap values.
*/
static int count_mantissa_bits(AC3EncodeContext *s)
* Run the bit allocation with a given SNR offset.
* This calculates the bit allocation pointers that will be used to determine
* the quantization of each mantissa.
+ *
+ * @param s AC-3 encoder private context
+ * @param snr_offset SNR offset, 0 to 1023
* @return the number of bits needed for mantissas if the given SNR offset is
* is used.
*/
}
-/**
+/*
* Constant bitrate bit allocation search.
* Find the largest SNR offset that will allow data to fit in the frame.
*/
}
-/**
+/*
* Perform bit allocation search.
* Finds the SNR offset value that maximizes quality and fits in the specified
* frame size. Output is the SNR offset and a set of bit allocation pointers
/**
* Symmetric quantization on 'levels' levels.
+ *
+ * @param c unquantized coefficient
+ * @param e exponent
+ * @param levels number of quantization levels
+ * @return quantized coefficient
*/
static inline int sym_quant(int c, int e, int levels)
{
/**
* Asymmetric quantization on 2^qbits levels.
+ *
+ * @param c unquantized coefficient
+ * @param e exponent
+ * @param qbits number of quantization bits
+ * @return quantized coefficient
*/
static inline int asym_quant(int c, int e, int qbits)
{
/**
* Quantize a set of mantissas for a single channel in a single block.
+ *
+ * @param s Mantissa count context
+ * @param fixed_coef unquantized fixed-point coefficients
+ * @param exp exponents
+ * @param bap bit allocation pointer indices
+ * @param[out] qmant quantized coefficients
+ * @param start_freq starting coefficient bin
+ * @param end_freq ending coefficient bin
*/
static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef,
uint8_t *exp, uint8_t *bap,
/**
* Quantize mantissas using coefficients, exponents, and bit allocation pointers.
+ *
+ * @param s AC-3 encoder private context
*/
void ff_ac3_quantize_mantissas(AC3EncodeContext *s)
{
}
-/**
+/*
* Write the AC-3 frame header to the output bitstream.
*/
static void ac3_output_frame_header(AC3EncodeContext *s)
}
-/**
+/*
* Write one audio block to the output bitstream.
*/
static void output_audio_block(AC3EncodeContext *s, int blk)
{
- int ch, i, baie, bnd, got_cpl;
- int av_uninit(ch0);
+ int ch, i, baie, bnd, got_cpl, ch0;
AC3Block *block = &s->blocks[blk];
/* block switching */
}
-/**
+/*
* Fill the end of the frame with 0's and compute the two CRCs.
*/
static void output_frame_end(AC3EncodeContext *s)
/**
* Write the frame to the output bitstream.
+ *
+ * @param s AC-3 encoder private context
+ * @param frame output data buffer
*/
void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame)
{
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);
/**
* Validate metadata options as set by AVOption system.
* These values can optionally be changed per-frame.
+ *
+ * @param s AC-3 encoder private context
*/
int ff_ac3_validate_metadata(AC3EncodeContext *s)
{
opt->eac3_info_metadata = 0;
/* determine mixing metadata / xbsi1 use */
- if (s->channel_mode > AC3_CHMODE_STEREO && opt->preferred_stereo_downmix >= 0) {
+ if (s->channel_mode > AC3_CHMODE_STEREO && opt->preferred_stereo_downmix != AC3ENC_OPT_NONE) {
opt->extended_bsi_1 = 1;
opt->eac3_mixing_metadata = 1;
}
/* determine info metadata use */
if (avctx->audio_service_type != AV_AUDIO_SERVICE_TYPE_MAIN)
opt->eac3_info_metadata = 1;
- if (opt->copyright >= 0 || opt->original >= 0)
+ 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 >= 0 || opt->dolby_surround_mode >= 0))
+ (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 >= 0)
+ if (s->channel_mode >= AC3_CHMODE_2F2R && opt->dolby_surround_ex_mode != AC3ENC_OPT_NONE)
opt->eac3_info_metadata = 1;
- if (opt->mixing_level >= 0 || opt->room_type >= 0 || opt->ad_converter_type >= 0) {
+ 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 >= 0 || opt->room_type >= 0)
+ 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 >= 0)
+ 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 >= 0)
+ if (s->channel_mode == AC3_CHMODE_STEREO && opt->dolby_headphone_mode != AC3ENC_OPT_NONE)
opt->extended_bsi_2 = 1;
- if (opt->ad_converter_type >= 0)
+ if (opt->ad_converter_type != AC3ENC_OPT_NONE)
opt->extended_bsi_2 = 1;
}
/* validate extended bsi 1 / mixing metadata */
if (opt->extended_bsi_1 || opt->eac3_mixing_metadata) {
/* default preferred stereo downmix */
- if (opt->preferred_stereo_downmix < 0)
- opt->preferred_stereo_downmix = 0;
+ 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",
/* validate extended bsi 2 / info metadata */
if (opt->extended_bsi_2 || opt->eac3_info_metadata) {
/* default dolby headphone mode */
- if (opt->dolby_headphone_mode < 0)
- opt->dolby_headphone_mode = 0;
+ 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 < 0)
- opt->dolby_surround_ex_mode = 0;
+ 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 < 0)
- opt->ad_converter_type = 0;
+ if (opt->ad_converter_type == AC3ENC_OPT_NONE)
+ opt->ad_converter_type = AC3ENC_OPT_ADCONV_STANDARD;
}
/* copyright & original defaults */
if (!s->eac3 || opt->eac3_info_metadata) {
/* default copyright */
- if (opt->copyright < 0)
- opt->copyright = 0;
+ if (opt->copyright == AC3ENC_OPT_NONE)
+ opt->copyright = AC3ENC_OPT_OFF;
/* default original */
- if (opt->original < 0)
- opt->original = 1;
+ if (opt->original == AC3ENC_OPT_NONE)
+ opt->original = AC3ENC_OPT_ON;
}
/* dolby surround mode default */
if (!s->eac3 || opt->eac3_info_metadata) {
- if (opt->dolby_surround_mode < 0)
- opt->dolby_surround_mode = 0;
+ 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 < 0) {
+ 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;
+ if (opt->room_type == AC3ENC_OPT_NONE)
+ opt->room_type = AC3ENC_OPT_NOT_INDICATED;
}
/* set bitstream id for alternate bitstream syntax */
/**
* Finalize encoding and free any memory allocated by the encoder.
+ *
+ * @param avctx Codec context
*/
av_cold int ff_ac3_encode_close(AVCodecContext *avctx)
{
s->mdct_end(s);
+#if FF_API_OLD_ENCODE_AUDIO
av_freep(&avctx->coded_frame);
+#endif
return 0;
}
-/**
+/*
* Set channel information during initialization.
*/
static av_cold int set_channel_info(AC3EncodeContext *s, int channels,
- int64_t *channel_layout)
+ uint64_t *channel_layout)
{
int ch_layout;
if (channels < 1 || channels > AC3_MAX_CHANNELS)
return AVERROR(EINVAL);
- if ((uint64_t)*channel_layout > 0x7FF)
+ if (*channel_layout > 0x7FF)
return AVERROR(EINVAL);
ch_layout = *channel_layout;
if (!ch_layout)
- ch_layout = avcodec_guess_channel_layout(channels, CODEC_ID_AC3, NULL);
+ ch_layout = av_get_default_channel_layout(channels);
s->lfe_on = !!(ch_layout & AV_CH_LOW_FREQUENCY);
s->channels = channels;
s->bit_alloc.sr_code = i % 3;
s->bitstream_id = s->eac3 ? 16 : 8 + s->bit_alloc.sr_shift;
+ /* select a default bit rate if not set by the user */
+ if (!avctx->bit_rate) {
+ switch (s->fbw_channels) {
+ case 1: avctx->bit_rate = 96000; break;
+ case 2: avctx->bit_rate = 192000; break;
+ case 3: avctx->bit_rate = 320000; break;
+ case 4: avctx->bit_rate = 384000; break;
+ case 5: avctx->bit_rate = 448000; break;
+ }
+ }
+
/* validate bit rate */
if (s->eac3) {
int max_br, min_br, wpf, min_br_dist, min_br_code;
wpf--;
s->frame_size_min = 2 * wpf;
} else {
+ int best_br = 0, best_code = 0, best_diff = INT_MAX;
for (i = 0; i < 19; i++) {
- if ((ff_ac3_bitrate_tab[i] >> s->bit_alloc.sr_shift)*1000 == avctx->bit_rate)
+ int br = (ff_ac3_bitrate_tab[i] >> s->bit_alloc.sr_shift) * 1000;
+ int diff = abs(br - avctx->bit_rate);
+ if (diff < best_diff) {
+ best_br = br;
+ best_code = i;
+ best_diff = diff;
+ }
+ if (!best_diff)
break;
}
- if (i == 19) {
- av_log(avctx, AV_LOG_ERROR, "invalid bit rate\n");
- return AVERROR(EINVAL);
- }
- s->frame_size_code = i << 1;
+ avctx->bit_rate = best_br;
+ s->frame_size_code = best_code << 1;
s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code];
s->num_blks_code = 0x3;
s->num_blocks = 6;
(s->channel_mode == AC3_CHMODE_STEREO);
s->cpl_enabled = s->options.channel_coupling &&
- s->channel_mode >= AC3_CHMODE_STEREO && !s->fixed_point;
+ s->channel_mode >= AC3_CHMODE_STEREO;
return 0;
}
-/**
+/*
* Set bandwidth for all channels.
* The user can optionally supply a cutoff frequency. Otherwise an appropriate
* default value will be used.
*/
static av_cold void set_bandwidth(AC3EncodeContext *s)
{
- int blk, ch;
- int av_uninit(cpl_start);
+ int blk, ch, cpl_start;
if (s->cutoff) {
/* calculate bandwidth based on user-specified cutoff frequency */
/* 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) {
- if (s->options.channel_coupling < 0)
+ if (s->options.channel_coupling == AC3ENC_OPT_AUTO)
s->cpl_enabled = 0;
else
cpl_start = 15;
}
-/**
- * Initialize the encoder.
- */
av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
{
AC3EncodeContext *s = avctx->priv_data;
return ret;
avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks;
+ avctx->delay = AC3_BLOCK_SIZE;
s->bitstream_mode = avctx->audio_service_type;
if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE)
if (ret)
goto init_fail;
+#if FF_API_OLD_ENCODE_AUDIO
avctx->coded_frame= avcodec_alloc_frame();
+ if (!avctx->coded_frame) {
+ ret = AVERROR(ENOMEM);
+ goto init_fail;
+ }
+#endif
- dsputil_init(&s->dsp, avctx);
+ ff_dsputil_init(&s->dsp, avctx);
+ avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
dprint_options(s);