diff options
author | jstebbins <[email protected]> | 2010-05-13 14:48:18 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2010-05-13 14:48:18 +0000 |
commit | 8ed88a9c59f4bd74804290dcc87e7483ce06f896 (patch) | |
tree | 6bc22c0294d03b445427096ac7c08ab50697080c | |
parent | 675c7146fe298cd566fa8e446c762a3ded12e0d7 (diff) |
allow mono mixdown with lame encoder
enable mono mode in lame encoder when mixdown is mono.
use lame_encode_buffer_float instead of lame_encode_buffer_interleave. this
eliminates the clipping issue in lame without reducing the level of the input.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3294 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | gtk/src/hb-backend.c | 6 | ||||
-rw-r--r-- | libhb/deca52.c | 2 | ||||
-rw-r--r-- | libhb/decavcodec.c | 4 | ||||
-rw-r--r-- | libhb/enclame.c | 35 | ||||
-rw-r--r-- | libhb/work.c | 35 |
5 files changed, 35 insertions, 47 deletions
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index 97f7d8df1..94fa5b0fa 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -1393,7 +1393,7 @@ ghb_grey_combo_options(GtkBuilder *builder) gboolean allow_dolby = TRUE; gboolean allow_dpl2 = TRUE; gboolean allow_6ch = TRUE; - allow_mono = acodec & ~HB_ACODEC_LAME; + allow_mono = TRUE; allow_6ch = acodec & ~HB_ACODEC_LAME; if (audio) { @@ -1451,7 +1451,7 @@ ghb_get_best_mix(gint titleindex, gint track, gint acodec, gint mix) audio = get_hb_audio(titleindex, track); if (audio) { - allow_mono = (acodec & ~HB_ACODEC_LAME); + allow_mono = TRUE; gint layout = audio->in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK; allow_stereo = ((layout == HB_INPUT_CH_LAYOUT_MONO && !allow_mono) || layout >= HB_INPUT_CH_LAYOUT_STEREO); @@ -4097,7 +4097,7 @@ ghb_validate_audio(signal_user_data_t *ud) gboolean allow_dolby = TRUE; gboolean allow_dpl2 = TRUE; gboolean allow_6ch = TRUE; - allow_mono = (codec & ~HB_ACODEC_LAME); + allow_mono = TRUE; gint layout = taudio->in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK; allow_stereo = ((layout == HB_INPUT_CH_LAYOUT_MONO && !allow_mono) || layout >= HB_INPUT_CH_LAYOUT_STEREO); diff --git a/libhb/deca52.c b/libhb/deca52.c index 3cb2f3355..785bf6aef 100644 --- a/libhb/deca52.c +++ b/libhb/deca52.c @@ -101,8 +101,6 @@ static int deca52Init( hb_work_object_t * w, hb_job_t * job ) work.c has already done some of this deduction for us in do_job() */ pv->flags_out = HB_AMIXDOWN_GET_A52_FORMAT(audio->config.out.mixdown); - if ( audio->config.out.codec == HB_ACODEC_LAME ) - pv->flags_out |= A52_ADJUST_LEVEL; /* pass the number of channels used into the private work data */ /* will only be actually used if we're not doing AC3 passthru */ diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index 0a9f63fec..31c0b751a 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -210,8 +210,6 @@ static int decavcodecInit( hb_work_object_t * w, hb_job_t * job ) pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, w->audio->config.out.mixdown); hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_qt_chan_map ); - if ( w->audio->config.out.codec == HB_ACODEC_LAME ) - hb_downmix_adjust_level( pv->downmix ); } return 0; @@ -1101,8 +1099,6 @@ static int decavcodecviInit( hb_work_object_t * w, hb_job_t * job ) pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, w->audio->config.out.mixdown); hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_qt_chan_map ); - if ( w->audio->config.out.codec == HB_ACODEC_LAME ) - hb_downmix_adjust_level( pv->downmix ); } return 0; diff --git a/libhb/enclame.c b/libhb/enclame.c index a3f4a3882..9692eef29 100644 --- a/libhb/enclame.c +++ b/libhb/enclame.c @@ -29,6 +29,7 @@ struct hb_work_private_s lame_global_flags * lame; int done; + int out_discrete_channels; unsigned long input_samples; unsigned long output_bytes; uint8_t * buf; @@ -41,6 +42,7 @@ int enclameInit( hb_work_object_t * w, hb_job_t * job ) { hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) ); hb_audio_t * audio = w->audio; + w->private_data = pv; pv->job = job; @@ -53,16 +55,25 @@ int enclameInit( hb_work_object_t * w, hb_job_t * job ) lame_set_VBR_mean_bitrate_kbps( pv->lame, audio->config.out.bitrate ); lame_set_in_samplerate( pv->lame, audio->config.out.samplerate ); lame_set_out_samplerate( pv->lame, audio->config.out.samplerate ); - lame_init_params( pv->lame ); + + pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); // Lame's default encoding mode is JOINT_STEREO. This subtracts signal // that is "common" to left and right (within some threshold) and encodes // it separately. This improves quality at low bitrates, but hurts // imaging (channel separation) at higher bitrates. So if the bitrate // is suffeciently high, use regular STEREO mode. - if ( audio->config.out.bitrate >= 128 ) + if ( pv->out_discrete_channels == 1 ) + { + lame_set_mode( pv->lame, MONO ); + lame_set_num_channels( pv->lame, 1 ); + } + else if ( audio->config.out.bitrate >= 128 ) + { lame_set_mode( pv->lame, STEREO ); + } + lame_init_params( pv->lame ); - pv->input_samples = 1152 * 2; + pv->input_samples = 1152 * pv->out_discrete_channels; pv->output_bytes = LAME_MAXMP3BUFFER; pv->buf = malloc( pv->input_samples * sizeof( float ) ); @@ -98,9 +109,9 @@ static hb_buffer_t * Encode( hb_work_object_t * w ) hb_work_private_t * pv = w->private_data; hb_audio_t * audio = w->audio; hb_buffer_t * buf; - int16_t samples_s16[1152 * 2]; + float samples[2][1152]; uint64_t pts, pos; - int i; + int i, j; if( hb_list_bytes( pv->list ) < pv->input_samples * sizeof( float ) ) { @@ -110,16 +121,22 @@ static hb_buffer_t * Encode( hb_work_object_t * w ) hb_list_getbytes( pv->list, pv->buf, pv->input_samples * sizeof( float ), &pts, &pos); - for( i = 0; i < 1152 * 2; i++ ) + memset(samples, 0, 2*1152*sizeof(float)); + for( i = 0; i < 1152; i++ ) { - samples_s16[i] = ((float*) pv->buf)[i]; + for( j = 0; j < pv->out_discrete_channels; j++ ) + { + samples[j][i] = ((float *) pv->buf)[(pv->out_discrete_channels * i + j)]; + } } buf = hb_buffer_init( pv->output_bytes ); - buf->start = pts + 90000 * pos / 2 / sizeof( float ) / audio->config.out.samplerate; + buf->start = pts + 90000 * pos / pv->out_discrete_channels / sizeof( float ) / audio->config.out.samplerate; buf->stop = buf->start + 90000 * 1152 / audio->config.out.samplerate; - buf->size = lame_encode_buffer_interleaved( pv->lame, samples_s16, + buf->size = lame_encode_buffer_float( + pv->lame, samples[0], samples[1], 1152, buf->data, LAME_MAXMP3BUFFER ); + buf->frametype = HB_FRAME_AUDIO; if( !buf->size ) diff --git a/libhb/work.c b/libhb/work.c index 838e50702..6c783032a 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -568,16 +568,13 @@ static void do_job( hb_job_t * job, int cpu_count ) // So if the encoder is lame we need the output to be stereo (or multichannel // matrixed into stereo like dpl). If the decoder is not AC3 or DCA the // encoder has to handle the input format since we can't do a mixdown. -#define STEREO_ONLY(a) ( a->config.out.codec & HB_ACODEC_LAME ) - switch (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) { // stereo input or something not handled below default: case HB_INPUT_CH_LAYOUT_STEREO: // mono gets mixed up to stereo & more than stereo gets mixed down - if ( STEREO_ONLY( audio ) || - audio->config.out.mixdown > HB_AMIXDOWN_STEREO) + if ( audio->config.out.mixdown > HB_AMIXDOWN_STEREO ) { audio->config.out.mixdown = HB_AMIXDOWN_STEREO; } @@ -585,23 +582,15 @@ static void do_job( hb_job_t * job, int cpu_count ) // mono input case HB_INPUT_CH_LAYOUT_MONO: - if ( STEREO_ONLY( audio ) ) - { - audio->config.out.mixdown = HB_AMIXDOWN_STEREO; - } - else - { - // everything else passes through - audio->config.out.mixdown = HB_AMIXDOWN_MONO; - } + // everything else passes through + audio->config.out.mixdown = HB_AMIXDOWN_MONO; break; // dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input // the A52 flags don't allow for a way to distinguish between DPL1 and // DPL2 on a DVD so we always assume a DPL1 source for A52_DOLBY. case HB_INPUT_CH_LAYOUT_DOLBY: - if ( STEREO_ONLY( audio ) || - audio->config.out.mixdown > HB_AMIXDOWN_DOLBY ) + if ( audio->config.out.mixdown > HB_AMIXDOWN_DOLBY ) { audio->config.out.mixdown = HB_AMIXDOWN_DOLBY; } @@ -610,8 +599,7 @@ static void do_job( hb_job_t * job, int cpu_count ) // 4 channel discrete case HB_INPUT_CH_LAYOUT_2F2R: case HB_INPUT_CH_LAYOUT_3F1R: - if ( STEREO_ONLY( audio ) || - audio->config.out.mixdown > HB_AMIXDOWN_DOLBY ) + if ( audio->config.out.mixdown > HB_AMIXDOWN_DOLBY ) { audio->config.out.mixdown = HB_AMIXDOWN_DOLBY; } @@ -619,18 +607,7 @@ static void do_job( hb_job_t * job, int cpu_count ) // 5 or 6 channel discrete case HB_INPUT_CH_LAYOUT_3F2R: - if ( STEREO_ONLY( audio ) ) - { - if ( audio->config.out.mixdown < HB_AMIXDOWN_STEREO ) - { - audio->config.out.mixdown = HB_AMIXDOWN_STEREO; - } - else if ( audio->config.out.mixdown > HB_AMIXDOWN_DOLBYPLII ) - { - audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII; - } - } - else if ( ! ( audio->config.in.channel_layout & + if ( ! ( audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE ) ) { // we don't do 5 channel discrete so mixdown to DPLII |