diff options
-rw-r--r-- | libhb/common.c | 93 | ||||
-rw-r--r-- | libhb/common.h | 3 | ||||
-rw-r--r-- | libhb/work.c | 54 | ||||
-rw-r--r-- | test/test.c | 122 |
4 files changed, 162 insertions, 110 deletions
diff --git a/libhb/common.c b/libhb/common.c index 3788d3109..d800267fe 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -37,7 +37,6 @@ hb_rate_t hb_audio_bitrates[] = { "512", 512 }, { "576", 576 }, { "640", 640 }, { "768", 768 } }; int hb_audio_bitrates_count = sizeof( hb_audio_bitrates ) / sizeof( hb_rate_t ); -int hb_audio_bitrates_default = 8; /* 128 kbps */ static hb_error_handler_t *error_handler = NULL; @@ -279,33 +278,45 @@ int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown ) return bitrate; } -int hb_get_best_mixdown( uint32_t codec, int layout ) +int hb_get_best_mixdown( uint32_t codec, int layout, int mixdown ) { + + int best_mixdown; + + if (codec & HB_ACODEC_PASS_FLAG) + { + // Audio pass-thru. No mixdown. + return 0; + } switch (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 - return HB_AMIXDOWN_STEREO; + best_mixdown = HB_AMIXDOWN_STEREO; + break; // mono input case HB_INPUT_CH_LAYOUT_MONO: // everything else passes through - return HB_AMIXDOWN_MONO; + best_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: - return HB_AMIXDOWN_DOLBY; + best_mixdown = HB_AMIXDOWN_DOLBY; + break; // 4 channel discrete case HB_INPUT_CH_LAYOUT_2F2R: case HB_INPUT_CH_LAYOUT_3F1R: // a52dec and libdca can't upmix to 6ch, // so we must downmix these. - return HB_AMIXDOWN_DOLBYPLII; + best_mixdown = HB_AMIXDOWN_DOLBYPLII; + break; // 5 or 6 channel discrete case HB_INPUT_CH_LAYOUT_3F2R: @@ -314,71 +325,47 @@ int hb_get_best_mixdown( uint32_t codec, int layout ) // we don't do 5 channel discrete so mixdown to DPLII // a52dec and libdca can't upmix to 6ch, // so we must downmix this. - return HB_AMIXDOWN_DOLBYPLII; + best_mixdown = HB_AMIXDOWN_DOLBYPLII; } else { switch (codec) { case HB_ACODEC_LAME: - return HB_AMIXDOWN_DOLBYPLII; + best_mixdown = HB_AMIXDOWN_DOLBYPLII; + break; default: - return HB_AMIXDOWN_6CH; + best_mixdown = HB_AMIXDOWN_6CH; + break; } } + break; } + // return the best that is not greater than the requested mixdown + // 0 means the caller requested the best available mixdown + if( best_mixdown > mixdown && mixdown != 0 ) + best_mixdown = mixdown; + + return best_mixdown; } int hb_get_default_mixdown( uint32_t codec, int layout ) { - switch (layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) + int mixdown; + switch (codec) { - // stereo input or something not handled below + // the AC3 encoder defaults to the best mixdown up to 6-channel + case HB_ACODEC_AC3: + mixdown = HB_AMIXDOWN_6CH; + break; + // other encoders default to the best mixdown up to DPLII default: - case HB_INPUT_CH_LAYOUT_STEREO: - // mono gets mixed up to stereo & more than stereo gets mixed down - return HB_AMIXDOWN_STEREO; - - // mono input - case HB_INPUT_CH_LAYOUT_MONO: - // everything else passes through - return HB_AMIXDOWN_MONO; - - // 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: - return HB_AMIXDOWN_DOLBY; - - // 4 channel discrete - case HB_INPUT_CH_LAYOUT_2F2R: - case HB_INPUT_CH_LAYOUT_3F1R: - // a52dec and libdca can't upmix to 6ch, - // so we must downmix these. - return HB_AMIXDOWN_DOLBYPLII; - - // 5 or 6 channel discrete - case HB_INPUT_CH_LAYOUT_3F2R: - if ( ! ( layout & HB_INPUT_CH_LAYOUT_HAS_LFE ) ) - { - // we don't do 5 channel discrete so mixdown to DPLII - // a52dec and libdca can't upmix to 6ch, - // so we must downmix this. - return HB_AMIXDOWN_DOLBYPLII; - } - else - { - switch (codec) - { - case HB_ACODEC_AC3: - return HB_AMIXDOWN_6CH; - - default: - return HB_AMIXDOWN_DOLBYPLII; - } - } + mixdown = HB_AMIXDOWN_DOLBYPLII; + break; } + // return the best available mixdown up to the selected default + return hb_get_best_mixdown( codec, layout, mixdown ); } /********************************************************************** diff --git a/libhb/common.h b/libhb/common.h index 2a3d07038..7383bf627 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -145,12 +145,11 @@ extern int hb_audio_rates_count; extern int hb_audio_rates_default; extern hb_rate_t hb_audio_bitrates[]; extern int hb_audio_bitrates_count; -extern int hb_audio_bitrates_default; extern hb_mixdown_t hb_audio_mixdowns[]; extern int hb_audio_mixdowns_count; int hb_mixdown_get_mixdown_from_short_name( const char * short_name ); const char * hb_mixdown_get_short_name_from_mixdown( int amixdown ); -int hb_get_best_mixdown( uint32_t codec, int layout ); +int hb_get_best_mixdown( uint32_t codec, int layout, int mixdown ); int hb_get_default_mixdown( uint32_t codec, int layout ); int hb_find_closest_audio_bitrate(int bitrate); void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, int *low, int *high); diff --git a/libhb/work.c b/libhb/work.c index c9d32de91..ebbc408bf 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -559,28 +559,30 @@ static void do_job( hb_job_t * job, int cpu_count ) } int requested_mixdown = 0; - int best_mixdown = 0; int requested_mixdown_index = 0; + int best_mixdown = 0; + int requested_bitrate = 0; + int best_bitrate = 0; for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i ); best_mixdown = hb_get_best_mixdown( audio->config.out.codec, - audio->config.in.channel_layout ); + audio->config.in.channel_layout, 0 ); /* sense-check the current mixdown options */ /* sense-check the requested mixdown */ if( audio->config.out.mixdown == 0 && - audio->config.out.codec != HB_ACODEC_AC3_PASS && - audio->config.out.codec != HB_ACODEC_DCA_PASS ) + !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) ) { /* * Mixdown wasn't specified and this is not pass-through, * set a default mixdown */ - audio->config.out.mixdown = best_mixdown; + audio->config.out.mixdown = hb_get_default_mixdown( audio->config.out.codec, + audio->config.in.channel_layout ); for (j = 0; j < hb_audio_mixdowns_count; j++) { if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) @@ -616,10 +618,50 @@ static void do_job( hb_job_t * job, int cpu_count ) if (hb_audio_mixdowns[j].amixdown == audio->config.out.mixdown) { hb_log("work: sanitizing track %i mixdown %s to %s", i, hb_audio_mixdowns[requested_mixdown_index].human_readable_name, hb_audio_mixdowns[j].human_readable_name); - break; + break; } } } + + /* sense-check the current bitrates */ + + /* sense-check the requested bitrate */ + if( audio->config.out.bitrate == 0 && + !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) ) + { + /* + * Bitrate wasn't specified and this is not pass-through, + * set a default bitrate + */ + audio->config.out.bitrate = hb_get_default_audio_bitrate( audio->config.out.codec, + audio->config.out.samplerate, + audio->config.out.mixdown ); + + hb_log( "work: bitrate not specified, track %d setting bitrate %d", + i, audio->config.out.bitrate ); + } + + /* log the requested bitrate */ + requested_bitrate = audio->config.out.bitrate; + best_bitrate = hb_get_best_audio_bitrate( audio->config.out.codec, + audio->config.out.bitrate, + audio->config.out.samplerate, + audio->config.out.mixdown ); + + if ( !( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) ) + { + if ( audio->config.out.bitrate != best_bitrate ) + { + audio->config.out.bitrate = best_bitrate; + } + } + + if ( audio->config.out.bitrate != requested_bitrate ) + { + /* log the output bitrate */ + hb_log( "work: sanitizing track %d audio bitrate %d to %d", + i, requested_bitrate, audio->config.out.bitrate); + } if (audio->config.out.codec == HB_ACODEC_VORBIS) audio->priv.config.vorbis.language = audio->config.lang.simple; diff --git a/test/test.c b/test/test.c index 14046cf1d..2af240882 100644 --- a/test/test.c +++ b/test/test.c @@ -74,8 +74,11 @@ static char * arates = NULL; static char * abitrates = NULL; static char * acodecs = NULL; static char * anames = NULL; +#ifdef __APPLE_CC__ +static int default_acodec = HB_ACODEC_CA_AAC; +#else static int default_acodec = HB_ACODEC_FAAC; -static int default_abitrate = 160; +#endif static int audio_explicit = 0; static char ** subtracks = NULL; static char ** subforce = NULL; @@ -1635,6 +1638,52 @@ static int HandleEvents( hb_handle_t * h ) } } /* Sample Rate */ + + /* Audio Mixdown */ + i = 0; + if ( mixdowns ) + { + char * token = strtok(mixdowns, ","); + if (token == NULL) + token = mixdowns; + while ( token != NULL ) + { + mixdown = hb_mixdown_get_mixdown_from_short_name(token); + audio = hb_list_audio_config_item(job->list_audio, i); + if( audio != NULL ) + { + audio->out.mixdown = mixdown; + if( (++i) >= num_audio_tracks ) + break; /* We have more inputs than audio tracks, oops */ + } + else + { + fprintf(stderr, "Ignoring mixdown, no audio tracks\n"); + } + token = strtok(NULL, ","); + } + } + if (i < num_audio_tracks) + { + /* We have fewer inputs than audio tracks, use the default mixdown for the rest. Unless + * we only have one input, then use that. + */ + int use_default = 0; + if (i != 1) + use_default = 1; + + for (; i < num_audio_tracks; i++) + { + audio = hb_list_audio_config_item(job->list_audio, i); + if (use_default) + { + // Get default for this tracks codec and layout + mixdown = hb_get_default_mixdown( audio->out.codec, audio->in.channel_layout ); + } + audio->out.mixdown = mixdown; + } + } + /* Audio Mixdown */ /* Audio Bitrate */ i = 0; @@ -1667,11 +1716,19 @@ static int HandleEvents( hb_handle_t * h ) * for the remaining tracks. Unless we only have one input, then use * that for all tracks. */ + int use_default = 0; if (i != 1) - abitrate = default_abitrate; + use_default = 1; + for (; i < num_audio_tracks; i++) { audio = hb_list_audio_config_item(job->list_audio, i); + if (use_default) + { + abitrate = hb_get_default_audio_bitrate( + audio->out.codec, audio->out.samplerate, + audio->out.mixdown ); + } audio->out.bitrate = abitrate; } } @@ -1717,45 +1774,6 @@ static int HandleEvents( hb_handle_t * h ) } /* Audio DRC */ - /* Audio Mixdown */ - i = 0; - if ( mixdowns ) - { - char * token = strtok(mixdowns, ","); - if (token == NULL) - token = mixdowns; - while ( token != NULL ) - { - mixdown = hb_mixdown_get_mixdown_from_short_name(token); - audio = hb_list_audio_config_item(job->list_audio, i); - if( audio != NULL ) - { - audio->out.mixdown = mixdown; - if( (++i) >= num_audio_tracks ) - break; /* We have more inputs than audio tracks, oops */ - } - else - { - fprintf(stderr, "Ignoring mixdown, no audio tracks\n"); - } - token = strtok(NULL, ","); - } - } - if (i < num_audio_tracks) - { - /* We have fewer inputs than audio tracks, use DPLII for the rest. Unless - * we only have one input, then use that. - */ - if (i != 1) - mixdown = HB_AMIXDOWN_DOLBYPLII; - for (; i < num_audio_tracks; i++) - { - audio = hb_list_audio_config_item(job->list_audio, i); - audio->out.mixdown = mixdown; - } - } - /* Audio Mixdown */ - /* Audio Track Names */ i = 0; if ( anames ) @@ -2401,7 +2419,7 @@ static void ShowHelp() " copy, copy:ac3 and copy:dts meaning passthrough.\n" " copy will passthrough either ac3 or dts.\n" " Separated by commas for more than one audio track.\n" - " (default: guessed)\n" ); + " (default: ca_aac)\n" ); #else fprintf( out, " -E, --aencoder <string> Audio encoder(s):\n" @@ -2409,14 +2427,16 @@ static void ShowHelp() " copy, copy:ac3 and copy:dts meaning passthrough.\n" " copy will passthrough either ac3 or dts.\n" " Separated by commas for more than one audio track.\n" - " (default: guessed)\n" ); + " (default: faac for mp4, lame for mkv)\n" ); #endif fprintf( out, - " -B, --ab <kb/s> Set audio bitrate(s) (default: 160)\n" + " -B, --ab <kb/s> Set audio bitrate(s) (default: depends on the\n" + " selected codec, mixdown and samplerate)\n" " Separated by commas for more than one audio track.\n" " -6, --mixdown <string> Format(s) for surround sound downmixing\n" " Separated by commas for more than one audio track.\n" - " (mono/stereo/dpl1/dpl2/6ch, default: dpl2)\n" + " (mono/stereo/dpl1/dpl2/6ch, default: up to 6ch for ac3,\n" + " up to dpl2 for other encoders)\n" " -R, --arate Set audio samplerate(s) (" ); for( i = 0; i < hb_audio_rates_count; i++ ) { @@ -3368,12 +3388,14 @@ static int CheckOptions( int argc, char ** argv ) mux = HB_MUX_IPOD; else mux = HB_MUX_MP4; - default_acodec = HB_ACODEC_FAAC; } else if( p && !strcasecmp(p, ".mkv" ) ) { mux = HB_MUX_MKV; - default_acodec = HB_ACODEC_AC3; +#ifndef __APPLE_CC__ + // default to Lame for MKV (except under OS X where Core Audio is available) + default_acodec = HB_ACODEC_LAME; +#endif } else { @@ -3389,12 +3411,14 @@ static int CheckOptions( int argc, char ** argv ) mux = HB_MUX_IPOD; else mux = HB_MUX_MP4; - default_acodec = HB_ACODEC_FAAC; } else if( !strcasecmp( format, "mkv" ) ) { mux = HB_MUX_MKV; - default_acodec = HB_ACODEC_AC3; +#ifndef __APPLE_CC__ + // default to Lame for MKV (except under OS X where Core Audio is available) + default_acodec = HB_ACODEC_LAME; +#endif } else { |