OSDN Git Service

LinGui: remove target file size option
[handbrake-jp/handbrake-jp-git.git] / gtk / src / hb-backend.c
index 8614b0a..0f7bba1 100644 (file)
@@ -2,7 +2,7 @@
  *            hb-backend.c
  *
  *  Fri Mar 28 10:38:44 2008
- *  Copyright  2008  John Stebbins
+ *  Copyright  2008-2011  John Stebbins
  *  <john at stebbins dot name>
  ****************************************************************************/
 
@@ -86,6 +86,7 @@ static options_map_t d_when_complete_opts[] =
 {
        {"Do Nothing",            "nothing",  0, "0"},
        {"Show Notification",     "notify",   1, "1"},
+       {"Quit Handbrake",        "quit",     4, "4"},
        {"Put Computer To Sleep", "sleep",    2, "2"},
        {"Shutdown Computer",     "shutdown", 3, "3"},
 };
@@ -302,9 +303,9 @@ combo_opts_t bpyramid_opts =
 
 static options_map_t d_weightp_opts[] =
 {
-       {"Off",   "0", 0, "0"},
-       {"Blind", "1", 1, "1"},
-       {"Smart", "2", 2, "2"},
+       {"Off",    "0", 0, "0"},
+       {"Simple", "1", 1, "1"},
+       {"Smart",  "2", 2, "2"},
 };
 combo_opts_t weightp_opts =
 {
@@ -413,6 +414,7 @@ combo_name_map_t combo_name_map[] =
        {"PictureDenoise", &denoise_opts},
        {"VideoEncoder", &vcodec_opts},
        {"AudioEncoder", &acodec_opts},
+       {"AudioEncoderActual", &acodec_opts},
        {"x264_direct", &direct_opts},
        {"x264_b_adapt", &badapt_opts},
        {"x264_bpyramid", &bpyramid_opts},
@@ -1096,35 +1098,6 @@ lookup_audio_rate_option(const GValue *rate)
 }
 
 gint
-ghb_find_closest_audio_bitrate(gint codec, gint rate)
-{
-       gint ii;
-       gint low = 32;
-       gint high = 768;
-       gint result;
-
-       if (codec == HB_ACODEC_FAAC)
-               high = 320;
-       else if (codec == HB_ACODEC_AC3)
-               high = 640;
-
-       result = high;
-       for (ii = 0; ii < hb_audio_bitrates_count; ii++)
-       {
-               if (hb_audio_bitrates[ii].rate < low)
-                       continue;
-               if (hb_audio_bitrates[ii].rate > high)
-                       break;
-               if (rate <= hb_audio_bitrates[ii].rate)
-               {
-                       result = hb_audio_bitrates[ii].rate;
-                       break;
-               }
-       }
-       return result;
-}
-
-gint
 ghb_find_closest_audio_rate(gint rate)
 {
        gint ii;
@@ -1142,6 +1115,9 @@ ghb_find_closest_audio_rate(gint rate)
        return result;
 }
 
