summaryrefslogtreecommitdiffstats
path: root/libhb/encavcodecaudio.c
diff options
context:
space:
mode:
authorRodeo <[email protected]>2013-03-03 21:52:28 +0000
committerRodeo <[email protected]>2013-03-03 21:52:28 +0000
commit2c022d89ed2d94c2ff0bc068fed8c019cb96fb12 (patch)
tree6ce5fe7e81005704b06469f59e5664a130f630a5 /libhb/encavcodecaudio.c
parent0c65680bdf29ea1e89597ae3ab7503e609382e17 (diff)
encavcodecaInit: minimize code duplication.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5292 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/encavcodecaudio.c')
-rw-r--r--libhb/encavcodecaudio.c131
1 files changed, 72 insertions, 59 deletions
diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c
index 2443e64a8..fd410f4bd 100644
--- a/libhb/encavcodecaudio.c
+++ b/libhb/encavcodecaudio.c
@@ -44,29 +44,81 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
AVCodec *codec;
AVCodecContext *context;
hb_audio_t *audio = w->audio;
- const char * codec_name = NULL;
- int profile = FF_PROFILE_UNKNOWN;
hb_work_private_t *pv = calloc(1, sizeof(hb_work_private_t));
w->private_data = pv;
pv->job = job;
pv->list = hb_list_init();
+ // channel count, layout and matrix encoding
+ int matrix_encoding;
+ uint64_t channel_layout = hb_ff_mixdown_xlat(audio->config.out.mixdown,
+ &matrix_encoding);
+ pv->out_discrete_channels =
+ hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
+
+ // default settings and options
+ AVDictionary *av_opts = NULL;
+ const char *codec_name = NULL;
+ enum AVCodecID codec_id = AV_CODEC_ID_NONE;
+ enum AVSampleFormat sample_fmt = AV_SAMPLE_FMT_FLTP;
+ int bits_per_raw_sample = 0;
+ int profile = FF_PROFILE_UNKNOWN;
+
+ // override with encoder-specific values
switch (audio->config.out.codec)
{
- case HB_ACODEC_FDK_AAC:
- codec_name = "libfdk_aac";
- profile = FF_PROFILE_AAC_LOW;
+ case HB_ACODEC_AC3:
+ codec_id = AV_CODEC_ID_AC3;
+ if (matrix_encoding != AV_MATRIX_ENCODING_NONE)
+ av_dict_set(&av_opts, "dsur_mode", "on", 0);
break;
+
+ case HB_ACODEC_FDK_AAC:
case HB_ACODEC_FDK_HAAC:
- codec_name = "libfdk_aac";
- profile = FF_PROFILE_AAC_HE;
+ codec_name = "libfdk_aac";
+ sample_fmt = AV_SAMPLE_FMT_S16;
+ bits_per_raw_sample = 16;
+ switch (audio->config.out.codec)
+ {
+ case HB_ACODEC_FDK_HAAC:
+ profile = FF_PROFILE_AAC_HE;
+ break;
+ default:
+ profile = FF_PROFILE_AAC_LOW;
+ break;
+ }
+ // Libav's libfdk-aac wrapper expects back channels for 5.1
+ // audio, and will error out unless we translate the layout
+ if (channel_layout == AV_CH_LAYOUT_5POINT1)
+ channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
break;
+
case HB_ACODEC_FFAAC:
codec_name = "aac";
+ av_dict_set(&av_opts, "stereo_mode", "ms_off", 0);
break;
- default:
+
+ case HB_ACODEC_FFFLAC:
+ case HB_ACODEC_FFFLAC24:
+ codec_id = AV_CODEC_ID_FLAC;
+ switch (audio->config.out.codec)
+ {
+ case HB_ACODEC_FFFLAC24:
+ sample_fmt = AV_SAMPLE_FMT_S32;
+ bits_per_raw_sample = 24;
+ break;
+ default:
+ sample_fmt = AV_SAMPLE_FMT_S16;
+ bits_per_raw_sample = 16;
+ break;
+ }
break;
+
+ default:
+ hb_error("encavcodecaInit: unsupported codec (0x%x)",
+ audio->config.out.codec);
+ return 1;
}
if (codec_name != NULL)
{
@@ -80,32 +132,22 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
}
else
{
- codec = avcodec_find_encoder(w->codec_param);
+ codec = avcodec_find_encoder(codec_id);
if (codec == NULL)
{
- hb_error("encavcodecaInit: avcodec_find_encoder() failed");
+ hb_error("encavcodecaInit: avcodec_find_encoder(%d) failed",
+ codec_id);
return 1;
}
}
- context = avcodec_alloc_context3(codec);
-
- int mode;
- context->channel_layout = hb_ff_mixdown_xlat(audio->config.out.mixdown,
- &mode);
- context->channels = pv->out_discrete_channels =
- hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown);
- context->sample_rate = audio->config.out.samplerate;
-
- AVDictionary *av_opts = NULL;
- if (audio->config.out.codec == HB_ACODEC_FFAAC)
- {
- av_dict_set(&av_opts, "stereo_mode", "ms_off", 0);
- }
- else if (w->codec_param == AV_CODEC_ID_AC3 &&
- mode != AV_MATRIX_ENCODING_NONE)
- {
- av_dict_set(&av_opts, "dsur_mode", "on", 0);
- }
+ // allocate the context and apply the settings
+ context = avcodec_alloc_context3(codec);
+ hb_ff_set_sample_fmt(context, codec, sample_fmt);
+ context->bits_per_raw_sample = bits_per_raw_sample;
+ context->profile = profile;
+ context->channel_layout = channel_layout;
+ context->channels = pv->out_discrete_channels;
+ context->sample_rate = audio->config.out.samplerate;
if (audio->config.out.bitrate > 0)
{
@@ -128,34 +170,6 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
// packet instead.
context->flags |= CODEC_FLAG_GLOBAL_HEADER;
- // set the sample format and bit depth to something practical
- switch (audio->config.out.codec)
- {
- case HB_ACODEC_FDK_AAC:
- case HB_ACODEC_FDK_HAAC:
- hb_ff_set_sample_fmt(context, codec, AV_SAMPLE_FMT_S16);
- context->bits_per_raw_sample = 16;
- context->profile = profile;
- // fdk-aac implementation in libav does not support
- // AV_CH_LAYOUT_5POINT1, so translate to AV_CH_LAYOUT_5POINT1_BACK
- if (context->channel_layout == AV_CH_LAYOUT_5POINT1)
- context->channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
- break;
- case HB_ACODEC_FFFLAC:
- hb_ff_set_sample_fmt(context, codec, AV_SAMPLE_FMT_S16);
- context->bits_per_raw_sample = 16;
- break;
-
- case HB_ACODEC_FFFLAC24:
- hb_ff_set_sample_fmt(context, codec, AV_SAMPLE_FMT_S32);
- context->bits_per_raw_sample = 24;
- break;
-
- default:
- hb_ff_set_sample_fmt(context, codec, AV_SAMPLE_FMT_FLTP);
- break;
- }
-
if (hb_avcodec_open(context, codec, &av_opts, 0))
{
hb_error("encavcodecaInit: hb_avcodec_open() failed");
@@ -171,6 +185,7 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
av_dict_free(&av_opts);
pv->context = context;
+ audio->config.out.samples_per_frame =
pv->samples_per_frame = context->frame_size;
pv->input_samples = context->frame_size * context->channels;
pv->input_buf = malloc(pv->input_samples * sizeof(float));
@@ -218,8 +233,6 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
pv->output_buf = pv->input_buf;
}
- audio->config.out.samples_per_frame = pv->samples_per_frame;
-
if (context->extradata != NULL)
{
memcpy(w->config->extradata.bytes, context->extradata,