summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2010-10-08 18:55:03 +0000
committerjstebbins <[email protected]>2010-10-08 18:55:03 +0000
commit0b489b411b69296262c74e02ec3bcf3eed38f7e3 (patch)
treea65956357de80bdaaf6588080ddf4e826ccfb63f
parent4947466a36cd72a238ea676c0c440ee19ae46bee (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.c48
-rw-r--r--gtk/src/hb-backend.c116
-rw-r--r--gtk/src/hb-backend.h4
-rw-r--r--libhb/common.c124
-rw-r--r--libhb/common.h4
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