+hb_rate_t *ghb_audio_bitrates;
+int ghb_audio_bitrates_count;
+
 static gint
 lookup_audio_bitrate_int(const GValue *rate)
 {
@@ -1153,11 +1129,11 @@ lookup_audio_bitrate_int(const GValue *rate)
                // Coincidentally, the string "source" will return 0
                // which is our flag to use "same as source"
                gchar *str = ghb_value_string(rate);
-               for (ii = 0; ii < hb_audio_bitrates_count; ii++)
+               for (ii = 0; ii < ghb_audio_bitrates_count; ii++)
                {
-                       if (strcmp(hb_audio_bitrates[ii].string, str) == 0)
+                       if (strcmp(ghb_audio_bitrates[ii].string, str) == 0)
                        {
-                               result = hb_audio_bitrates[ii].rate;
+                               result = ghb_audio_bitrates[ii].rate;
                                break;
                        }
                }
@@ -1168,11 +1144,11 @@ lookup_audio_bitrate_int(const GValue *rate)
                         G_VALUE_TYPE(rate) == G_TYPE_DOUBLE)
        {
                gint val = ghb_value_int(rate);
-               for (ii = 0; ii < hb_audio_bitrates_count; ii++)
+               for (ii = 0; ii < ghb_audio_bitrates_count; ii++)
                {
-                       if (hb_audio_bitrates[ii].rate == val)
+                       if (ghb_audio_bitrates[ii].rate == val)
                        {
-                               result = hb_audio_bitrates[ii].rate;
+                               result = ghb_audio_bitrates[ii].rate;
                                break;
                        }
                }
@@ -1191,11 +1167,11 @@ lookup_audio_bitrate_option(const GValue *rate)
                // Coincidentally, the string "source" will return 0
                // which is our flag to use "same as source"
                gchar *str = ghb_value_string(rate);
-               for (ii = 0; ii < hb_audio_bitrates_count; ii++)
+               for (ii = 0; ii < ghb_audio_bitrates_count; ii++)
                {
-                       if (strcmp(hb_audio_bitrates[ii].string, str) == 0)
+                       if (strcmp(ghb_audio_bitrates[ii].string, str) == 0)
                        {
-                               result = hb_audio_bitrates[ii].string;
+                               result = ghb_audio_bitrates[ii].string;
                                break;
                        }
                }
@@ -1206,11 +1182,11 @@ lookup_audio_bitrate_option(const GValue *rate)
                         G_VALUE_TYPE(rate) == G_TYPE_DOUBLE)
        {
                gint val = ghb_value_int(rate);
-               for (ii = 0; ii < hb_audio_bitrates_count; ii++)
+               for (ii = 0; ii < ghb_audio_bitrates_count; ii++)
                {
-                       if (hb_audio_bitrates[ii].rate == val)
+                       if (ghb_audio_bitrates[ii].rate == val)
                        {
-                               result = hb_audio_bitrates[ii].string;
+                               result = ghb_audio_bitrates[ii].string;
                                break;
                        }
                }
@@ -1489,14 +1465,14 @@ ghb_get_title_number(gint titleindex)
 }
 
 static hb_audio_config_t*
