diff options
author | jstebbins <[email protected]> | 2010-10-08 18:55:03 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2010-10-08 18:55:03 +0000 |
commit | 0b489b411b69296262c74e02ec3bcf3eed38f7e3 (patch) | |
tree | a65956357de80bdaaf6588080ddf4e826ccfb63f | |
parent | 4947466a36cd72a238ea676c0c440ee19ae46bee (diff) |
add audio defaults and limits calculation to libhb
hb_get_audio_bitrate_limits()
Get the bitrate limits for a (codec,samplerate,mixdown) triplet
hb_get_best_audio_bitrate()
Given an input bitrate, sanitize it. Check low and high limits
and make sure it is in the set of allowed bitrates.
hb_get_default_audio_bitrate()
Get the default bitrate for a given (codec,samplerate,mixdown) triplet
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3578 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | gtk/src/audiohandler.c | 48 | ||||
-rw-r--r-- | gtk/src/hb-backend.c | 116 | ||||
-rw-r--r-- | gtk/src/hb-backend.h | 4 | ||||
-rw-r--r-- | libhb/common.c | 124 | ||||
-rw-r--r-- | libhb/common.h | 4 |
5 files changed, 169 insertions, 127 deletions
diff --git a/gtk/src/audiohandler.c b/gtk/src/audiohandler.c index 6ca014895..5288e3178 100644 --- a/gtk/src/audiohandler.c +++ b/gtk/src/audiohandler.c @@ -31,6 +31,7 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud) GValue *gval; int mux; gint bitrate; + gint sr = 48000; g_debug("ghb_adjust_audio_rate_combos ()"); mux = ghb_settings_combo_int(ud->settings, "FileFormat"); @@ -54,6 +55,10 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud) gval = ghb_widget_value(widget); bitrate = ghb_lookup_combo_int("AudioBitrate", gval); + widget = GHB_WIDGET(ud->builder, "AudioSamplerate"); + gval = ghb_widget_value(widget); + sr = ghb_lookup_combo_int("AudioSamplerate", gval); + select_acodec = acodec; if (mux == HB_MUX_MP4) { @@ -66,10 +71,19 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud) acodec = select_acodec; } + gboolean info_valid = FALSE; + if (ghb_get_audio_info (&ainfo, titleindex, track)) + { + info_valid = TRUE; + } + if (sr == 0) + { + sr = info_valid ? ainfo.samplerate : 48000; + } if (ghb_audio_is_passthru (select_acodec)) { ghb_set_default_bitrate_opts (ud->builder, 0, -1); - if (ghb_get_audio_info (&ainfo, titleindex, track)) + if (info_valid) { bitrate = ainfo.bitrate / 1000; @@ -91,7 +105,7 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud) int channels; mix = ghb_get_best_mix( titleindex, track, select_acodec, mix); channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mix); - bitrate = ghb_get_default_audio_bitrate(select_acodec, ainfo.samplerate, bitrate, channels); + bitrate = hb_get_default_audio_bitrate(select_acodec, sr, mix); ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix)); } ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(bitrate)); @@ -106,12 +120,11 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud) } ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(0)); } - gint channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mix); - bitrate = ghb_get_best_audio_bitrate(select_acodec, bitrate, channels); + bitrate = hb_get_best_audio_bitrate(select_acodec, bitrate, sr, mix); ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(bitrate)); int low, high; - ghb_get_audio_bitrate_limits(select_acodec, channels, &low, &high); + hb_get_audio_bitrate_limits(select_acodec, sr, mix, &low, &high); ghb_set_default_bitrate_opts (ud->builder, low, high); ghb_settings_take_value(ud->settings, "AudioEncoderActual", @@ -401,7 +414,7 @@ audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud) if (asettings != NULL) { br = ghb_settings_get_int(asettings, "AudioBitrate"); - sr = ghb_settings_get_int(asettings, "AudioSamplerate"); + sr = ghb_settings_combo_int(asettings, "AudioSamplerate"); mix_code = ghb_settings_combo_int(asettings, "AudioMixdown"); } else @@ -413,14 +426,28 @@ audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud) titleindex = ghb_settings_combo_int(ud->settings, "title"); track = ghb_settings_combo_int(ud->settings, "AudioTrack"); + if (sr) + { + sr = ghb_find_closest_audio_rate(sr); + } + ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(sr)); + if (sr == 0) + { + ghb_audio_info_t ainfo; + if (ghb_get_audio_info (&ainfo, titleindex, track)) + { + sr = ainfo.samplerate; + } + else + { + sr = 48000; + } + } mix_code = ghb_get_best_mix( titleindex, track, acodec_code, mix_code); - int channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mix_code); - br = ghb_get_best_audio_bitrate(acodec_code, br, channels); + br = hb_get_best_audio_bitrate(acodec_code, br, sr, mix_code); ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(br)); - sr = ghb_find_closest_audio_rate(sr); - ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(sr)); ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code)); } ghb_adjust_audio_rate_combos(ud); @@ -482,6 +509,7 @@ audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud) GValue *asettings; g_debug("audio_widget_changed_cb ()"); + ghb_adjust_audio_rate_combos(ud); ghb_check_dependency(ud, widget, NULL); asettings = get_selected_asettings(ud); if (asettings != NULL) diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index 5f8347858..310cce02d 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -1610,108 +1610,6 @@ ghb_grey_combo_options(GtkBuilder *builder) grey_combo_box_item(builder, "AudioMixdown", HB_AMIXDOWN_6CH, !allow_6ch); } -void -ghb_get_audio_bitrate_limits(gint acodec, gint channels, gint *low, gint *high) -{ - if (acodec & HB_ACODEC_FAAC) - { - *low = 32 * channels; - if (channels >= 6) - *high = 768; - else if (channels >= 2) - *high = 320; - else - *high = 160; - } - else if (acodec & HB_ACODEC_AC3) - { - *low = 32 * channels; - *high = 640; - } - else - { - *low = hb_audio_bitrates[0].rate; - *high = hb_audio_bitrates[hb_audio_bitrates_count-1].rate; - } -} - -gint -ghb_find_closest_audio_bitrate(gint codec, gint rate) -{ - gint ii; - gint result; - - result = hb_audio_bitrates[hb_audio_bitrates_count-1].rate; - for (ii = 0; ii < hb_audio_bitrates_count; ii++) - { - if (rate <= hb_audio_bitrates[ii].rate) - { - result = hb_audio_bitrates[ii].rate; - break; - } - } - return result; -} - -gint -ghb_get_best_audio_bitrate(gint acodec, gint br, gint channels) -{ - int low, high; - - ghb_get_audio_bitrate_limits(acodec, channels, &low, &high); - if (br > high) - br = high; - if (br < low) - br = low; - br = ghb_find_closest_audio_bitrate(acodec, br); - return br; -} - -gint -ghb_get_default_audio_bitrate(gint acodec, gint sr, gint br, gint channels) -{ - gint min_rate, max_rate; - gint sr_div = 1; - - // Min bitrate is established such that we get good quality - // audio as a minimum. If the input bitrate is higher than - // the output codec allows, we will cap the bitrate. - if (sr <= 24000) - { - sr_div = 2; - } - if (acodec & HB_ACODEC_AC3) - { - switch (channels) - { - case 1: - min_rate = 96; - break; - case 2: - min_rate = 224; - break; - case 6: - default: - min_rate = 448; - break; - } - max_rate = channels * 160; - } - else - { - min_rate = channels * 64; - max_rate = channels * 160; - } - max_rate /= sr_div; - min_rate /= sr_div; - if ( br < min_rate ) - br = min_rate; - if ( br > max_rate ) - br = max_rate; - br = ghb_get_best_audio_bitrate(acodec, br, channels); - return br; -} - gint ghb_get_best_mix(gint titleindex, gint track, gint acodec, gint mix) { @@ -4836,16 +4734,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) } else { - int channels; - audio.out.mixdown = ghb_settings_combo_int(asettings, "AudioMixdown"); - if (audio.out.mixdown == HB_AMIXDOWN_MONO) - channels = 1; - else if (audio.out.mixdown == HB_AMIXDOWN_6CH) - channels = 6; - else - channels = 2; - // Make sure the mixdown is valid and pick a new one if not. audio.out.mixdown = ghb_get_best_mix(titleindex, audio.in.track, audio.out.codec, audio.out.mixdown); @@ -4857,8 +4746,9 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) else audio.out.samplerate = srate; - audio.out.bitrate = ghb_get_best_audio_bitrate( - audio.out.codec, audio.out.bitrate, channels); + audio.out.bitrate = hb_get_best_audio_bitrate( + audio.out.codec, audio.out.bitrate, + audio.out.samplerate, audio.out.mixdown); } // Add it to the jobs audio list diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h index e5a816b10..67874bb4e 100644 --- a/gtk/src/hb-backend.h +++ b/gtk/src/hb-backend.h @@ -185,11 +185,7 @@ const gchar* ghb_lookup_combo_string(const gchar *name, const GValue *gval); gchar* ghb_get_tmp_dir(); gint ghb_select_audio_codec(GValue *settings, gint acodec, gint track); const gchar* ghb_select_audio_codec_str(GValue *settings, gint acodec, gint track); -gint ghb_find_closest_audio_bitrate(gint codec, gint rate); gint ghb_find_closest_audio_rate(gint rate); -gint ghb_get_best_audio_bitrate(gint acodec, gint br, gint channels); -gint ghb_get_default_audio_bitrate(gint acodec, gint sr, gint br, gint channels); -void ghb_get_audio_bitrate_limits(gint acodec, gint channels, gint *low, gint *high); GValue* ghb_lookup_acodec_value(gint val); #endif // _HBBACKEND_H_ diff --git a/libhb/common.c b/libhb/common.c index 0c9ac629e..0c8c5cf94 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -77,6 +77,130 @@ const char * hb_mixdown_get_short_name_from_mixdown( int amixdown ) return ""; } +// Given an input bitrate, find closest match in the set of allowed bitrates +int hb_find_closest_audio_bitrate(int bitrate) +{ + int ii; + int result; + + // result is highest rate if none found during search. + // rate returned will always be <= rate asked for. + result = hb_audio_bitrates[hb_audio_bitrates_count-1].rate; + for (ii = 0; ii < hb_audio_bitrates_count; ii++) + { + if (bitrate <= hb_audio_bitrates[ii].rate) + { + result = hb_audio_bitrates[ii].rate; + break; + } + } + return result; +} + +// Get the bitrate low and high limits for a codec/samplerate/mixdown triplet +void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, int *low, int *high) +{ + int channels; + + channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mixdown); + switch (codec) + { + case HB_ACODEC_AC3: + *low = 32 * channels; + *high = 640; + break; + + case HB_ACODEC_CA_AAC: + *low = channels * 80; + if (samplerate <= 44100) + *low = channels * 64; + if (samplerate <= 24000) + *low = channels * 32; + *high = hb_audio_bitrates[hb_audio_bitrates_count-1].rate; + break; + + case HB_ACODEC_FAAC: + *low = 32 * channels; + if (channels >= 6) + *high = 768; + else if (channels >= 2) + *high = 320; + else + *high = 160; + break; + + case HB_ACODEC_VORBIS: + *low = channels * 16; + *high = hb_audio_bitrates[hb_audio_bitrates_count-1].rate; + if (samplerate > 24000) + { + if (channels > 2) + { + // Vorbis minimum is around 30kbps/ch for 6ch + // at rates > 24k (32k/44.1k/48k) + *low = 32 * channels; + } + else + { + // Allow 24kbps mono and 48kbps stereo at rates > 24k + // (32k/44.1k/48k) + *low = 24 * channels; + } + } + break; + + default: + *low = hb_audio_bitrates[0].rate; + *high = hb_audio_bitrates[hb_audio_bitrates_count-1].rate; + break; + } +} + +// Given an input bitrate, sanitize it. Check low and high limits and +// make sure it is in the set of allowed bitrates. +int hb_get_best_audio_bitrate( uint32_t codec, int bitrate, int samplerate, int mixdown) +{ + int low, high; + + hb_get_audio_bitrate_limits(codec, samplerate, mixdown, &low, &high); + if (bitrate > high) + bitrate = high; + if (bitrate < low) + bitrate = low; + bitrate = hb_find_closest_audio_bitrate(bitrate); + return bitrate; +} + +// Get the default bitrate for a given codec/samplerate/mixdown triplet. +int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown ) +{ + int bitrate, channels; + int sr_shift; + + channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mixdown); + + // Min bitrate is established such that we get good quality + // audio as a minimum. + sr_shift = (samplerate <= 24000) ? 1 : 0; + + switch ( codec ) + { + case HB_ACODEC_AC3: + if (channels == 1) + bitrate = 96; + else if (channels <= 2) + bitrate = 224; + else + bitrate = 640; + break; + default: + bitrate = channels * 80; + } + bitrate >>= sr_shift; + bitrate = hb_get_best_audio_bitrate( codec, bitrate, samplerate, mixdown ); + return bitrate; +} + /********************************************************************** * hb_reduce ********************************************************************** diff --git a/libhb/common.h b/libhb/common.h index fcb4d4d04..b21abb3b5 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -150,6 +150,10 @@ 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_find_closest_audio_bitrate(int bitrate); +void hb_get_audio_bitrate_limits(uint32_t codec, int samplerate, int mixdown, int *low, int *high); +int hb_get_best_audio_bitrate( uint32_t codec, int bitrate, int samplerate, int mixdown); +int hb_get_default_audio_bitrate( uint32_t codec, int samplerate, int mixdown ); /****************************************************************************** * hb_job_t: settings to be filled by the UI |