X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=gtk%2Fsrc%2Fhb-backend.c;h=f15fe0081c5a7ac09173e275b1d370d744e13334;hb=023bc0f853674db16682807936aabf77139c1bb7;hp=bb30d2c2852da10b853920f82eae3da24b505936;hpb=e2cd98f3e71232b518b7165705d25d965ab9d9f3;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index bb30d2c2..f15fe008 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -31,6 +31,7 @@ #include "settings.h" #include "callbacks.h" #include "subtitlehandler.h" +#include "x264handler.h" #include "preview.h" #include "values.h" #include "lang.h" @@ -106,6 +107,19 @@ combo_opts_t logging_opts = d_logging_opts }; +static options_map_t d_appcast_update_opts[] = +{ + {"Never", "never", 0, "never"}, + {"Daily", "daily", 1, "daily"}, + {"Weekly", "weekly", 2, "weekly"}, + {"Monthly", "monthly", 3, "monthly"}, +}; +combo_opts_t appcast_update_opts = +{ + sizeof(d_appcast_update_opts)/sizeof(options_map_t), + d_appcast_update_opts +}; + static options_map_t d_vqual_granularity_opts[] = { {"0.2", "0.2", 0.2, "0.2"}, @@ -321,6 +335,7 @@ combo_name_map_t combo_name_map[] = {"PicturePAR", &par_opts}, {"PictureModulus", &alignment_opts}, {"LoggingLevel", &logging_opts}, + {"check_updates", &appcast_update_opts}, {"VideoQualityGranularity", &vqual_granularity_opts}, {"FileFormat", &container_opts}, {"PictureDeinterlace", &deint_opts}, @@ -607,7 +622,6 @@ ghb_vquality_range( *inverted = TRUE; } break; - case HB_VCODEC_XVID: case HB_VCODEC_FFMPEG: { *min = 1; @@ -1028,11 +1042,15 @@ ghb_subtitle_track_source_name(signal_user_data_t *ud, gint track) const gchar * name = "Unknown"; if (track == -2) - return CC608SUB; - if (track < 0) - return VOBSUB; - if (track < 0) + { + name = "Text"; goto done; + } + if (track == -1) + { + name = "Bitmap"; + goto done; + } titleindex = ghb_settings_combo_int(ud->settings, "title"); if (titleindex < 0) @@ -1042,7 +1060,8 @@ ghb_subtitle_track_source_name(signal_user_data_t *ud, gint track) hb_title_t * title; hb_subtitle_t * sub; - if (h_scan == NULL) return VOBSUB; + if (h_scan == NULL) + goto done; list = hb_get_titles( h_scan ); if( !hb_list_count( list ) ) goto done; @@ -1344,6 +1363,8 @@ init_combo_box(GtkBuilder *builder, const gchar *name) g_debug("init_combo_box() %s\n", name); // First modify the combobox model to allow greying out of options combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name)); + if (combo == NULL) + return; // Store contains: // 1 - String to display // 2 - bool indicating whether the entry is selectable (grey or not) @@ -1675,7 +1696,7 @@ audio_track_opts_set(GtkBuilder *builder, const gchar *name, gint titleindex) } void -subtitle_opts_set(signal_user_data_t *ud, const gchar *name, gint titleindex) +subtitle_track_opts_set(GtkBuilder *builder, const gchar *name, gint titleindex) { GtkTreeIter iter; GtkListStore *store; @@ -1683,9 +1704,10 @@ subtitle_opts_set(signal_user_data_t *ud, const gchar *name, gint titleindex) hb_title_t * title = NULL; hb_subtitle_t * subtitle; gint ii, count = 0; + static char ** options = NULL; - g_debug("subtitle_opts_set () %s\n", name); - store = get_combo_box_store(ud->builder, name); + g_debug("subtitle_track_opts_set ()\n"); + store = get_combo_box_store(builder, name); gtk_list_store_clear(store); if (h_scan != NULL) { @@ -1705,64 +1727,57 @@ subtitle_opts_set(signal_user_data_t *ud, const gchar *name, gint titleindex) } else { - subtitle_opts.count = LANG_TABLE_SIZE+2; - subtitle_opts.map = g_malloc((LANG_TABLE_SIZE+2)*sizeof(options_map_t)); + subtitle_opts.count = LANG_TABLE_SIZE+1; + subtitle_opts.map = g_malloc((LANG_TABLE_SIZE+1)*sizeof(options_map_t)); } gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, - 0, "Autoselect", + 0, "Foreign Audio Search", 1, TRUE, 2, "-1", 3, -1.0, 4, "auto", -1); - subtitle_opts.map[0].option = "Same as audio"; + subtitle_opts.map[0].option = "Foreign Audio Search"; subtitle_opts.map[0].shortOpt = "-1"; subtitle_opts.map[0].ivalue = -1; subtitle_opts.map[0].svalue = "auto"; if (count > 0) { + if (options != NULL) + g_strfreev(options); + options = g_malloc((count+1)*sizeof(gchar*)); index_str_init(count-1); for (ii = 0; ii < count; ii++) { subtitle = (hb_subtitle_t *)hb_list_item(title->list_subtitle, ii); // Skip subtitles that must be burned if there is already // a burned subtitle in the list - subtitle_opts.map[ii+1].option = subtitle->lang; + options[ii] = g_strdup_printf("%d - %s", ii+1, subtitle->lang); + subtitle_opts.map[ii+1].option = options[ii]; subtitle_opts.map[ii+1].shortOpt = index_str[ii]; subtitle_opts.map[ii+1].ivalue = ii; subtitle_opts.map[ii+1].svalue = subtitle->iso639_2; gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, - 0, subtitle->lang, + 0, options[ii], 1, TRUE, 2, index_str[ii], 3, (gdouble)ii, 4, subtitle->iso639_2, -1); } + options[count] = NULL; } else { - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, - 0, "Closed Captions", - 1, TRUE, - 2, "-2", - 3, -2.0, - 4, "und", - -1); - subtitle_opts.map[1].option = "Closed Captions"; - subtitle_opts.map[1].shortOpt = "-2"; - subtitle_opts.map[1].ivalue = -2; - subtitle_opts.map[1].svalue = "und"; index_str_init(LANG_TABLE_SIZE-1); for (ii = 0; ii < LANG_TABLE_SIZE; ii++) { - subtitle_opts.map[ii+2].option = ghb_language_table[ii].eng_name; - subtitle_opts.map[ii+2].shortOpt = index_str[ii]; - subtitle_opts.map[ii+2].ivalue = ii; - subtitle_opts.map[ii+2].svalue = ghb_language_table[ii].iso639_2; + subtitle_opts.map[ii+1].option = ghb_language_table[ii].eng_name; + subtitle_opts.map[ii+1].shortOpt = index_str[ii]; + subtitle_opts.map[ii+1].ivalue = ii; + subtitle_opts.map[ii+1].svalue = ghb_language_table[ii].iso639_2; gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, ghb_language_table[ii].eng_name, @@ -1802,6 +1817,32 @@ ghb_longest_title() return titleindex; } +gchar* +ghb_get_source_audio_lang(gint titleindex, gint track) +{ + hb_list_t * list; + hb_title_t * title; + hb_audio_config_t * audio; + gchar *lang = NULL; + + g_debug("ghb_lookup_1st_audio_lang ()\n"); + if (h_scan == NULL) + return NULL; + list = hb_get_titles( h_scan ); + title = (hb_title_t*)hb_list_item( list, titleindex ); + if (title == NULL) + return NULL; + if (hb_list_count( title->list_audio ) <= track) + return NULL; + + audio = hb_list_audio_config_item(title->list_audio, track); + if (audio == NULL) + return NULL; + + lang = g_strdup(audio->lang.iso639_2); + return lang; +} + gint ghb_find_audio_track( gint titleindex, @@ -1960,6 +2001,21 @@ ghb_find_audio_track( } gint +ghb_find_pref_subtitle_track(const gchar *lang) +{ + gint ii, count; + count = subtitle_opts.count; + for (ii = 0; ii < count; ii++) + { + if (strcmp(lang, subtitle_opts.map[ii].svalue) == 0) + { + return subtitle_opts.map[ii].ivalue; + } + } + return -2; +} + +gint ghb_find_subtitle_track( gint titleindex, const gchar *lang, @@ -1968,8 +2024,7 @@ ghb_find_subtitle_track( hb_list_t * list; hb_title_t * title; hb_subtitle_t * subtitle; - gint ii; - gint count = 0; + gint count, ii; gboolean *used; g_debug("find_subtitle_track ()\n"); @@ -2001,52 +2056,8 @@ ghb_find_subtitle_track( return ii; } } - return -1; } - else - { - count = subtitle_opts.count; - for (ii = 0; ii < count; ii++) - { - if (strcmp(lang, subtitle_opts.map[ii].svalue) == 0) - { - return subtitle_opts.map[ii].ivalue; - } - } - return -1; - } -} - -gint -ghb_pick_subtitle_track(signal_user_data_t *ud) -{ - gint ii, count, track, candidate, first; - GValue *settings, *subtitle_list; - - first = candidate = ghb_settings_combo_int(ud->settings, "SubtitleTrack"); - subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list"); - count = ghb_array_len(subtitle_list); - for (ii = 0; ii < count; ii++) - { - settings = ghb_array_get_nth(subtitle_list, ii); - track = ghb_settings_combo_int(settings, "SubtitleTrack"); - if (candidate == track) - { - // Already in use, pick another - candidate++; - if (candidate >= subtitle_opts.count) - { - candidate = 0; - } - if (candidate == first) - { - candidate = -1; - break; - } - ii = -1; - } - } - return candidate; + return -2; } static void @@ -2218,13 +2229,14 @@ ghb_update_ui_combo_box( video_rate_opts_set(ud->builder, "VideoFramerate", hb_video_rates, hb_video_rates_count); mix_opts_set(ud->builder, "AudioMixdown"); language_opts_set(ud->builder, "SourceAudioLang"); - subtitle_opts_set(ud, "SubtitleTrack", user_data); title_opts_set(ud->builder, "title"); audio_track_opts_set(ud->builder, "AudioTrack", user_data); + subtitle_track_opts_set(ud->builder, "SubtitleTrack", user_data); generic_opts_set(ud->builder, "VideoQualityGranularity", &vqual_granularity_opts); generic_opts_set(ud->builder, "PicturePAR", &par_opts); generic_opts_set(ud->builder, "PictureModulus", &alignment_opts); generic_opts_set(ud->builder, "LoggingLevel", &logging_opts); + generic_opts_set(ud->builder, "check_updates", &appcast_update_opts); generic_opts_set(ud->builder, "FileFormat", &container_opts); generic_opts_set(ud->builder, "PictureDeinterlace", &deint_opts); generic_opts_set(ud->builder, "PictureDetelecine", &detel_opts); @@ -2251,10 +2263,10 @@ ghb_update_ui_combo_box( mix_opts_set(ud->builder, "AudioMixdown"); else if (strcmp(name, "SourceAudioLang") == 0) language_opts_set(ud->builder, "SourceAudioLang"); - else if (strcmp(name, "SubtitleTrack") == 0) - subtitle_opts_set(ud, "SubtitleTrack", user_data); else if (strcmp(name, "title") == 0) title_opts_set(ud->builder, "title"); + else if (strcmp(name, "SubtitleTrack") == 0) + subtitle_track_opts_set(ud->builder, "SubtitleTrack", user_data); else if (strcmp(name, "AudioTrack") == 0) audio_track_opts_set(ud->builder, "AudioTrack", user_data); else @@ -2276,7 +2288,6 @@ init_ui_combo_boxes(GtkBuilder *builder) init_combo_box(builder, "VideoFramerate"); init_combo_box(builder, "AudioMixdown"); init_combo_box(builder, "SourceAudioLang"); - init_combo_box(builder, "SubtitleTrack"); init_combo_box(builder, "title"); init_combo_box(builder, "AudioTrack"); for (ii = 0; combo_name_map[ii].name != NULL; ii++) @@ -2287,7 +2298,7 @@ init_ui_combo_boxes(GtkBuilder *builder) static const char * turbo_opts = "ref=1:subme=1:me=dia:analyse=none:trellis=0:" - "no-fast-pskip=0:8x8dct=0:weightb=0"; + "no-fast-pskip=0:8x8dct=0"; // Construct the x264 options string // The result is allocated, so someone must free it at some point. @@ -2378,7 +2389,7 @@ ghb_ac3_in_audio_list(const GValue *audio_list) asettings = ghb_array_get_nth(audio_list, ii); acodec = ghb_settings_combo_int(asettings, "AudioEncoder"); - if (acodec == HB_ACODEC_AC3) + if (acodec & HB_ACODEC_AC3) return TRUE; } return FALSE; @@ -2795,7 +2806,7 @@ picture_settings_deps(signal_user_data_t *ud) { gboolean autoscale, keep_aspect, enable_keep_aspect; gboolean enable_scale_width, enable_scale_height; - gboolean enable_disp_width, enable_disp_height; + gboolean enable_disp_width, enable_disp_height, enable_par; gint pic_par; GtkWidget *widget; @@ -2817,6 +2828,7 @@ picture_settings_deps(signal_user_data_t *ud) enable_scale_width = !autoscale && (pic_par != 1); enable_scale_height = !autoscale && (pic_par != 1); enable_disp_width = (pic_par == 3) && !keep_aspect; + enable_par = (pic_par == 3) && !keep_aspect; enable_disp_height = FALSE; widget = GHB_WIDGET(ud->builder, "PictureModulus"); @@ -2831,6 +2843,10 @@ picture_settings_deps(signal_user_data_t *ud) gtk_widget_set_sensitive(widget, enable_disp_width); widget = GHB_WIDGET(ud->builder, "PictureDisplayHeight"); gtk_widget_set_sensitive(widget, enable_disp_height); + widget = GHB_WIDGET(ud->builder, "PicturePARWidth"); + gtk_widget_set_sensitive(widget, enable_par); + widget = GHB_WIDGET(ud->builder, "PicturePARHeight"); + gtk_widget_set_sensitive(widget, enable_par); widget = GHB_WIDGET(ud->builder, "PictureKeepRatio"); gtk_widget_set_sensitive(widget, enable_keep_aspect); widget = GHB_WIDGET(ud->builder, "autoscale"); @@ -3008,6 +3024,11 @@ ghb_set_scale(signal_user_data_t *ud, gint mode) // The scaler crashes if the dimensions are not divisible by 2 // Align mod 2. And so does something in x264_encoder_headers() job->anamorphic.modulus = mod; + job->anamorphic.par_width = title->pixel_aspect_width; + job->anamorphic.par_height = title->pixel_aspect_height; + job->anamorphic.dar_width = 0; + job->anamorphic.dar_height = 0; + if (keep_height && pic_par == 2) width = ((double)height * crop_width / crop_height) + 0.5; job->width = width; @@ -3020,33 +3041,41 @@ ghb_set_scale(signal_user_data_t *ud, gint mode) job->crop[2] = crop[2]; job->crop[3] = crop[3]; if (job->anamorphic.mode == 3 && !keep_aspect) { - gint dar_width, dar_height; + job->anamorphic.keep_display_aspect = 0; if (mode & GHB_PIC_KEEP_PAR) { - par_width = ghb_settings_get_int(ud->settings, - "PicturePARWidth"); - par_height = ghb_settings_get_int(ud->settings, - "PicturePARHeight"); - dar_width = ((gdouble)width * par_width / par_height) + 0.5; - dar_height = height; + job->anamorphic.par_width = + ghb_settings_get_int(ud->settings, "PicturePARWidth"); + job->anamorphic.par_height = + ghb_settings_get_int(ud->settings, "PicturePARHeight"); } else { - dar_width = ghb_settings_get_int(ud->settings, - "PictureDisplayWidth"); - dar_height = ghb_settings_get_int(ud->settings, - "PictureDisplayHeight"); + job->anamorphic.dar_width = + ghb_settings_get_int(ud->settings, + "PictureDisplayWidth"); + job->anamorphic.dar_height = + ghb_settings_get_int(ud->settings, + "PictureDisplayHeight"); } - job->anamorphic.dar_width = dar_width; - job->anamorphic.dar_height = dar_height; } else { - job->anamorphic.dar_width = 0; - job->anamorphic.dar_height = 0; + job->anamorphic.keep_display_aspect = 1; } hb_set_anamorphic_size( job, &width, &height, &par_width, &par_height ); + if (job->anamorphic.mode == 3 && !keep_aspect && + mode & GHB_PIC_KEEP_PAR) + { + // hb_set_anamorphic_size reduces the par, which we + // don't want in this case because the user is + // explicitely specifying it. + par_width = ghb_settings_get_int(ud->settings, + "PicturePARWidth"); + par_height = ghb_settings_get_int(ud->settings, + "PicturePARHeight"); + } } else { @@ -3125,8 +3154,8 @@ ghb_set_scale(signal_user_data_t *ud, gint mode) } ghb_ui_update(ud, "display_aspect", ghb_string_value(str)); g_free(str); - ghb_ui_update(ud, "par_width", ghb_int64_value(par_width)); - ghb_ui_update(ud, "par_height", ghb_int64_value(par_height)); + ghb_ui_update(ud, "PicturePARWidth", ghb_int64_value(par_width)); + ghb_ui_update(ud, "PicturePARHeight", ghb_int64_value(par_height)); ghb_ui_update(ud, "PictureDisplayWidth", ghb_int64_value(disp_width)); ghb_ui_update(ud, "PictureDisplayHeight", ghb_int64_value(height)); busy = FALSE; @@ -3147,12 +3176,17 @@ set_preview_job_settings(hb_job_t *job, GValue *settings) job->height = ghb_settings_get_int(settings, "scale_height"); if (ghb_settings_get_boolean(settings, "show_crop")) { + gdouble xscale = (gdouble)job->width / + (gdouble)(job->title->width - job->crop[2] - job->crop[3]); + gdouble yscale = (gdouble)job->height / + (gdouble)(job->title->height - job->crop[0] - job->crop[1]); + + job->width += xscale * (job->crop[2] + job->crop[3]); + job->height += yscale * (job->crop[0] + job->crop[1]); job->crop[0] = 0; job->crop[1] = 0; job->crop[2] = 0; job->crop[3] = 0; - job->width = job->title->width; - job->height = job->title->height; job->anamorphic.modulus = 2; } @@ -3162,18 +3196,25 @@ set_preview_job_settings(hb_job_t *job, GValue *settings) gboolean keep_aspect; keep_aspect = ghb_settings_get_boolean(settings, "PictureKeepRatio"); - if (job->anamorphic.mode == 3 && !keep_aspect) - { - gint disp_width, disp_height; - disp_width = ghb_settings_get_int(settings, "PictureDisplayWidth"); - disp_height = ghb_settings_get_int(settings, "PictureDisplayHeight"); - job->anamorphic.dar_width = disp_width; - job->anamorphic.dar_height = disp_height; - } - else + if (job->anamorphic.mode) { + job->anamorphic.par_width = job->title->pixel_aspect_width; + job->anamorphic.par_height = job->title->pixel_aspect_height; job->anamorphic.dar_width = 0; job->anamorphic.dar_height = 0; + + if (job->anamorphic.mode == 3 && !keep_aspect) + { + job->anamorphic.keep_display_aspect = 0; + job->anamorphic.par_width = + ghb_settings_get_int(settings, "PicturePARWidth"); + job->anamorphic.par_height = + ghb_settings_get_int(settings, "PicturePARHeight"); + } + else + { + job->anamorphic.keep_display_aspect = 1; + } } } @@ -3316,20 +3357,95 @@ ghb_validate_video(signal_user_data_t *ud) message = g_strdup_printf( "Theora is not supported in the MP4 and AVI containers.\n\n" "You should choose a different video codec or container.\n" - "If you continue, XviD will be chosen for you."); + "If you continue, FFMPEG will be chosen for you."); if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue")) { g_free(message); return FALSE; } g_free(message); - vcodec = HB_VCODEC_XVID; + vcodec = HB_VCODEC_FFMPEG; ghb_ui_update(ud, "VideoEncoder", ghb_int64_value(vcodec)); } return TRUE; } gboolean +ghb_validate_subtitles(signal_user_data_t *ud) +{ + hb_list_t * list; + hb_title_t * title; + gchar *message; + + if (h_scan == NULL) return FALSE; + list = hb_get_titles( h_scan ); + if( !hb_list_count( list ) ) + { + /* No valid title, stop right there */ + g_message("No title found.\n"); + return FALSE; + } + + gint titleindex; + + titleindex = ghb_settings_combo_int(ud->settings, "title"); + title = hb_list_item( list, titleindex ); + if (title == NULL) return FALSE; + gint mux = ghb_settings_combo_int(ud->settings, "FileFormat"); + + const GValue *slist, *settings; + gint count, ii, track, source; + gboolean burned, one_burned = FALSE; + + slist = ghb_settings_get_value(ud->settings, "subtitle_list"); + count = ghb_array_len(slist); + for (ii = 0; ii < count; ii++) + { + settings = ghb_array_get_nth(slist, ii); + track = ghb_settings_combo_int(settings, "SubtitleTrack"); + burned = ghb_settings_get_boolean(settings, "SubtitleBurned"); + source = ghb_subtitle_track_source(ud, track); + if (burned && one_burned) + { + // MP4 can only handle burned vobsubs. make sure there isn't + // already something burned in the list + message = g_strdup_printf( + "Only one subtitle may be burned into the video.\n\n" + "You should change your subtitle selections.\n" + "If you continue, some subtitles will be lost."); + if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue")) + { + g_free(message); + return FALSE; + } + g_free(message); + break; + } + else if (burned) + { + one_burned = TRUE; + } + if (!burned && mux == HB_MUX_MP4 && source == VOBSUB) + { + // MP4 can only handle burned vobsubs. make sure there isn't + // already something burned in the list + message = g_strdup_printf( + "Your chosen container does not support soft bitmap subtitles.\n\n" + "You should change your subtitle selections.\n" + "If you continue, some subtitles will be lost."); + if (!ghb_message_dialog(GTK_MESSAGE_WARNING, message, "Cancel", "Continue")) + { + g_free(message); + return FALSE; + } + g_free(message); + break; + } + } + return TRUE; +} + +gboolean ghb_validate_audio(signal_user_data_t *ud) { hb_list_t * list; @@ -3550,7 +3666,6 @@ ghb_validate_vquality(GValue *settings) max = 30; } break; - case HB_VCODEC_XVID: case HB_VCODEC_FFMPEG: { min = 1; @@ -3696,8 +3811,30 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) job->deinterlace = 0; job->grayscale = ghb_settings_get_boolean(js, "VideoGrayScale"); + gboolean keep_aspect; + keep_aspect = ghb_settings_get_boolean(js, "PictureKeepRatio"); job->anamorphic.mode = ghb_settings_combo_int(js, "PicturePAR"); job->anamorphic.modulus = ghb_settings_combo_int(js, "PictureModulus"); + if (job->anamorphic.mode) + { + job->anamorphic.par_width = title->pixel_aspect_width; + job->anamorphic.par_height = title->pixel_aspect_height; + job->anamorphic.dar_width = 0; + job->anamorphic.dar_height = 0; + + if (job->anamorphic.mode == 3 && !keep_aspect) + { + job->anamorphic.keep_display_aspect = 0; + job->anamorphic.par_width = + ghb_settings_get_int(js, "PicturePARWidth"); + job->anamorphic.par_height = + ghb_settings_get_int(js, "PicturePARHeight"); + } + else + { + job->anamorphic.keep_display_aspect = 1; + } + } /* Add selected filters */ job->filters = hb_list_init(); @@ -3766,7 +3903,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) (job->vcodec == HB_VCODEC_THEORA)) { // mp4|avi/theora combination is not supported. - job->vcodec = HB_VCODEC_XVID; + job->vcodec = HB_VCODEC_FFMPEG; } if ((job->vcodec == HB_VCODEC_X264) && (job->mux == HB_MUX_MP4)) { @@ -3809,18 +3946,8 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) job->cfr = 1; } - // First remove any audios that are already in the list - // This happens if you are encoding the same title a second time. - gint num_audio_tracks = hb_list_count(job->list_audio); - gint ii; - for(ii = 0; ii < num_audio_tracks; ii++) - { - hb_audio_t *audio = (hb_audio_t*)hb_list_item(job->list_audio, 0); - hb_list_rem(job->list_audio, audio); - } - const GValue *audio_list; - gint count; + gint count, ii; gint tcount = 0; audio_list = ghb_settings_get_value(js, "audio_list"); @@ -3881,6 +4008,9 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) } audio.out.dynamic_range_compression = ghb_settings_get_double(asettings, "AudioTrackDRCSlider"); + if (audio.out.dynamic_range_compression < 1.0) + audio.out.dynamic_range_compression = 0.0; + // It would be better if this were done in libhb for us, but its not yet. if (audio.out.codec == HB_ACODEC_AC3 || audio.out.codec == HB_ACODEC_DCA) { @@ -3920,62 +4050,97 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) dest_str = ghb_settings_get_string(js, "destination"); job->file = dest_str; job->crf = ghb_settings_get_boolean(js, "constant_rate_factor"); - // TODO: libhb holds onto a reference to the x264opts and is not - // finished with it until encoding the job is done. But I can't - // find a way to get at the job before it is removed in order to - // free up the memory I am allocating here. - // The short story is THIS LEAKS. - x264opts = ghb_build_x264opts_string(js); - - if( x264opts != NULL && *x264opts != '\0' ) - { - job->x264opts = x264opts; - } - else /*avoids a bus error crash when options aren't specified*/ - { - job->x264opts = NULL; - } const GValue *subtitle_list; gint subtitle; + gboolean force, burned, def, one_burned = FALSE; subtitle_list = ghb_settings_get_value(js, "subtitle_list"); count = ghb_array_len(subtitle_list); for (ii = 0; ii < count; ii++) { GValue *ssettings; - gboolean burned; ssettings = ghb_array_get_nth(subtitle_list, ii); subtitle = ghb_settings_get_int(ssettings, "SubtitleTrack"); + force = ghb_settings_get_boolean(ssettings, "SubtitleForced"); burned = ghb_settings_get_boolean(ssettings, "SubtitleBurned"); + def = ghb_settings_get_boolean(ssettings, "SubtitleDefaultTrack"); + if (subtitle == -1) { + if (!burned && job->mux == HB_MUX_MKV) + { + job->select_subtitle_config.dest = PASSTHRUSUB; + } + else if (!burned && job->mux == HB_MUX_MP4) + { + // Skip any non-burned vobsubs when output is mp4 + continue; + } + else if (burned) + { + // Only allow one subtitle to be burned into the video + if (one_burned) + continue; + job->select_subtitle_config.dest = RENDERSUB; + one_burned = TRUE; + } + job->select_subtitle_config.force = force; + job->select_subtitle_config.default_track = def; job->indepth_scan = 1; } else if (subtitle >= 0) { hb_subtitle_t * subt; + hb_subtitle_config_t sub_config; subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle); + sub_config = subt->config; if (subt != NULL) { if (!burned && job->mux == HB_MUX_MKV && subt->format == PICTURESUB) { - subt->dest = PASSTHRUSUB; + sub_config.dest = PASSTHRUSUB; + } + else if (!burned && job->mux == HB_MUX_MP4 && + subt->format == PICTURESUB) + { + // Skip any non-burned vobsubs when output is mp4 + continue; + } + else if ( burned && subt->format == PICTURESUB ) + { + // Only allow one subtitle to be burned into the video + if (one_burned) + continue; + one_burned = TRUE; } - subt->force = ghb_settings_get_boolean(ssettings, "SubtitleForced"); - hb_list_add(job->list_subtitle, subt); + sub_config.force = force; + sub_config.default_track = def; + hb_subtitle_add( job, &sub_config, subtitle ); } } } + // TODO: libhb holds onto a reference to the x264opts and is not + // finished with it until encoding the job is done. But I can't + // find a way to get at the job before it is removed in order to + // free up the memory I am allocating here. + // The short story is THIS LEAKS. + x264opts = ghb_build_x264opts_string(js); + + if( *x264opts == '\0' ) + { + g_free(x264opts); + x264opts = NULL; + } + if (job->indepth_scan == 1) { // Subtitle scan. Look for subtitle matching audio language - char *x264opts_tmp; /* * When subtitle scan is enabled do a fast pre-scan job @@ -3983,27 +4148,15 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) */ job->pass = -1; job->indepth_scan = 1; - - x264opts_tmp = job->x264opts; job->x264opts = NULL; - job->select_subtitle = malloc(sizeof(hb_subtitle_t*)); - *(job->select_subtitle) = NULL; - /* * Add the pre-scan job */ job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24); hb_add( h, job ); - //if (job->x264opts != NULL) - // g_free(job->x264opts); - - job->x264opts = x264opts_tmp; - } - else - { - job->select_subtitle = NULL; } + if( ghb_settings_get_boolean(js, "VideoTwoPass") && !ghb_settings_get_boolean(js, "vquality_type_constant")) { @@ -4012,27 +4165,32 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) * for the second pass and then off again for the * second. */ - hb_subtitle_t **subtitle_tmp = job->select_subtitle; - job->select_subtitle = NULL; job->pass = 1; job->indepth_scan = 0; - gchar *x264opts2 = NULL; - if (x264opts) - { - x264opts2 = g_strdup(x264opts); - } + /* * If turbo options have been selected then append them * to the x264opts now (size includes one ':' and the '\0') */ if( ghb_settings_get_boolean(js, "VideoTurboTwoPass") ) { - char *tmp_x264opts; + gchar *tmp_x264opts; + gchar *extra_opts; + gint badapt; + badapt = ghb_lookup_badapt(x264opts); + if (badapt == 2) + { + extra_opts = g_strdup_printf("%s", turbo_opts); + } + else + { + extra_opts = g_strdup_printf("%s:weightb=0", turbo_opts); + } + if ( x264opts ) { - tmp_x264opts = g_strdup_printf("%s:%s", x264opts, turbo_opts); - g_free(x264opts); + tmp_x264opts = g_strdup_printf("%s:%s", x264opts, extra_opts); } else { @@ -4040,10 +4198,14 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) * No x264opts to modify, but apply the turbo options * anyway as they may be modifying defaults */ - tmp_x264opts = g_strdup_printf("%s", turbo_opts); + tmp_x264opts = g_strdup_printf("%s", extra_opts); } - x264opts = tmp_x264opts; + g_free(extra_opts); + job->x264opts = tmp_x264opts; + } + else + { job->x264opts = x264opts; } job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24); @@ -4051,7 +4213,6 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) //if (job->x264opts != NULL) // g_free(job->x264opts); - job->select_subtitle = subtitle_tmp; job->pass = 2; /* * On the second pass we turn off subtitle scan so that we @@ -4060,7 +4221,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) * attribute of the job). */ job->indepth_scan = 0; - job->x264opts = x264opts2; + job->x264opts = x264opts; job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24); hb_add( h, job ); //if (job->x264opts != NULL) @@ -4068,6 +4229,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) } else { + job->x264opts = x264opts; job->indepth_scan = 0; job->pass = 0; job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24); @@ -4075,6 +4237,25 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) //if (job->x264opts != NULL) // g_free(job->x264opts); } + + // clean up audio list + gint num_audio_tracks = hb_list_count(job->list_audio); + for(ii = 0; ii < num_audio_tracks; ii++) + { + hb_audio_t *audio = (hb_audio_t*)hb_list_item(job->list_audio, 0); + hb_list_rem(job->list_audio, audio); + free(audio); + } + + // clean up subtitle list + gint num_subtitle_tracks = hb_list_count(job->list_subtitle); + for(ii = 0; ii < num_subtitle_tracks; ii++) + { + hb_subtitle_t *subtitle = hb_list_item(job->list_subtitle, 0); + hb_list_rem(job->list_subtitle, subtitle); + free(subtitle); + } + if (detel_str) g_free(detel_str); if (decomb_str) g_free(decomb_str); if (deint_str) g_free(deint_str); @@ -4383,7 +4564,6 @@ ghb_get_preview_image( w *= (gdouble)dstWidth / orig_w; h *= (gdouble)dstHeight / orig_h; } - g_debug("scaled %d x %d", dstWidth, dstHeight); GdkPixbuf *scaled_preview; scaled_preview = gdk_pixbuf_scale_simple(preview, dstWidth, dstHeight, GDK_INTERP_HYPER); if (ghb_settings_get_boolean(settings, "show_crop"))