-get_hb_audio(gint titleindex, gint track)
+get_hb_audio(hb_handle_t *h, gint titleindex, gint track)
 {
        hb_list_t  * list;
        hb_title_t * title;
     hb_audio_config_t *audio = NULL;
        
-    if (h_scan == NULL) return NULL;
-       list = hb_get_titles( h_scan );
+    if (h == NULL) return NULL;
+       list = hb_get_titles( h );
        if( !hb_list_count( list ) )
        {
                /* No valid title, stop right there */
@@ -1559,7 +1535,7 @@ ghb_grey_combo_options(GtkBuilder *builder)
 {
        GtkWidget *widget;
        gint container, track, titleindex, acodec;
-    hb_audio_config_t *audio = NULL;
+    hb_audio_config_t *aconfig = NULL;
        GValue *gval;
        
        widget = GHB_WIDGET (builder, "title");
@@ -1570,7 +1546,7 @@ ghb_grey_combo_options(GtkBuilder *builder)
        gval = ghb_widget_value(widget);
        track = ghb_lookup_combo_int("AudioTrack", gval);
        ghb_value_free(gval);
-       audio = get_hb_audio(titleindex, track);
+       aconfig = get_hb_audio(h_scan, titleindex, track);
        widget = GHB_WIDGET (builder, "FileFormat");
        gval = ghb_widget_value(widget);
        container = ghb_lookup_combo_int("FileFormat", gval);
@@ -1590,11 +1566,11 @@ ghb_grey_combo_options(GtkBuilder *builder)
        else
                grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
 
-       if (audio && audio->in.codec != HB_ACODEC_AC3)
+       if (aconfig && aconfig->in.codec != HB_ACODEC_AC3)
        {
                grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_AC3_PASS, TRUE);
        }
-       if (audio && audio->in.codec != HB_ACODEC_DCA)
+       if (aconfig && aconfig->in.codec != HB_ACODEC_DCA)
        {
                grey_combo_box_item(builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
        }
@@ -1618,19 +1594,14 @@ ghb_grey_combo_options(GtkBuilder *builder)
        gboolean allow_6ch = TRUE;
        allow_mono = TRUE;
        allow_6ch = acodec & ~HB_ACODEC_LAME;
-       if (audio)
-       {
-               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);
-               allow_dolby =
-                       (layout == HB_INPUT_CH_LAYOUT_3F1R) || 
-                       (layout == HB_INPUT_CH_LAYOUT_3F2R) || 
-                       (layout == HB_INPUT_CH_LAYOUT_DOLBY);
-               allow_dpl2 = (layout == HB_INPUT_CH_LAYOUT_3F2R);
-               allow_6ch = allow_6ch &&
-                       (layout == HB_INPUT_CH_LAYOUT_3F2R) && 
-                       (audio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE);
+       if (aconfig)
+       {
+               gint best = hb_get_best_mixdown(acodec, aconfig->in.channel_layout, 0);
+
+               allow_stereo = best >= HB_AMIXDOWN_STEREO;
+               allow_dolby = best >= HB_AMIXDOWN_DOLBY;
+               allow_dpl2 = best >= HB_AMIXDOWN_DOLBYPLII;
+               allow_6ch = best >= HB_AMIXDOWN_6CH;
        }
        grey_combo_box_item(builder, "AudioMixdown", HB_AMIXDOWN_MONO, !allow_mono);
        grey_combo_box_item(builder, "AudioMixdown", HB_AMIXDOWN_STEREO, !allow_stereo);
@@ -1640,90 +1611,12 @@ ghb_grey_combo_options(GtkBuilder *builder)
 }
 
 gint
-ghb_get_best_audio_bitrate(gint acodec, gint br, gint channels)
+ghb_get_best_mix(hb_audio_config_t *aconfig, gint acodec, gint mix)
 {
-       if (acodec & HB_ACODEC_FAAC)
-       {
-               int maxbr;
-
-               if (channels == 2)
-                       maxbr = 320;
-               else
-                       maxbr = 768;
-               if (br > maxbr)
-                       br = maxbr;
-       }
-       return br;
-}
-
-gint
-ghb_get_best_mix(gint titleindex, gint track, gint acodec, gint mix)
-{
-    hb_audio_config_t *audio = NULL;
-       gboolean allow_mono = TRUE;
-       gboolean allow_stereo = TRUE;
-       gboolean allow_dolby = TRUE;
-       gboolean allow_dpl2 = TRUE;
-       gboolean allow_6ch = TRUE;
-       
-       if (acodec & HB_ACODEC_PASS_FLAG)
-       {
-               // Audio codec pass-thru.  No mixdown
-               return 0;
-       }
-       audio = get_hb_audio(titleindex, track);
-       if (audio)
-       {
-               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);
-               allow_dolby =
-                       (layout == HB_INPUT_CH_LAYOUT_3F1R) || 
-                       (layout == HB_INPUT_CH_LAYOUT_3F2R) || 
-                       (layout == HB_INPUT_CH_LAYOUT_DOLBY);
-               allow_dpl2 = (layout == HB_INPUT_CH_LAYOUT_3F2R);
-               allow_6ch =
-                       (acodec & ~HB_ACODEC_LAME) &&
-                       (layout == HB_INPUT_CH_LAYOUT_3F2R) && 
-                       (audio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE);
-       }
-       gboolean greater = FALSE;
-       if (mix == 0) 
-       {
-               // If no mix is specified, select the best available.
-               mix = HB_AMIXDOWN_6CH;
-       }
-       if (mix == HB_AMIXDOWN_6CH)
-       {
-               greater = TRUE;
-               if (allow_6ch) return HB_AMIXDOWN_6CH;
-       }
-       if (mix == HB_AMIXDOWN_DOLBYPLII || greater)
-       {
-               greater = TRUE;
-               if (allow_dpl2) return HB_AMIXDOWN_DOLBYPLII;
-       }
-       if (mix == HB_AMIXDOWN_DOLBY || greater)
-       {
-               greater = TRUE;
-               if (allow_dolby) return HB_AMIXDOWN_DOLBY;
-       }
-       if (mix == HB_AMIXDOWN_STEREO || greater)
-       {
-               greater = TRUE;
-               if (allow_stereo) return HB_AMIXDOWN_STEREO;
-       }
-       if (mix == HB_AMIXDOWN_MONO || greater)
-       {
-               greater = TRUE;
-               if (allow_mono) return HB_AMIXDOWN_MONO;
-       }
-       if (allow_stereo) return HB_AMIXDOWN_STEREO;
-       if (allow_dolby) return HB_AMIXDOWN_DOLBY;
-       if (allow_dpl2) return HB_AMIXDOWN_DOLBYPLII;
-       if (allow_6ch) return HB_AMIXDOWN_6CH;
-       return 0;
+       int layout;
+       layout = aconfig ? aconfig->in.channel_layout : 
+                                               HB_INPUT_CH_LAYOUT_3F2R | HB_INPUT_CH_LAYOUT_HAS_LFE;
+       return hb_get_best_mixdown( acodec, layout, mix );
 }
 
 // Set up the model for the combo box
@@ -1997,14 +1890,20 @@ title_opts_set(GtkBuilder *builder, const gchar *name)
                {
                        if (title->duration != 0)
                        {
-                               titles[ii]  = g_strdup_printf ("%d - %02dh%02dm%02ds - %s",
+                char *tmp;
+                               tmp  = g_strdup_printf ("%d - %02dh%02dm%02ds - %s",
                                        title->index, title->hours, title->minutes, title->seconds, 
                                        title->name);
+                titles[ii] = g_markup_escape_text(tmp, -1);
+                g_free(tmp);
                        }
                        else
                        {
-                               titles[ii]  = g_strdup_printf ("%d - %s", 
+                char *tmp;
+                               tmp  = g_strdup_printf ("%d - %s", 
                                                                                title->index, title->name);
+                titles[ii] = g_markup_escape_text(tmp, -1);
+                g_free(tmp);
                        }
                }
                else
@@ -2347,7 +2246,7 @@ ghb_find_audio_track(
                {
                        audio = (hb_audio_config_t*)hb_list_audio_config_item( 
                                                                                                        title->list_audio, ii );
-                       passthru_acodec = acodec & audio->in.codec;
+                       passthru_acodec = HB_ACODEC_PASS_MASK & acodec & audio->in.codec;
                        // Is the source track use a passthru capable codec?
                        if (passthru_acodec == 0)
                                continue;
@@ -2428,7 +2327,7 @@ ghb_find_audio_track(
                {
                        audio = (hb_audio_config_t*)hb_list_audio_config_item( 
                                                                                                        title->list_audio, ii );
-                       passthru_acodec = HB_ACODEC_PASS_MASK & audio->in.codec;
+                       passthru_acodec = HB_ACODEC_PASS_MASK & acodec & audio->in.codec;
                        // Is the source track use a passthru capable codec?
                        if (passthru_acodec == 0)
                                continue;
@@ -3073,6 +2972,15 @@ audio_bitrate_opts_add(GtkBuilder *builder, const gchar *name, gint rate)
 
        if (rate < 8) return;
 
+       if (ghb_audio_bitrates[hb_audio_bitrates_count].string)
+       {
+               g_free(ghb_audio_bitrates[hb_audio_bitrates_count].string);
+       }
+       ghb_audio_bitrates[hb_audio_bitrates_count].rate = rate;
+       ghb_audio_bitrates[hb_audio_bitrates_count].string = 
+               g_strdup_printf("%d", rate);
+       ghb_audio_bitrates_count = hb_audio_bitrates_count + 1;
+
        store = get_combo_box_store(builder, name);
        if (!find_combo_item_by_int(GTK_TREE_MODEL(store), rate, &iter))
        {
@@ -3081,9 +2989,9 @@ audio_bitrate_opts_add(GtkBuilder *builder, const gchar *name, gint rate)
                gtk_list_store_set(store, &iter, 
                                                   0, str, 
                                                   1, TRUE, 
-                                                  2, str
+                                                  2, ghb_audio_bitrates[hb_audio_bitrates_count].string
                                                   3, (gdouble)rate, 
-                                                  4, str
+                                                  4, ghb_audio_bitrates[hb_audio_bitrates_count].string
                                                   -1);
                g_free(str);
        }
@@ -3104,6 +3012,8 @@ audio_bitrate_opts_clean(
        guint last = (guint)last_rate;
        guint first = (guint)first_rate;
        
+       ghb_audio_bitrates_count = hb_audio_bitrates_count;
+
        g_debug("audio_bitrate_opts_clean ()\n");
        store = get_combo_box_store(builder, name);
        if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(store), &iter))
@@ -3112,7 +3022,7 @@ audio_bitrate_opts_clean(
                {
                        gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 3, &ivalue, -1);
                        if (search_rates(
-                               hb_audio_bitrates, ivalue, hb_audio_bitrates_count) < 0)
+                               ghb_audio_bitrates, ivalue, ghb_audio_bitrates_count) < 0)
                        {
                                done = !gtk_list_store_remove(store, &iter);
                        }
@@ -3140,20 +3050,28 @@ audio_bitrate_opts_set(GtkBuilder *builder, const gchar *name)
        gint ii;
        gchar *str;
        
+       ghb_audio_bitrates_count = hb_audio_bitrates_count;
+       ghb_audio_bitrates = calloc(hb_audio_bitrates_count+1, sizeof(hb_rate_t));
+
+       for (ii = 0; ii < hb_audio_bitrates_count; ii++)
+       {
+               ghb_audio_bitrates[ii] = hb_audio_bitrates[ii];
+       }
+
        g_debug("audio_bitrate_opts_set ()\n");
        store = get_combo_box_store(builder, name);
        gtk_list_store_clear(store);
-       for (ii = 0; ii < hb_audio_bitrates_count; ii++)
+       for (ii = 0; ii < ghb_audio_bitrates_count; ii++)
        {
                gtk_list_store_append(store, &iter);
                str = g_strdup_printf ("<small>%s</small>", 
-                       hb_audio_bitrates[ii].string);
+                       ghb_audio_bitrates[ii].string);
                gtk_list_store_set(store, &iter, 
                                                   0, str,
                                                   1, TRUE, 
-                                                  2, hb_audio_bitrates[ii].string, 
-                                                  3, (gdouble)hb_audio_bitrates[ii].rate, 
-                                                  4, hb_audio_bitrates[ii].string, 
+                                                  2, ghb_audio_bitrates[ii].string, 
+                                                  3, (gdouble)ghb_audio_bitrates[ii].rate, 
+                                                  4, ghb_audio_bitrates[ii].string, 
                                                   -1);
                g_free(str);
        }
@@ -3485,17 +3403,13 @@ ghb_get_title_info(ghb_title_info_t *tinfo, gint titleindex)
        return TRUE;
 }
 
-gboolean
-ghb_get_audio_info(ghb_audio_info_t *ainfo, gint titleindex, gint audioindex)
+hb_audio_config_t*
+ghb_get_scan_audio_info(gint titleindex, gint audioindex)
 {
-    hb_audio_config_t *audio;
+    hb_audio_config_t *aconfig;
        
-       audio = get_hb_audio(titleindex, audioindex);
-       if (audio == NULL) return FALSE; // Bad audioindex
-       ainfo->codec = audio->in.codec;
-       ainfo->bitrate = audio->in.bitrate;
-       ainfo->samplerate = audio->in.samplerate;
-       return TRUE;
+       aconfig = get_hb_audio(h_scan, titleindex, audioindex);
+       return aconfig;
 }
 
 gboolean
@@ -3942,24 +3856,6 @@ set_preview_job_settings(hb_job_t *job, GValue *settings)
        }
 }
 
-gint
-ghb_calculate_target_bitrate(GValue *settings, gint titleindex)
-{
-       hb_list_t  * list;
-       hb_title_t * title;
-       hb_job_t   * job;
-       gint size;
-
-       if (h_scan == NULL) return 1500;
-       list = hb_get_titles( h_scan );
-    title = hb_list_item( list, titleindex );
-       if (title == NULL) return 1500;
-       job   = title->job;
-       if (job == NULL) return 1500;
-       size = ghb_settings_get_int(settings, "VideoTargetSize");
-       return hb_calc_bitrate( job, size );
-}
-
 gboolean
 ghb_validate_filter_string(const gchar *str, gint max_fields)
 {
@@ -4173,43 +4069,25 @@ ghb_validate_subtitles(signal_user_data_t *ud)
 }
 
 gint
-ghb_select_audio_codec(GValue *settings, gint acodec, gint track)
+ghb_select_audio_codec(GValue *settings, hb_audio_config_t *aconfig, gint acodec)
 {
-       hb_list_t  * list;
-       hb_title_t * title;
-       hb_audio_config_t *audio;
-
-       if (h_scan == NULL) return -1;
-       list = hb_get_titles( h_scan );
-       if( !hb_list_count( list ) )
-       {
-               return -1;
-       }
-
-       gint titleindex;
-
-       titleindex = ghb_settings_combo_int(settings, "title");
-    title = hb_list_item( list, titleindex );
-       if (title == NULL) return -1;
-
        gint mux = ghb_settings_combo_int(settings, "FileFormat");
 
-       if (track < 0 || track >= hb_list_count(title->list_audio))
-               return -1;
-
-       audio = (hb_audio_config_t *) hb_list_audio_config_item(
-                                                                       title->list_audio, track );
-
+       guint32 in_codec = aconfig ? aconfig->in.codec : HB_ACODEC_MASK;
        if (mux == HB_MUX_MP4)
        {
-               if ((acodec & audio->in.codec & HB_ACODEC_AC3))
+               if ((acodec & in_codec & HB_ACODEC_AC3))
                {
-                       return acodec & (audio->in.codec | HB_ACODEC_PASS_FLAG);
+                       return acodec & (in_codec | HB_ACODEC_PASS_FLAG);
                }
                else if (acodec & HB_ACODEC_AC3)
                {
                        return HB_ACODEC_AC3;
                }
+               else if (acodec & HB_ACODEC_LAME)
+               {
+                       return HB_ACODEC_LAME;
+               }
                else if (acodec & HB_ACODEC_FAAC)
                {
                        return HB_ACODEC_FAAC;
@@ -4221,9 +4099,9 @@ ghb_select_audio_codec(GValue *settings, gint acodec, gint track)
        }
        else
        {
-               if ((acodec & audio->in.codec & HB_ACODEC_PASS_MASK))
+               if ((acodec & in_codec & HB_ACODEC_PASS_MASK))
                {
-                       return acodec & (audio->in.codec | HB_ACODEC_PASS_FLAG);
+                       return acodec & (in_codec | HB_ACODEC_PASS_FLAG);
                }
                else if (acodec & HB_ACODEC_AC3)
                {
@@ -4237,6 +4115,10 @@ ghb_select_audio_codec(GValue *settings, gint acodec, gint track)
                {
                        return HB_ACODEC_LAME;
                }
+               else if (acodec & HB_ACODEC_FAAC)
+               {
+                       return HB_ACODEC_FAAC;
+               }
                else
                {
                        return HB_ACODEC_LAME;
@@ -4244,20 +4126,6 @@ ghb_select_audio_codec(GValue *settings, gint acodec, gint track)
        }
 }
 
-const gchar*
-ghb_select_audio_codec_str(GValue *settings, gint icodec, gint track)
-{
-       gint acodec, ii;
-
-       acodec = ghb_select_audio_codec(settings, icodec, track);
-       for (ii = 0; ii < acodec_opts.count; ii++)
-       {
-               if (acodec_opts.map[ii].ivalue == acodec)
-                       return acodec_opts.map[ii].option;
-       }
-       return "Unknown";
-}
-
 gboolean
 ghb_validate_audio(signal_user_data_t *ud)
 {
@@ -4290,7 +4158,7 @@ ghb_validate_audio(signal_user_data_t *ud)
        for (ii = 0; ii < count; ii++)
        {
                GValue *asettings;
-           hb_audio_config_t *taudio;
+           hb_audio_config_t *aconfig;
 
                asettings = ghb_array_get_nth(audio_list, ii);
                gint track = ghb_settings_combo_int(asettings, "AudioTrack");
@@ -4298,11 +4166,11 @@ ghb_validate_audio(signal_user_data_t *ud)
                if (codec == HB_ACODEC_ANY)
                        continue;
 
-        taudio = (hb_audio_config_t *) hb_list_audio_config_item(
+        aconfig = (hb_audio_config_t *) hb_list_audio_config_item(
                                                                                        title->list_audio, track );
                if ( ghb_audio_is_passthru(codec) &&
-                       !(ghb_audio_can_passthru(taudio->in.codec) && 
-                        (taudio->in.codec & codec)))
+                       !(ghb_audio_can_passthru(aconfig->in.codec) && 
+                        (aconfig->in.codec & codec)))
                {
                        // Not supported.  AC3 is passthrough only, so input must be AC3
                        message = g_strdup_printf(
@@ -4316,7 +4184,7 @@ ghb_validate_audio(signal_user_data_t *ud)
                        }
                        g_free(message);
                        if ((codec & HB_ACODEC_AC3) ||
-                               taudio->in.codec == HB_ACODEC_DCA)
+                               aconfig->in.codec == HB_ACODEC_DCA)
                        {
                                codec = HB_ACODEC_AC3;
                        }
@@ -4363,6 +4231,7 @@ ghb_validate_audio(signal_user_data_t *ud)
                        value = ghb_lookup_acodec_value(codec);
                        ghb_settings_take_value(asettings, "AudioEncoder", value);
                }
+
                gint mix = ghb_settings_combo_int (asettings, "AudioMixdown");
                gboolean allow_mono = TRUE;
                gboolean allow_stereo = TRUE;
@@ -4370,18 +4239,13 @@ ghb_validate_audio(signal_user_data_t *ud)
                gboolean allow_dpl2 = TRUE;
                gboolean allow_6ch = TRUE;
                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);
-               allow_dolby =
-                       (layout == HB_INPUT_CH_LAYOUT_3F1R) || 
-                       (layout == HB_INPUT_CH_LAYOUT_3F2R) || 
-                       (layout == HB_INPUT_CH_LAYOUT_DOLBY);
-               allow_dpl2 = (layout == HB_INPUT_CH_LAYOUT_3F2R);
-               allow_6ch =
-                       (codec & ~HB_ACODEC_LAME) &&
-                       (layout == HB_INPUT_CH_LAYOUT_3F2R) && 
-                       (taudio->in.channel_layout & HB_INPUT_CH_LAYOUT_HAS_LFE);
+
+               gint best = hb_get_best_mixdown(codec, aconfig->in.channel_layout, 0);
+
+               allow_stereo = best >= HB_AMIXDOWN_STEREO;
+               allow_dolby = best >= HB_AMIXDOWN_DOLBY;
+               allow_dpl2 = best >= HB_AMIXDOWN_DOLBYPLII;
+               allow_6ch = best >= HB_AMIXDOWN_6CH;
 
                gchar *mix_unsup = NULL;
                if (mix == HB_AMIXDOWN_MONO && !allow_mono)
@@ -4416,7 +4280,7 @@ ghb_validate_audio(signal_user_data_t *ud)
                                return FALSE;
                        }
                        g_free(message);
-                       mix = ghb_get_best_mix(titleindex, track, codec, mix);
+                       mix = ghb_get_best_mix(aconfig, codec, mix);
                        value = get_amix_value(mix);
                        ghb_settings_take_value(asettings, "AudioMixdown", value);
                }
@@ -4463,11 +4327,28 @@ ghb_validate_vquality(GValue *settings)
                                max = 62;
                        } break;
                }
