summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/ffmpeg/module.defs1
-rw-r--r--libhb/common.c16
-rw-r--r--libhb/common.h3
-rw-r--r--libhb/encavcodecaudio.c (renamed from libhb/encac3.c)106
-rw-r--r--libhb/hb.c7
-rw-r--r--libhb/internal.h2
-rw-r--r--libhb/muxmkv.c1
-rw-r--r--libhb/muxmp4.c1
-rw-r--r--libhb/work.c17
9 files changed, 119 insertions, 35 deletions
diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs
index 243b314ef..8572bae2f 100644
--- a/contrib/ffmpeg/module.defs
+++ b/contrib/ffmpeg/module.defs
@@ -19,6 +19,7 @@ FFMPEG.CONFIGURE.extra = \
--disable-dxva2 \
--enable-bzlib \
--enable-encoder=ac3 \
+ --enable-encoder=aac \
--enable-encoder=mpeg4 \
--enable-encoder=mpeg2video \
--enable-encoder=snow \
diff --git a/libhb/common.c b/libhb/common.c
index 868cafbcb..cc4f5ec0c 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -222,6 +222,22 @@ void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, in
}
break;
+ case HB_ACODEC_FFAAC:
+ *low = 32 * channels;
+ if (samplerate > 24000)
+ {
+ *high = 160 * channels;
+ if (*high > 768)
+ *high = 768;
+ }
+ else
+ {
+ *high = 96 * channels;
+ if (*high > 480)
+ *high = 480;
+ }
+ break;
+
case HB_ACODEC_VORBIS:
*high = channels * 80;
if (samplerate > 24000)
diff --git a/libhb/common.h b/libhb/common.h
index 14af50d8a..ee3bc3b98 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -321,6 +321,7 @@ struct hb_job_s
#define HB_ACODEC_FFMPEG 0x00008000
#define HB_ACODEC_CA_AAC 0x00010000
#define HB_ACODEC_CA_HAAC 0x00020000
+#define HB_ACODEC_FFAAC 0x00040000
#define HB_ACODEC_PASS_FLAG 0x40000000
#define HB_ACODEC_PASS_MASK (HB_ACODEC_AC3 | HB_ACODEC_DCA)
#define HB_ACODEC_AC3_PASS (HB_ACODEC_AC3 | HB_ACODEC_PASS_FLAG)
@@ -791,7 +792,7 @@ extern hb_work_object_t hb_encvorbis;
extern hb_work_object_t hb_muxer;
extern hb_work_object_t hb_encca_aac;
extern hb_work_object_t hb_encca_haac;
-extern hb_work_object_t hb_encac3;
+extern hb_work_object_t hb_encavcodeca;
#define FILTER_OK 0
#define FILTER_DELAY 1
diff --git a/libhb/encac3.c b/libhb/encavcodecaudio.c
index d0c27f419..a295dc368 100644
--- a/libhb/encac3.c
+++ b/libhb/encavcodecaudio.c
@@ -1,4 +1,4 @@
-/* $Id: encac3.c,v 1.23 2005/10/13 23:47:06 titer Exp $
+/* $Id: encavcodeca.c,v 1.23 2005/10/13 23:47:06 titer Exp $
This file is part of the HandBrake source code.
Homepage: <http://handbrake.fr/>.
@@ -7,6 +7,7 @@
#include "hb.h"
#include "hbffmpeg.h"
#include "downmix.h"
+#include "libavcodec/audioconvert.h"
struct hb_work_private_s
{
@@ -14,29 +15,27 @@ struct hb_work_private_s
AVCodecContext * context;
int out_discrete_channels;
+ int samples_per_frame;
unsigned long input_samples;
unsigned long output_bytes;
hb_list_t * list;
uint8_t * buf;
};
-int encac3Init( hb_work_object_t *, hb_job_t * );
-int encac3Work( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
-void encac3Close( hb_work_object_t * );
+static int encavcodecaInit( hb_work_object_t *, hb_job_t * );
+static int encavcodecaWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+static void encavcodecaClose( hb_work_object_t * );
-#define AC3_SAMPLES_PER_FRAME 1536
-#define AC3_MAX_CODED_FRAME_SIZE 3840
-
-hb_work_object_t hb_encac3 =
+hb_work_object_t hb_encavcodeca =
{
- WORK_ENCAC3,
- "AC-3 encoder (libavcodec)",
- encac3Init,
- encac3Work,
- encac3Close
+ WORK_ENCAVCODEC_AUDIO,
+ "AVCodec Audio encoder (libavcodec)",
+ encavcodecaInit,
+ encavcodecaWork,
+ encavcodecaClose
};
-int encac3Init( hb_work_object_t * w, hb_job_t * job )
+static int encavcodecaInit( hb_work_object_t * w, hb_job_t * job )
{
AVCodec * codec;
AVCodecContext * context;
@@ -48,20 +47,24 @@ int encac3Init( hb_work_object_t * w, hb_job_t * job )
pv->job = job;
pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
- pv->input_samples = AC3_SAMPLES_PER_FRAME * pv->out_discrete_channels;
- pv->output_bytes = AC3_MAX_CODED_FRAME_SIZE;
-
- pv->buf = malloc( pv->input_samples * sizeof( float ) );
- codec = avcodec_find_encoder( CODEC_ID_AC3 );
+ codec = avcodec_find_encoder( w->codec_param );
if( !codec )
{
- hb_log( "encac3Init: avcodec_find_encoder "
+ hb_log( "encavcodecaInit: avcodec_find_encoder "
"failed" );
+ return 1;
}
context = avcodec_alloc_context();
avcodec_get_context_defaults3(context, codec);
+ int ret = av_set_string3( context, "stereo_mode", "ms_off", 1, NULL );
+ /* Let avutil sanity check the options for us*/
+ if( ret == AVERROR(ENOENT) )
+ hb_log( "avcodec options: Unknown option %s", "stereo_mode" );
+ if( ret == AVERROR(EINVAL) )
+ hb_log( "avcodec options: Bad argument %s=%s", "stereo_mode", "ms_off" ? "ms_off" : "(null)" );
+
context->channel_layout = AV_CH_LAYOUT_STEREO;
switch( audio->config.out.mixdown )
{
@@ -80,23 +83,41 @@ int encac3Init( hb_work_object_t * w, hb_job_t * job )
break;
default:
- hb_log(" encac3Init: bad mixdown" );
+ hb_log(" encavcodecaInit: bad mixdown" );
break;
}
context->bit_rate = audio->config.out.bitrate * 1000;
context->sample_rate = audio->config.out.samplerate;
context->channels = pv->out_discrete_channels;
- context->sample_fmt = AV_SAMPLE_FMT_FLT;
+ // Try to set format to float. Fallback to whatever is supported.
+ hb_ff_set_sample_fmt( context, codec );
if( hb_avcodec_open( context, codec ) )
{
- hb_log( "encac3Init: avcodec_open failed" );
+ hb_log( "encavcodecaInit: avcodec_open failed" );
+ return 1;
}
pv->context = context;
+ pv->samples_per_frame = context->frame_size;
+ pv->input_samples = pv->samples_per_frame * pv->out_discrete_channels;
+
+ // Set a reasonable maximum output size
+ pv->output_bytes = context->frame_size *
+ (av_get_bits_per_sample_fmt(context->sample_fmt) / 8) *
+ context->channels;
+
+ pv->buf = malloc( pv->input_samples * sizeof( float ) );
+
pv->list = hb_list_init();
+ if ( w->codec_param == CODEC_ID_AAC && context->extradata )
+ {
+ memcpy( w->config->aac.bytes, context->extradata, context->extradata_size );
+ w->config->aac.length = context->extradata_size;
+ }
+
return 0;
}
@@ -105,7 +126,7 @@ int encac3Init( hb_work_object_t * w, hb_job_t * job )
***********************************************************************
*
**********************************************************************/
-void encac3Close( hb_work_object_t * w )
+static void encavcodecaClose( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
@@ -113,7 +134,7 @@ void encac3Close( hb_work_object_t * w )
{
if( pv->context )
{
- hb_deep_log( 2, "encac3: closing libavcodec" );
+ hb_deep_log( 2, "encavcodeca: closing libavcodec" );
if ( pv->context->codec )
avcodec_flush_buffers( pv->context );
hb_avcodec_close( pv->context );
@@ -176,7 +197,34 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
break;
}
hb_layout_remap( map, &hb_smpte_chan_map, layout,
- (float*)pv->buf, AC3_SAMPLES_PER_FRAME);
+ (float*)pv->buf, pv->samples_per_frame);
+ }
+
+ // Do we need to convert our internal float format?
+ if ( pv->context->sample_fmt != AV_SAMPLE_FMT_FLT )
+ {
+ int isamp, osamp;
+ AVAudioConvert *ctx;
+
+ isamp = av_get_bits_per_sample_fmt( AV_SAMPLE_FMT_FLT ) / 8;
+ osamp = av_get_bits_per_sample_fmt( pv->context->sample_fmt ) / 8;
+ ctx = av_audio_convert_alloc( pv->context->sample_fmt, 1,
+ AV_SAMPLE_FMT_FLT, 1,
+ NULL, 0 );
+
+ // get output buffer size then malloc a buffer
+ //nsamples = out_size / isamp;
+ //buffer = av_malloc( nsamples * sizeof(hb_sample_t) );
+
+ // we're doing straight sample format conversion which
+ // behaves as if there were only one channel.
+ const void * const ibuf[6] = { pv->buf };
+ void * const obuf[6] = { pv->buf };
+ const int istride[6] = { isamp };
+ const int ostride[6] = { osamp };
+
+ av_audio_convert( ctx, obuf, ostride, ibuf, istride, pv->input_samples );
+ av_audio_convert_free( ctx );
}
buf = hb_buffer_init( pv->output_bytes );
@@ -184,7 +232,7 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
(short*)pv->buf );
buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate;
- buf->stop = buf->start + 90000 * AC3_SAMPLES_PER_FRAME / audio->config.out.samplerate;
+ buf->stop = buf->start + 90000 * pv->samples_per_frame / audio->config.out.samplerate;
buf->frametype = HB_FRAME_AUDIO;
@@ -195,7 +243,7 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
}
else if (buf->size < 0)
{
- hb_log( "encac3: avcodec_encode_audio failed" );
+ hb_log( "encavcodeca: avcodec_encode_audio failed" );
hb_buffer_close( &buf );
return NULL;
}
@@ -208,7 +256,7 @@ static hb_buffer_t * Encode( hb_work_object_t * w )
***********************************************************************
*
**********************************************************************/
-int encac3Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
+static int encavcodecaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
hb_buffer_t ** buf_out )
{
hb_work_private_t * pv = w->private_data;
diff --git a/libhb/hb.c b/libhb/hb.c
index a4761a867..1e3686cf2 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -262,6 +262,9 @@ void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec)
break;
}
}
+ if ( *fmt == -1 )
+ context->sample_fmt = codec->sample_fmts[0];
+
}
}
@@ -415,7 +418,7 @@ hb_handle_t * hb_init( int verbose, int update_check )
hb_register( &hb_encca_aac );
hb_register( &hb_encca_haac );
#endif
- hb_register( &hb_encac3 );
+ hb_register( &hb_encavcodeca );
return h;
}
@@ -517,7 +520,7 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
hb_register( &hb_encca_aac );
hb_register( &hb_encca_haac );
#endif
- hb_register( &hb_encac3 );
+ hb_register( &hb_encavcodeca );
return h;
}
diff --git a/libhb/internal.h b/libhb/internal.h
index 700084e78..f92ce263a 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -360,7 +360,7 @@ enum
WORK_ENCVORBIS,
WORK_ENC_CA_AAC,
WORK_ENC_CA_HAAC,
- WORK_ENCAC3,
+ WORK_ENCAVCODEC_AUDIO,
WORK_MUX
};
diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c
index 7256843ff..654c51bc0 100644
--- a/libhb/muxmkv.c
+++ b/libhb/muxmkv.c
@@ -229,6 +229,7 @@ static int MKVInit( hb_mux_object_t * m )
}
break;
case HB_ACODEC_FAAC:
+ case HB_ACODEC_FFAAC:
case HB_ACODEC_CA_AAC:
case HB_ACODEC_CA_HAAC:
track->codecPrivate = audio->priv.config.aac.bytes;
diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c
index 3df70dc17..b9c7637e8 100644
--- a/libhb/muxmp4.c
+++ b/libhb/muxmp4.c
@@ -420,6 +420,7 @@ rate_found2:
}
}
else if( audio->config.out.codec == HB_ACODEC_FAAC ||
+ audio->config.out.codec == HB_ACODEC_FFAAC ||
audio->config.out.codec == HB_ACODEC_CA_AAC ||
audio->config.out.codec == HB_ACODEC_CA_HAAC )
{
diff --git a/libhb/work.c b/libhb/work.c
index f1db58b81..f0a81fa75 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -121,6 +121,7 @@ hb_work_object_t * hb_codec_decoder( int codec )
hb_work_object_t * hb_codec_encoder( int codec )
{
+ hb_work_object_t * w;
switch( codec )
{
case HB_ACODEC_FAAC: return hb_get_work( WORK_ENCFAAC );
@@ -128,7 +129,18 @@ hb_work_object_t * hb_codec_encoder( int codec )
case HB_ACODEC_VORBIS: return hb_get_work( WORK_ENCVORBIS );
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_AC3: return hb_get_work( WORK_ENCAC3 );
+ case HB_ACODEC_FFAAC:
+ {
+ w = hb_get_work( WORK_ENCAVCODEC_AUDIO );
+ w->codec_param = CODEC_ID_AAC;
+ return w;
+ }
+ case HB_ACODEC_AC3:
+ {
+ w = hb_get_work( WORK_ENCAVCODEC_AUDIO );
+ w->codec_param = CODEC_ID_AC3;
+ return w;
+ }
}
return NULL;
}
@@ -371,8 +383,9 @@ void hb_display_job_info( hb_job_t * job )
( ( audio->config.out.codec == HB_ACODEC_LAME ) ? "lame" :
( ( audio->config.out.codec == HB_ACODEC_CA_AAC ) ? "ca_aac" :
( ( audio->config.out.codec == HB_ACODEC_CA_HAAC ) ? "ca_haac" :
+ ( ( audio->config.out.codec == HB_ACODEC_FFAAC ) ? "ffaac" :
( ( audio->config.out.codec == HB_ACODEC_AC3 ) ? "ffac3" :
- "vorbis" ) ) ) ) );
+ "vorbis" ) ) ) ) ) );
hb_log( " + bitrate: %d kbps, samplerate: %d Hz", audio->config.out.bitrate, audio->config.out.samplerate );
}
}