diff options
author | Rodeo <[email protected]> | 2013-03-03 21:52:28 +0000 |
---|---|---|
committer | Rodeo <[email protected]> | 2013-03-03 21:52:28 +0000 |
commit | 2c022d89ed2d94c2ff0bc068fed8c019cb96fb12 (patch) | |
tree | 6ce5fe7e81005704b06469f59e5664a130f630a5 /libhb/encavcodecaudio.c | |
parent | 0c65680bdf29ea1e89597ae3ab7503e609382e17 (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.c | 131 |
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, |