-               if (vquality < min || vquality > max)
+               if (vcodec == HB_VCODEC_X264 && vquality == 0.0)
+               {
+                       message = g_strdup_printf(
+                                               "Warning: lossless h.264 selected\n\n"
+                                               "Lossless h.264 is not well supported by\n"
+                                               "many players and editors.\n\n"
+                        "It will produce enormous output files.\n\n"
+                                               "Are you sure you wish to use this setting?",
+                                               (gint)vquality, min, max);
+                       if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, 
+                                                                       "Cancel", "Continue"))
+                       {
+                               g_free(message);
+                               return FALSE;
+                       }
+                       g_free(message);
+               }
+               else if (vquality < min || vquality > max)
                {
                        message = g_strdup_printf(
-                                               "Interesting video quality choise: %d\n\n"
-                                               "Typical values range from %d to %d.\n"
+                                               "Interesting video quality choice: %d\n\n"
+                                               "Typical values range from %d to %d.\n\n"
                                                "Are you sure you wish to use this setting?",
                                                (gint)vquality, min, max);
                        if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, 
@@ -4539,6 +4420,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                gint start, end;
                gint num_chapters = hb_list_count(title->list_chapter);
                gint duration = title->duration / 90000;
+               job->chapter_markers = FALSE;
                job->chapter_start = 1;
                job->chapter_end = num_chapters;
 
@@ -4552,8 +4434,6 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                }
                if (ghb_settings_combo_int(js, "PtoPType") == 1)
                {
-                       job->chapter_start = 1;
-                       job->chapter_end = num_chapters;
                        start = ghb_settings_get_int(js, "start_point");
                        end = ghb_settings_get_int(js, "end_point");
                        job->pts_to_start = (int64_t)MIN(duration-1, start) * 90000;
@@ -4562,8 +4442,6 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                }
                if (ghb_settings_combo_int(js, "PtoPType") == 2)
                {
-                       job->chapter_start = 1;
-                       job->chapter_end = num_chapters;
                        start = ghb_settings_get_int(js, "start_point");
                        end = ghb_settings_get_int(js, "end_point");
                        gint64 max_frames;
@@ -4572,7 +4450,10 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                        job->frame_to_stop = (int64_t)MAX(start, end-1) - 
                                                                 job->frame_to_start;
                }
