diff options
author | jstebbins <[email protected]> | 2013-03-03 16:18:16 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2013-03-03 16:18:16 +0000 |
commit | 288639e626b5c550fdd33e49abf1b8e3a3fcd52e (patch) | |
tree | 0df5c1da8728a0706110984b675a0d3b7a350ba9 /libhb | |
parent | b56a9d0fc23ca64f1d63afb797bdc07e1dffc357 (diff) |
Add optional fdk-aac encoder
configure --enable-fdk-aac to enable this encoder
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5287 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/common.c | 9 | ||||
-rw-r--r-- | libhb/common.h | 6 | ||||
-rw-r--r-- | libhb/encavcodecaudio.c | 57 | ||||
-rw-r--r-- | libhb/module.defs | 12 | ||||
-rw-r--r-- | libhb/muxmkv.c | 5 | ||||
-rw-r--r-- | libhb/muxmp4.c | 4 | ||||
-rw-r--r-- | libhb/work.c | 2 |
7 files changed, 85 insertions, 10 deletions
diff --git a/libhb/common.c b/libhb/common.c index cfbeb6185..dbfc6caf1 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -127,6 +127,10 @@ hb_encoder_t hb_audio_encoders[] = { "HE-AAC (CoreAudio)", "ca_haac", HB_ACODEC_CA_HAAC, HB_MUX_MP4|HB_MUX_MKV }, #endif { "AAC (faac)", "faac", HB_ACODEC_FAAC, HB_MUX_MP4|HB_MUX_MKV }, +#ifdef USE_FDK_AAC + { "AAC (FDK)", "fdk_aac", HB_ACODEC_FDK_AAC, HB_MUX_MP4|HB_MUX_MKV }, + { "HE-AAC (FDK)", "fdk_haac", HB_ACODEC_FDK_HAAC, HB_MUX_MP4|HB_MUX_MKV }, +#endif { "AAC (ffmpeg)", "ffaac", HB_ACODEC_FFAAC, HB_MUX_MP4|HB_MUX_MKV }, { "AAC Passthru", "copy:aac", HB_ACODEC_AAC_PASS, HB_MUX_MP4|HB_MUX_MKV }, { "AC3 (ffmpeg)", "ffac3", HB_ACODEC_AC3, HB_MUX_MP4|HB_MUX_MKV }, @@ -179,6 +183,8 @@ int hb_audio_dither_is_supported(uint32_t codec) switch (codec) { case HB_ACODEC_FFFLAC: + case HB_ACODEC_FDK_AAC: + case HB_ACODEC_FDK_HAAC: return 1; default: return 0; @@ -670,6 +676,7 @@ void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, break; case HB_ACODEC_CA_AAC: + case HB_ACODEC_FDK_AAC: { switch (samplerate) { @@ -705,6 +712,7 @@ void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, } break; case HB_ACODEC_CA_HAAC: + case HB_ACODEC_FDK_HAAC: *low = nchannels * (12 + (4 * (samplerate >= 44100))); *high = nchannels * 40; break; @@ -788,6 +796,7 @@ int hb_get_default_audio_bitrate(uint32_t codec, int samplerate, int mixdown) break; case HB_ACODEC_CA_HAAC: + case HB_ACODEC_FDK_HAAC: bitrate = nchannels * 32; break; diff --git a/libhb/common.h b/libhb/common.h index c5abee399..e84fe97f8 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -471,7 +471,7 @@ struct hb_job_s /* Audio starts here */ /* Audio Codecs */ -#define HB_ACODEC_MASK 0x003FFF00 +#define HB_ACODEC_MASK 0x00FFFF00 #define HB_ACODEC_FAAC 0x00000100 #define HB_ACODEC_LAME 0x00000200 #define HB_ACODEC_VORBIS 0x00000400 @@ -486,7 +486,9 @@ struct hb_job_s #define HB_ACODEC_MP3 0x00080000 #define HB_ACODEC_FFFLAC 0x00100000 #define HB_ACODEC_FFFLAC24 0x00200000 -#define HB_ACODEC_FF_MASK 0x003F2000 +#define HB_ACODEC_FDK_AAC 0x00400000 +#define HB_ACODEC_FDK_HAAC 0x00800000 +#define HB_ACODEC_FF_MASK 0x00FF2000 #define HB_ACODEC_PASS_FLAG 0x40000000 #define HB_ACODEC_PASS_MASK (HB_ACODEC_MP3 | HB_ACODEC_FFAAC | HB_ACODEC_DCA_HD | HB_ACODEC_AC3 | HB_ACODEC_DCA) #define HB_ACODEC_AUTO_PASS (HB_ACODEC_PASS_MASK | HB_ACODEC_PASS_FLAG) diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c index ecd75ff98..da871c01c 100644 --- a/libhb/encavcodecaudio.c +++ b/libhb/encavcodecaudio.c @@ -44,17 +44,48 @@ 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(); - codec = avcodec_find_encoder(w->codec_param); - if (codec == NULL) + switch (audio->config.out.codec) { - hb_error("encavcodecaInit: avcodec_find_encoder() failed"); - return 1; + case HB_ACODEC_FDK_AAC: + codec_name = "libfdk_aac"; + profile = FF_PROFILE_AAC_LOW; + break; + case HB_ACODEC_FDK_HAAC: + codec_name = "libfdk_aac"; + profile = FF_PROFILE_AAC_HE; + break; + case HB_ACODEC_FAAC: + codec_name = "aac"; + break; + default: + break; + } + if (codec_name != NULL) + { + codec = avcodec_find_encoder_by_name(codec_name); + if (codec == NULL) + { + hb_error("encavcodecaInit: avcodec_find_encoder_by_name(%s) failed", + codec_name); + return 1; + } + } + else + { + codec = avcodec_find_encoder(w->codec_param); + if (codec == NULL) + { + hb_error("encavcodecaInit: avcodec_find_encoder() failed"); + return 1; + } } context = avcodec_alloc_context3(codec); @@ -66,7 +97,7 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job) context->sample_rate = audio->config.out.samplerate; AVDictionary *av_opts = NULL; - if (w->codec_param == AV_CODEC_ID_AAC) + if (audio->config.out.codec == HB_ACODEC_FFAAC) { av_dict_set(&av_opts, "stereo_mode", "ms_off", 0); } @@ -91,9 +122,25 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job) context->compression_level = audio->config.out.compression_level; } + // For some codecs, libav requires the following flag to be set + // so that it fills extradata with global header information. + // If this flag is not set, it inserts the data into each + // 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; diff --git a/libhb/module.defs b/libhb/module.defs index e5c5650fa..bb7ffccb5 100644 --- a/libhb/module.defs +++ b/libhb/module.defs @@ -1,6 +1,6 @@ __deps__ := A52DEC BZIP2 FAAC FFMPEG FONTCONFIG FREETYPE LAME LIBASS LIBDCA \ LIBDVDREAD LIBDVDNAV LIBICONV LIBMKV LIBOGG LIBSAMPLERATE LIBTHEORA LIBVORBIS LIBXML2 \ - MP4V2 MPEG2DEC PTHREADW32 X264 ZLIB LIBBLURAY + MP4V2 MPEG2DEC PTHREADW32 X264 ZLIB LIBBLURAY FDKAAC $(eval $(call import.MODULE.defs,LIBHB,libhb,$(__deps__))) $(eval $(call import.GCC,LIBHB)) @@ -37,6 +37,9 @@ LIBHB.out += $(LIBHB.a) ifeq (1,$(FEATURE.ff.mpeg2)) LIBHB.GCC.D += USE_FF_MPEG2 endif +ifeq (1,$(FEATURE.fdk_aac)) +LIBHB.GCC.D += USE_FDK_AAC +endif LIBHB.GCC.D += __LIBHB__ USE_PTHREAD LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include @@ -92,10 +95,15 @@ LIBHB.dll = $(LIBHB.build/)hb.dll LIBHB.lib = $(LIBHB.build/)hb.lib LIBHB.dll.libs = $(foreach n, \ - a52 ass avcodec avformat avutil avresample dvdnav dvdread faac fontconfig freetype mkv mpeg2 mp3lame mp4v2 \ + a52 ass avcodec avformat avutil avresample dvdnav dvdread faac \ + fontconfig freetype mkv mpeg2 mp3lame mp4v2 \ ogg samplerate swscale theora vorbis vorbisenc x264 xml2 bluray, \ $(CONTRIB.build/)lib/lib$(n).a ) +ifeq (1,$(FEATURE.fdk_aac)) +LIBHB.dll.libs += $(CONTRIB.build/)lib/libfdk-aac.a +endif + ifneq ($(HAS.iconv),1) LIBHB.dll.libs += $(CONTRIB.build/)lib/libiconv.a else diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c index e45ebb126..fe50a6415 100644 --- a/libhb/muxmkv.c +++ b/libhb/muxmkv.c @@ -260,6 +260,8 @@ static int MKVInit( hb_mux_object_t * m ) case HB_ACODEC_FFAAC: case HB_ACODEC_CA_AAC: case HB_ACODEC_CA_HAAC: + case HB_ACODEC_FDK_AAC: + case HB_ACODEC_FDK_HAAC: track->codecPrivate = audio->priv.config.extradata.bytes; track->codecPrivateSize = audio->priv.config.extradata.length; track->codecID = MK_ACODEC_AAC; @@ -285,7 +287,8 @@ static int MKVInit( hb_mux_object_t * m ) lang = lang_for_code2( audio->config.lang.iso639_2 ); track->language = lang->iso639_2b ? lang->iso639_2b : lang->iso639_2; // sample rate - if ((audio->config.out.codec == HB_ACODEC_CA_HAAC) || + if ((audio->config.out.codec == HB_ACODEC_CA_HAAC) || + (audio->config.out.codec == HB_ACODEC_FDK_HAAC) || (audio->config.out.codec == HB_ACODEC_AAC_PASS && audio->config.in.samples_per_frame > 1024)) { diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c index 987292d30..8754691bb 100644 --- a/libhb/muxmp4.c +++ b/libhb/muxmp4.c @@ -382,6 +382,8 @@ static int MP4Init( hb_mux_object_t * m ) case HB_ACODEC_FFAAC: case HB_ACODEC_CA_AAC: case HB_ACODEC_CA_HAAC: + case HB_ACODEC_FDK_AAC: + case HB_ACODEC_FDK_HAAC: case HB_ACODEC_LAME: case HB_ACODEC_MP3: case HB_ACODEC_DCA_HD: @@ -397,6 +399,8 @@ static int MP4Init( hb_mux_object_t * m ) case HB_ACODEC_FFAAC: case HB_ACODEC_CA_AAC: case HB_ACODEC_CA_HAAC: + case HB_ACODEC_FDK_AAC: + case HB_ACODEC_FDK_HAAC: { audio_type = MP4_MPEG4_AUDIO_TYPE; config_bytes = audio->priv.config.extradata.bytes; diff --git a/libhb/work.c b/libhb/work.c index 575bebdbd..f957e2fbd 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -146,6 +146,8 @@ hb_work_object_t * hb_codec_encoder( int codec ) case HB_ACODEC_CA_AAC: return hb_get_work( WORK_ENC_CA_AAC ); case HB_ACODEC_CA_HAAC:return hb_get_work( WORK_ENC_CA_HAAC ); case HB_ACODEC_FFAAC: + case HB_ACODEC_FDK_AAC: + case HB_ACODEC_FDK_HAAC: { w = hb_get_work( WORK_ENCAVCODEC_AUDIO ); w->codec_param = AV_CODEC_ID_AAC; |