* The simplest AC-3 encoder.
*/
-//#define ASSERT_LEVEL 2
-
#include <stdint.h>
-#include "libavutil/audioconvert.h"
+#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
+#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
+#include "libavutil/internal.h"
#include "libavutil/opt.h"
#include "avcodec.h"
+#include "me_cmp.h"
#include "put_bits.h"
-#include "dsputil.h"
+#include "audiodsp.h"
#include "ac3dsp.h"
#include "ac3.h"
-#include "audioconvert.h"
#include "fft.h"
+#include "internal.h"
#include "ac3enc.h"
#include "eac3enc.h"
/**
* 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,
exp_strategy[blk] = EXP_NEW;
continue;
}
- exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16);
+ exp_diff = s->mecc.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16);
exp_strategy[blk] = EXP_REUSE;
if (ch == CPL_CH && exp_diff > (EXP_DIFF_THRESHOLD * (s->blocks[blk].end_freq[ch] - s->start_freq[ch]) / AC3_MAX_COEFS))
exp_strategy[blk] = EXP_NEW;
* bit allocation parameters do not change between blocks
* no delta bit allocation
* no skipped data
- * no auxilliary data
+ * no auxiliary data
* no E-AC-3 metadata
*/
* Initialize bit allocation.
* Set default parameter codes and calculate parameter values.
*/
-static void bit_alloc_init(AC3EncodeContext *s)
+static av_cold void bit_alloc_init(AC3EncodeContext *s)
{
int ch;
*/
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 */
}
+#ifdef DEBUG
static void dprint_options(AC3EncodeContext *s)
{
-#ifdef DEBUG
AVCodecContext *avctx = s->avctx;
AC3EncOptions *opt = &s->options;
char strbuf[32];
case 16: av_strlcpy(strbuf, "E-AC-3 (enhanced)", 32); break;
default: snprintf(strbuf, 32, "ERROR");
}
- av_dlog(avctx, "bitstream_id: %s (%d)\n", strbuf, s->bitstream_id);
- av_dlog(avctx, "sample_fmt: %s\n", av_get_sample_fmt_name(avctx->sample_fmt));
+ ff_dlog(avctx, "bitstream_id: %s (%d)\n", strbuf, s->bitstream_id);
+ ff_dlog(avctx, "sample_fmt: %s\n", av_get_sample_fmt_name(avctx->sample_fmt));
av_get_channel_layout_string(strbuf, 32, s->channels, avctx->channel_layout);
- av_dlog(avctx, "channel_layout: %s\n", strbuf);
- av_dlog(avctx, "sample_rate: %d\n", s->sample_rate);
- av_dlog(avctx, "bit_rate: %d\n", s->bit_rate);
- av_dlog(avctx, "blocks/frame: %d (code=%d)\n", s->num_blocks, s->num_blks_code);
+ ff_dlog(avctx, "channel_layout: %s\n", strbuf);
+ ff_dlog(avctx, "sample_rate: %d\n", s->sample_rate);
+ ff_dlog(avctx, "bit_rate: %d\n", s->bit_rate);
+ ff_dlog(avctx, "blocks/frame: %d (code=%d)\n", s->num_blocks, s->num_blks_code);
if (s->cutoff)
- av_dlog(avctx, "cutoff: %d\n", s->cutoff);
+ ff_dlog(avctx, "cutoff: %d\n", s->cutoff);
- av_dlog(avctx, "per_frame_metadata: %s\n",
+ ff_dlog(avctx, "per_frame_metadata: %s\n",
opt->allow_per_frame_metadata?"on":"off");
if (s->has_center)
- av_dlog(avctx, "center_mixlev: %0.3f (%d)\n", opt->center_mix_level,
+ ff_dlog(avctx, "center_mixlev: %0.3f (%d)\n", opt->center_mix_level,
s->center_mix_level);
else
- av_dlog(avctx, "center_mixlev: {not written}\n");
+ ff_dlog(avctx, "center_mixlev: {not written}\n");
if (s->has_surround)
- av_dlog(avctx, "surround_mixlev: %0.3f (%d)\n", opt->surround_mix_level,
+ ff_dlog(avctx, "surround_mixlev: %0.3f (%d)\n", opt->surround_mix_level,
s->surround_mix_level);
else
- av_dlog(avctx, "surround_mixlev: {not written}\n");
+ ff_dlog(avctx, "surround_mixlev: {not written}\n");
if (opt->audio_production_info) {
- av_dlog(avctx, "mixing_level: %ddB\n", opt->mixing_level);
+ ff_dlog(avctx, "mixing_level: %ddB\n", opt->mixing_level);
switch (opt->room_type) {
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);
+ ff_dlog(avctx, "room_type: %s\n", strbuf);
} else {
- av_dlog(avctx, "mixing_level: {not written}\n");
- av_dlog(avctx, "room_type: {not written}\n");
+ ff_dlog(avctx, "mixing_level: {not written}\n");
+ ff_dlog(avctx, "room_type: {not written}\n");
}
- av_dlog(avctx, "copyright: %s\n", opt->copyright?"on":"off");
- av_dlog(avctx, "dialnorm: %ddB\n", opt->dialogue_level);
+ ff_dlog(avctx, "copyright: %s\n", opt->copyright?"on":"off");
+ ff_dlog(avctx, "dialnorm: %ddB\n", opt->dialogue_level);
if (s->channel_mode == AC3_CHMODE_STEREO) {
switch (opt->dolby_surround_mode) {
case AC3ENC_OPT_NOT_INDICATED: av_strlcpy(strbuf, "notindicated", 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);
+ ff_dlog(avctx, "dsur_mode: %s\n", strbuf);
} else {
- av_dlog(avctx, "dsur_mode: {not written}\n");
+ ff_dlog(avctx, "dsur_mode: {not written}\n");
}
- av_dlog(avctx, "original: %s\n", opt->original?"on":"off");
+ ff_dlog(avctx, "original: %s\n", opt->original?"on":"off");
if (s->bitstream_id == 6) {
if (opt->extended_bsi_1) {
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);
- av_dlog(avctx, "ltrt_cmixlev: %0.3f (%d)\n",
+ ff_dlog(avctx, "dmix_mode: %s\n", strbuf);
+ ff_dlog(avctx, "ltrt_cmixlev: %0.3f (%d)\n",
opt->ltrt_center_mix_level, s->ltrt_center_mix_level);
- av_dlog(avctx, "ltrt_surmixlev: %0.3f (%d)\n",
+ ff_dlog(avctx, "ltrt_surmixlev: %0.3f (%d)\n",
opt->ltrt_surround_mix_level, s->ltrt_surround_mix_level);
- av_dlog(avctx, "loro_cmixlev: %0.3f (%d)\n",
+ ff_dlog(avctx, "loro_cmixlev: %0.3f (%d)\n",
opt->loro_center_mix_level, s->loro_center_mix_level);
- av_dlog(avctx, "loro_surmixlev: %0.3f (%d)\n",
+ ff_dlog(avctx, "loro_surmixlev: %0.3f (%d)\n",
opt->loro_surround_mix_level, s->loro_surround_mix_level);
} else {
- av_dlog(avctx, "extended bitstream info 1: {not written}\n");
+ ff_dlog(avctx, "extended bitstream info 1: {not written}\n");
}
if (opt->extended_bsi_2) {
switch (opt->dolby_surround_ex_mode) {
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);
+ ff_dlog(avctx, "dsurex_mode: %s\n", strbuf);
switch (opt->dolby_headphone_mode) {
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);
+ ff_dlog(avctx, "dheadphone_mode: %s\n", strbuf);
switch (opt->ad_converter_type) {
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);
+ ff_dlog(avctx, "ad_conv_type: %s\n", strbuf);
} else {
- av_dlog(avctx, "extended bitstream info 2: {not written}\n");
+ ff_dlog(avctx, "extended bitstream info 2: {not written}\n");
}
}
-#endif
}
+#else
+#define dprint_options(x) do {} while(0)
+#endif
#define FLT_OPTION_THRESHOLD 0.01
s->mdct_end(s);
- av_freep(&avctx->coded_frame);
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;
*/
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 */
s->avctx = avctx;
- s->eac3 = avctx->codec_id == CODEC_ID_EAC3;
+ s->eac3 = avctx->codec_id == AV_CODEC_ID_EAC3;
ff_ac3_common_init();
return ret;
avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks;
+ avctx->initial_padding = AC3_BLOCK_SIZE;
s->bitstream_mode = avctx->audio_service_type;
if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE)
if (ret)
goto init_fail;
- avctx->coded_frame= avcodec_alloc_frame();
-
- dsputil_init(&s->dsp, avctx);
- ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ ff_audiodsp_init(&s->adsp);
+ ff_me_cmp_init(&s->mecc, avctx);
+ ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
dprint_options(s);