-               job->chapter_markers = ghb_settings_get_boolean(js, "ChapterMarkers");
+               if (job->chapter_start != job->chapter_end)
+               {
+                       job->chapter_markers = ghb_settings_get_boolean(js, "ChapterMarkers");
+               }
                if (job->chapter_start == job->chapter_end)
                        job->chapter_markers = 0;
                if ( job->chapter_markers )
@@ -4733,18 +4614,18 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
        {
                job->vrate = title->rate;
                job->vrate_base = title->rate_base;
-               job->cfr = 0;
        }
        else
        {
                job->vrate = 27000000;
                job->vrate_base = vrate;
-               gboolean pfr = ghb_settings_get_boolean(js, "VideoFrameratePFR");
-               if (pfr)
-                       job->cfr = 2;
-               else
-                       job->cfr = 1;
        }
+       if (ghb_settings_get_boolean(js, "VideoFrameratePFR"))
+               job->cfr = 2;
+       else if (ghb_settings_get_boolean(js, "VideoFramerateCFR"))
+               job->cfr = 1;
+       else
+               job->cfr = 0;
 
        const GValue *audio_list;
        gint count, ii;
@@ -4756,18 +4637,20 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
        {
                GValue *asettings;
            hb_audio_config_t audio;
-           hb_audio_config_t *taudio;
+           hb_audio_config_t *aconfig;
                gint acodec;
 
                hb_audio_config_init(&audio);
                asettings = ghb_array_get_nth(audio_list, ii);
                audio.in.track = ghb_settings_get_int(asettings, "AudioTrack");
                audio.out.track = tcount;
-               acodec = ghb_settings_combo_int(asettings, "AudioEncoder");
-               audio.out.codec = ghb_select_audio_codec(js, acodec, audio.in.track);
 
-        taudio = (hb_audio_config_t *) hb_list_audio_config_item(
+        aconfig = (hb_audio_config_t *) hb_list_audio_config_item(
                                                                        title->list_audio, audio.in.track );
+
+               acodec = ghb_settings_combo_int(asettings, "AudioEncoder");
+               audio.out.codec = ghb_select_audio_codec(js, aconfig, acodec);
+
         audio.out.dynamic_range_compression = 
                        ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
         if (audio.out.dynamic_range_compression < 1.0)
@@ -4780,46 +4663,27 @@ 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);
+                       audio.out.mixdown = ghb_get_best_mix(aconfig, audio.out.codec
+                                                                                                       audio.out.mixdown);
                        audio.out.bitrate = 
                                ghb_settings_combo_int(asettings, "AudioBitrate");
                        gint srate = ghb_settings_combo_int(asettings, "AudioSamplerate");
                        if (srate == 0) // 0 is same as source
-                               audio.out.samplerate = taudio->in.samplerate;
+                               audio.out.samplerate = aconfig->in.samplerate;
                        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
         hb_audio_add( job, &audio );
                tcount++;
        }
