summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2013-03-03 16:18:16 +0000
committerjstebbins <[email protected]>2013-03-03 16:18:16 +0000
commit288639e626b5c550fdd33e49abf1b8e3a3fcd52e (patch)
tree0df5c1da8728a0706110984b675a0d3b7a350ba9 /libhb
parentb56a9d0fc23ca64f1d63afb797bdc07e1dffc357 (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.c9
-rw-r--r--libhb/common.h6
-rw-r--r--libhb/encavcodecaudio.c57
-rw-r--r--libhb/module.defs12
-rw-r--r--libhb/muxmkv.c5
-rw-r--r--libhb/muxmp4.c4
-rw-r--r--libhb/work.c2
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;