summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/aaccoder_twoloop.h2
-rw-r--r--libavcodec/aacenc.c137
-rw-r--r--libavcodec/aacenc.h4
-rw-r--r--libavcodec/aacenc_utils.h38
-rw-r--r--libavcodec/aacenctab.h7
5 files changed, 137 insertions, 51 deletions
diff --git a/libavcodec/aaccoder_twoloop.h b/libavcodec/aaccoder_twoloop.h
index 2cc9a52d73..e53257fbaa 100644
--- a/libavcodec/aaccoder_twoloop.h
+++ b/libavcodec/aaccoder_twoloop.h
@@ -142,7 +142,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
* No need to be overly precise, this only controls RD
* adjustment CB limits when going overboard
*/
- if (s->options.stereo_mode && s->cur_type == TYPE_CPE)
+ if (s->options.mid_side && s->cur_type == TYPE_CPE)
destbits *= 2;
/**
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 8041127009..78e292b246 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -46,6 +46,44 @@
#include "psymodel.h"
+struct AACProfileOptions {
+ int profile;
+ struct AACEncOptions opts;
+};
+
+ /**
+ * List of currently supported profiles, anything not listed isn't supported.
+ */
+static const struct AACProfileOptions aacenc_profiles[] = {
+ {FF_PROFILE_AAC_MAIN,
+ { /* Main profile, all advanced encoding abilities enabled */
+ .mid_side = 0,
+ .pns = 1,
+ .tns = 0,
+ .pred = OPT_REQUIRED,
+ .intensity_stereo = 1,
+ },
+ },
+ {FF_PROFILE_AAC_LOW,
+ { /* Default profile, these are the settings that get set by default */
+ .mid_side = 0,
+ .pns = 1,
+ .tns = 0,
+ .pred = OPT_NEEDS_MAIN,
+ .intensity_stereo = 1,
+ },
+ },
+ {FF_PROFILE_MPEG2_AAC_LOW,
+ { /* Strict MPEG 2 Part 7 compliance profile */
+ .mid_side = 0,
+ .pns = OPT_BANNED,
+ .tns = 0,
+ .pred = OPT_BANNED,
+ .intensity_stereo = 1,
+ },
+ },
+};
+
/**
* Make AAC audio config object.
* @see 1.6.2.1 "Syntax - AudioSpecificConfig"
@@ -690,8 +728,8 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
}
s->cur_channel = start_ch;
}
- if (s->options.stereo_mode) { /* Mid/Side stereo */
- if (s->options.stereo_mode == -1 && s->coder->search_for_ms)
+ if (s->options.mid_side) { /* Mid/Side stereo */
+ if (s->options.mid_side == -1 && s->coder->search_for_ms)
s->coder->search_for_ms(s, cpe);
else if (cpe->common_window)
memset(cpe->ms_mask, 1, sizeof(cpe->ms_mask));
@@ -852,82 +890,88 @@ alloc_fail:
static av_cold int aac_encode_init(AVCodecContext *avctx)
{
AACEncContext *s = avctx->priv_data;
+ const AACEncOptions *p_opt = NULL;
int i, ret = 0;
const uint8_t *sizes[2];
uint8_t grouping[AAC_MAX_CHANNELS];
int lengths[2];
+ s->channels = avctx->channels;
+ s->chan_map = aac_chan_configs[s->channels-1];
+ s->random_state = 0x1f2e3d4c;
+ s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120;
+ avctx->extradata_size = 5;
avctx->frame_size = 1024;
+ avctx->initial_padding = 1024;
+ avctx->bit_rate = (int)FFMIN(
+ 6144 * s->channels / 1024.0 * avctx->sample_rate,
+ avctx->bit_rate);
+ avctx->profile = avctx->profile == FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW :
+ avctx->profile;
for (i = 0; i < 16; i++)
if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i])
break;
+ s->samplerate_index = i;
- s->channels = avctx->channels;
-
- ERROR_IF(i == 16 || i >= ff_aac_swb_size_1024_len || i >= ff_aac_swb_size_128_len,
+ ERROR_IF(s->samplerate_index == 16 ||
+ s->samplerate_index >= ff_aac_swb_size_1024_len ||
+ s->samplerate_index >= ff_aac_swb_size_128_len,
"Unsupported sample rate %d\n", avctx->sample_rate);
ERROR_IF(s->channels > AAC_MAX_CHANNELS || s->channels == 7,
"Unsupported number of channels: %d\n", s->channels);
WARN_IF(1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * s->channels,
"Too many bits per frame requested, clamping to max\n");
- if (avctx->profile == FF_PROFILE_AAC_MAIN) {
- s->options.pred = 1;
- } else if ((avctx->profile == FF_PROFILE_AAC_LOW ||
- avctx->profile == FF_PROFILE_UNKNOWN) && s->options.pred) {
- s->profile = 0; /* Main */
- WARN_IF(1, "Prediction requested, changing profile to AAC-Main\n");
- } else if (avctx->profile == FF_PROFILE_AAC_LOW ||
- avctx->profile == FF_PROFILE_UNKNOWN) {
- s->profile = 1; /* Low */
- } else {
- ERROR_IF(1, "Unsupported profile %d\n", avctx->profile);
+
+ for (i = 0; i < FF_ARRAY_ELEMS(aacenc_profiles); i++) {
+ if (avctx->profile == aacenc_profiles[i].profile) {
+ p_opt = &aacenc_profiles[i].opts;
+ break;
+ }
}
+ ERROR_IF(!p_opt, "Unsupported encoding profile: %d\n", avctx->profile);
+ AAC_OPT_SET(&s->options, p_opt, 1, coder);
+ AAC_OPT_SET(&s->options, p_opt, 0, pns);
+ AAC_OPT_SET(&s->options, p_opt, 0, tns);
+ AAC_OPT_SET(&s->options, p_opt, 0, pred);
+ AAC_OPT_SET(&s->options, p_opt, 1, mid_side);
+ AAC_OPT_SET(&s->options, p_opt, 0, intensity_stereo);
+ if (avctx->profile == FF_PROFILE_MPEG2_AAC_LOW)
+ s->profile = FF_PROFILE_AAC_LOW;
+ else
+ s->profile = avctx->profile;
+ s->coder = &ff_aac_coders[s->options.coder];
- if (s->options.aac_coder != AAC_CODER_TWOLOOP) {
+ if (s->options.coder != AAC_CODER_TWOLOOP) {
s->options.intensity_stereo = 0;
s->options.pns = 0;
}
- avctx->bit_rate = (int)FFMIN(
- 6144 * s->channels / 1024.0 * avctx->sample_rate,
- avctx->bit_rate);
-
- s->samplerate_index = i;
-
- s->chan_map = aac_chan_configs[s->channels-1];
-
if ((ret = dsp_init(avctx, s)) < 0)
goto fail;
if ((ret = alloc_buffers(avctx, s)) < 0)
goto fail;
- avctx->extradata_size = 5;
put_audio_specific_config(avctx);
- sizes[0] = ff_aac_swb_size_1024[i];
- sizes[1] = ff_aac_swb_size_128[i];
- lengths[0] = ff_aac_num_swb_1024[i];
- lengths[1] = ff_aac_num_swb_128[i];
+ sizes[0] = ff_aac_swb_size_1024[s->samplerate_index];
+ sizes[1] = ff_aac_swb_size_128[s->samplerate_index];
+ lengths[0] = ff_aac_num_swb_1024[s->samplerate_index];
+ lengths[1] = ff_aac_num_swb_128[s->samplerate_index];
for (i = 0; i < s->chan_map[0]; i++)
grouping[i] = s->chan_map[i + 1] == TYPE_CPE;
if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths,
s->chan_map[0], grouping)) < 0)
goto fail;
s->psypp = ff_psy_preprocess_init(avctx);
- s->coder = &ff_aac_coders[s->options.aac_coder];
ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON);
if (HAVE_MIPSDSPR1)
ff_aac_coder_init_mips(s);
- s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120;
- s->random_state = 0x1f2e3d4c;
-
ff_aac_tableinit();
- avctx->initial_padding = 1024;
ff_af_queue_init(avctx, &s->afq);
return 0;
@@ -938,19 +982,16 @@ fail:
#define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption aacenc_options[] = {
- {"stereo_mode", "Stereo coding method", offsetof(AACEncContext, options.stereo_mode), AV_OPT_TYPE_INT, {.i64 = 0}, -1, 1, AACENC_FLAGS, "stereo_mode"},
- {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
- {"ms_off", "Disable Mid/Side coding", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
- {"ms_force", "Force Mid/Side for the whole frame if possible", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
- {"aac_coder", "Coding algorithm", offsetof(AACEncContext, options.aac_coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_TWOLOOP}, 0, AAC_CODER_NB-1, AACENC_FLAGS, "aac_coder"},
- {"faac", "FAAC-inspired method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAAC}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"},
- {"anmr", "ANMR method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"},
- {"twoloop", "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"},
- {"fast", "Constant quantizer", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST}, INT_MIN, INT_MAX, AACENC_FLAGS, "aac_coder"},
- {"aac_pns", "Perceptual Noise Substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AACENC_FLAGS},
- {"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AACENC_FLAGS},
- {"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AACENC_FLAGS},
- {"aac_pred", "AAC-Main prediction", offsetof(AACEncContext, options.pred), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AACENC_FLAGS},
+ {"aac_coder", "Coding algorithm", offsetof(AACEncContext, options.coder), AV_OPT_TYPE_INT, {.i64 = AAC_CODER_TWOLOOP}, -1, AAC_CODER_NB-1, AACENC_FLAGS, "coder"},
+ {"faac", "FAAC-inspired method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAAC}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
+ {"anmr", "ANMR method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_ANMR}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
+ {"twoloop", "Two loop searching method", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_TWOLOOP}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
+ {"fast", "Constant quantizer", 0, AV_OPT_TYPE_CONST, {.i64 = AAC_CODER_FAST}, INT_MIN, INT_MAX, AACENC_FLAGS, "coder"},
+ {"aac_ms", "Force M/S stereo coding", offsetof(AACEncContext, options.mid_side), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, AACENC_FLAGS},
+ {"aac_is", "Intensity stereo coding", offsetof(AACEncContext, options.intensity_stereo), AV_OPT_TYPE_BOOL, {.i64 = OPT_AUTO}, -1, 1, AACENC_FLAGS},
+ {"aac_pns", "Perceptual noise substitution", offsetof(AACEncContext, options.pns), AV_OPT_TYPE_BOOL, {.i64 = OPT_AUTO}, -1, 1, AACENC_FLAGS},
+ {"aac_tns", "Temporal noise shaping", offsetof(AACEncContext, options.tns), AV_OPT_TYPE_BOOL, {.i64 = OPT_AUTO}, -1, 1, AACENC_FLAGS},
+ {"aac_pred", "AAC-Main prediction", offsetof(AACEncContext, options.pred), AV_OPT_TYPE_BOOL, {.i64 = OPT_AUTO}, -1, 1, AACENC_FLAGS},
{NULL}
};
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 98b38a4bde..b29fdf5307 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -42,11 +42,11 @@ typedef enum AACCoder {
}AACCoder;
typedef struct AACEncOptions {
- int stereo_mode;
- int aac_coder;
+ int coder;
int pns;
int tns;
int pred;
+ int mid_side;
int intensity_stereo;
} AACEncOptions;
diff --git a/libavcodec/aacenc_utils.h b/libavcodec/aacenc_utils.h
index 16dad63f61..2fbe4c95bd 100644
--- a/libavcodec/aacenc_utils.h
+++ b/libavcodec/aacenc_utils.h
@@ -201,5 +201,43 @@ static inline int lcg_random(unsigned previous_val)
av_log(avctx, AV_LOG_WARNING, __VA_ARGS__); \
}
+#define AAC_OPT_SET(e_opt, p_opt, bypass, name) \
+ ERROR_IF ((e_opt)->name == 1 && (p_opt)->name == OPT_BANNED, \
+ "Profile %i does not allow %s\n", avctx->profile, #name); \
+ ERROR_IF ((e_opt)->name == 0 && (p_opt)->name == OPT_REQUIRED, \
+ "Option %s is a requirement for this profile (%i)\n", \
+ #name, avctx->profile); \
+ if ((e_opt)->name == 1 && (p_opt)->name == OPT_NEEDS_MAIN && \
+ avctx->profile == FF_PROFILE_AAC_LOW) { \
+ WARN_IF(1, "Profile %i does not allow for %s, setting profile to " \
+ "\"aac_main\"(%i)\n", avctx->profile, #name, \
+ FF_PROFILE_AAC_MAIN); \
+ avctx->profile = FF_PROFILE_AAC_MAIN; \
+ p_opt = &aacenc_profiles[FF_PROFILE_AAC_MAIN].opts; \
+ } \
+ if ((e_opt)->name == 1 && (p_opt)->name == OPT_NEEDS_LTP && \
+ avctx->profile == FF_PROFILE_AAC_LOW) { \
+ WARN_IF(1, "Profile %i does not allow for %s, setting profile to " \
+ "\"aac_ltp\"(%i)\n", avctx->profile, #name, \
+ FF_PROFILE_AAC_LTP); \
+ avctx->profile = FF_PROFILE_AAC_LTP; \
+ p_opt = &aacenc_profiles[FF_PROFILE_AAC_LTP].opts; \
+ } \
+ if ((e_opt)->name == OPT_AUTO) { \
+ if ((p_opt)->name == OPT_BANNED) { \
+ (e_opt)->name = 0; \
+ } else if ((p_opt)->name == OPT_NEEDS_LTP) { \
+ (e_opt)->name = 0; \
+ } else if ((p_opt)->name == OPT_NEEDS_MAIN) { \
+ (e_opt)->name = 0; \
+ } else if ((p_opt)->name == OPT_REQUIRED) { \
+ (e_opt)->name = 1; \
+ } else if (bypass) { \
+ (e_opt)->name = (e_opt)->name; \
+ } else { \
+ (e_opt)->name = (p_opt)->name; \
+ } \
+ } \
+ av_log(avctx, AV_LOG_VERBOSE, "Option %s set to %i\n", #name, (e_opt)->name);
#endif /* AVCODEC_AACENC_UTILS_H */
diff --git a/libavcodec/aacenctab.h b/libavcodec/aacenctab.h
index 78b4d400c3..c6658a4a6f 100644
--- a/libavcodec/aacenctab.h
+++ b/libavcodec/aacenctab.h
@@ -36,6 +36,13 @@
/** Total number of codebooks, including special ones **/
#define CB_TOT_ALL 15
+/** Profile option settings **/
+#define OPT_AUTO -1
+#define OPT_BANNED -256
+#define OPT_NEEDS_LTP -384
+#define OPT_NEEDS_MAIN -512
+#define OPT_REQUIRED -768
+
#define AAC_MAX_CHANNELS 8
extern const uint8_t *ff_aac_swb_size_1024[];