-       // I was tempted to move this up with the reset of the video quality
-       // settings, but I suspect the settings above need to be made
-       // first in order for hb_calc_bitrate to be accurate.
-       if (ghb_settings_get_boolean(js, "vquality_type_target"))
-       {
-               gint size;
-               
-               size = ghb_settings_get_int(js, "VideoTargetSize");
-        job->vbitrate = hb_calc_bitrate( job, size );
-               job->vquality = -1.0;
-       }
 
        dest_str = ghb_settings_get_string(js, "destination");
        job->file = dest_str;
@@ -4856,8 +4720,10 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                        sub_config.offset = ghb_settings_get_int(ssettings, "SrtOffset");
                        lang = ghb_settings_get_string(ssettings, "SrtLanguage");
                        code = ghb_settings_get_string(ssettings, "SrtCodeset");
-                       strncpy(sub_config.src_filename, filename, 128);
-                       strncpy(sub_config.src_codeset, code, 40);
+                       strncpy(sub_config.src_filename, filename, 255);
+                       sub_config.src_filename[255] = 0;
+                       strncpy(sub_config.src_codeset, code, 39);
+                       sub_config.src_codeset[39] = 0;
                        sub_config.force = 0;
                        sub_config.dest = PASSTHRUSUB;
                        sub_config.default_track = def;