OSDN Git Service

add audio defaults and limits calculation to libhb
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 8 Oct 2010 18:55:03 +0000 (18:55 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 8 Oct 2010 18:55:03 +0000 (18:55 +0000)
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://localhost/HandBrake/trunk@3578 b64f7644-9d1e-0410-96f1-a4d463321fa5

gtk/src/audiohandler.c
gtk/src/hb-backend.c
gtk/src/hb-backend.h
libhb/common.c
libhb/common.h

index 6ca0148..5288e31 100644 (file)
@@ -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)
index 5f83478..310cce0 100644 (file)
@@ -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
index e5a816b..67874bb 100644 (file)
@@ -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_
index 0c9ac62..0c8c5cf 100644 (file)
@@ -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
  **********************************************************************
index fcb4d4d..b21abb3 100644 (file)
@@ -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