void ghb_preview_set_visible(signal_user_data_t *ud) { gint title_id, titleindex; const hb_title_t *title; GtkToggleToolButton *button; GtkWidget *widget; gboolean active; button = GTK_TOGGLE_TOOL_BUTTON(GHB_WIDGET(ud->builder, "show_preview")); active = gtk_toggle_tool_button_get_active(button); title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); active &= title != NULL; widget = GHB_WIDGET(ud->builder, "preview_window"); gtk_widget_set_visible(widget, active); if (active) { gint x, y; x = ghb_dict_get_int(ud->prefs, "preview_x"); y = ghb_dict_get_int(ud->prefs, "preview_y"); if (x >= 0 && y >= 0) gtk_window_move(GTK_WINDOW(widget), x, y); } }
gchar* get_deblock_val(signal_user_data_t *ud) { int alpha, beta; gchar *result; alpha = ghb_dict_get_int(ud->x264_priv, "x264_deblock_alpha"); beta = ghb_dict_get_int(ud->x264_priv, "x264_deblock_beta"); result = g_strdup_printf("%d,%d", alpha, beta); return result; }
G_MODULE_EXPORT void live_preview_start_cb(GtkWidget *xwidget, signal_user_data_t *ud) { gchar *tmp_dir; gchar *name; gint frame = ud->preview->frame; tmp_dir = ghb_get_tmp_dir(); name = g_strdup_printf("%s/live%02d", tmp_dir, ud->preview->frame); free(tmp_dir); if (ud->preview->current) g_free(ud->preview->current); ud->preview->current = name; if (ud->preview->encoded[frame] && g_file_test(name, G_FILE_TEST_IS_REGULAR)) { #if defined(_ENABLE_GST) if (ud->preview->pause) live_preview_start(ud); else live_preview_pause(ud); #endif } else { GhbValue *js; GhbValue *range, *dest; ud->preview->encode_frame = frame; js = ghb_value_dup(ud->settings); ghb_finalize_job(js); range = ghb_get_job_range_settings(js); dest = ghb_get_job_dest_settings(js); ghb_dict_set_string(dest, "File", name); ghb_dict_set_string(range, "Type", "preview"); ghb_dict_set_int(range, "Start", ud->preview->frame + 1); ghb_dict_set_int(range, "End", ghb_dict_get_int(ud->prefs, "live_duration") * 90000); ghb_dict_set_int(range, "SeekPoints", ghb_dict_get_int(ud->prefs, "preview_count")); GhbValue *job_dict = ghb_dict_get(js, "Job"); ud->preview->live_id = ghb_add_job(ghb_live_handle(), job_dict); ghb_start_live_encode(); ghb_value_free(&js); } }
G_MODULE_EXPORT void video_preset_slider_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { ghb_widget_to_setting(ud->settings, widget); int presetIndex = ghb_dict_get_int(ud->settings, "VideoPresetSlider"); const char * const *video_presets; const char *preset = "medium"; int count; int encoder = ghb_get_video_encoder(ud->settings); video_presets = hb_video_encoder_get_presets(encoder); if (video_presets != NULL) { for (count = 0; video_presets[count]; count++); if (presetIndex < count) { preset = video_presets[presetIndex]; } } ghb_set_video_preset(ud->settings, encoder, preset); GhbValue *gval = ghb_dict_get_value(ud->settings, "VideoPresetSlider"); ghb_ui_settings_update(ud, ud->settings, "VideoPresetSlider", gval); ghb_check_dependency(ud, widget, NULL); ghb_clear_presets_selection(ud); update_adv_settings_tooltip(ud); }
void ghb_reset_subtitles(signal_user_data_t *ud, GhbValue *settings) { GhbValue *slist; GhbValue *subtitle; gint count, ii; gint title_id, titleindex; const hb_title_t *title; g_debug("ghb_reset_subtitles"); ghb_clear_subtitle_list_settings(ud->settings); ghb_clear_subtitle_list_ui(ud->builder); title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); if (title == NULL) return; slist = ghb_dict_get_value(settings, "subtitle_list"); count = ghb_array_len(slist); for (ii = 0; ii < count; ii++) { subtitle = ghb_value_dup(ghb_array_get(slist, ii)); subtitle_add_to_settings(ud->settings, subtitle); } subtitle_refresh_list_ui(ud); }
G_MODULE_EXPORT void subtitle_add_all_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { // Add the current subtitle settings to the list. gboolean one_burned = FALSE; gint track; const hb_title_t *title; int title_id, titleindex; title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); if (title == NULL) { return; } ghb_clear_subtitle_list_settings(ud->settings); ghb_clear_subtitle_list_ui(ud->builder); const char *mux_id; const hb_container_t *mux; mux_id = ghb_dict_get_string(ud->settings, "FileFormat"); mux = ghb_lookup_container_by_name(mux_id); int count = hb_list_count(title->list_subtitle); for (track = 0; track < count; track++) { subtitle_add_track(ud, ud->settings, title, track, mux->format, FALSE, FALSE, FALSE, &one_burned); } subtitle_refresh_list_ui(ud); ghb_live_reset(ud); }
G_MODULE_EXPORT void subtitle_srt_radio_toggled_cb(GtkWidget *widget, signal_user_data_t *ud) { GhbValue *subsettings; ghb_widget_to_setting(ud->settings, widget); subsettings = subtitle_get_selected_settings(ud, NULL); if (subsettings != NULL) { if (ghb_dict_get_bool(ud->settings, "SubtitleSrtEnable")) { ghb_dict_set_int(subsettings, "SubtitleSource", SRTSUB); } else { int track, source; track = ghb_dict_get_int(subsettings, "SubtitleTrack"); source = ghb_subtitle_track_source(ud->settings, track); ghb_dict_set_int(subsettings, "SubtitleSource", source); } subtitle_set_track_description(ud->settings, subsettings); subtitle_update_dialog_widgets(ud, subsettings); ghb_subtitle_list_refresh_selected(ud); ghb_live_reset(ud); } }
G_MODULE_EXPORT void subtitle_reset_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { int title_id, titleindex; const hb_title_t *title; title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); ghb_set_pref_subtitle(title, ud); }
static void subtitle_add_to_settings(GhbValue *settings, GhbValue *subsettings) { // Add the current subtitle settings to the list. GhbValue *subtitle_list; gint count; gboolean burned, forced, def; gint source; subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); if (subtitle_list == NULL) { subtitle_list = ghb_array_new(); ghb_dict_set(settings, "subtitle_list", subtitle_list); } // Validate some settings const char *mux_id; const hb_container_t *mux; mux_id = ghb_dict_get_string(settings, "FileFormat"); mux = ghb_lookup_container_by_name(mux_id); source = ghb_dict_get_int(subsettings, "SubtitleSource"); burned = ghb_dict_get_bool(subsettings, "SubtitleBurned"); if (burned && !hb_subtitle_can_burn(source)) { burned = FALSE; ghb_dict_set_bool(subsettings, "SubtitleBurned", burned); } if (!burned && !hb_subtitle_can_pass(source, mux->format)) { burned = TRUE; ghb_dict_set_bool(subsettings, "SubtitleBurned", burned); ghb_dict_set_bool(subsettings, "SubtitleDefaultTrack", FALSE); } def = ghb_dict_get_bool(subsettings, "SubtitleDefaultTrack"); forced = ghb_dict_get_bool(subsettings, "SubtitleForced"); if (forced && !hb_subtitle_can_force(source)) { forced = FALSE; ghb_dict_set_bool(subsettings, "SubtitleForced", forced); } ghb_array_append(subtitle_list, subsettings); // Check consistancy of exclusive flags count = ghb_array_len(subtitle_list); if (burned) ghb_subtitle_exclusive_burn_settings(settings, count-1); if (def) ghb_subtitle_exclusive_default_settings(settings, count-1); }
void init_preview_image(signal_user_data_t *ud) { GtkWidget *widget; gint width, height; g_debug("set_preview_button_image ()"); gint title_id, titleindex; const hb_title_t *title; live_preview_stop(ud); title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); if (title == NULL && ud->preview->pix != NULL) { g_object_unref(ud->preview->pix); ud->preview->pix = NULL; } widget = GHB_WIDGET (ud->builder, "preview_frame"); ud->preview->frame = ghb_widget_int(widget) - 1; if (ud->preview->encoded[ud->preview->frame]) { widget = GHB_WIDGET(ud->builder, "live_progress_box"); gtk_widget_hide (widget); widget = GHB_WIDGET(ud->builder, "live_preview_progress"); gtk_widget_show (widget); } else { widget = GHB_WIDGET(ud->builder, "live_preview_progress"); gtk_widget_hide (widget); widget = GHB_WIDGET(ud->builder, "live_progress_box"); gtk_widget_show (widget); widget = GHB_WIDGET(ud->builder, "live_encode_progress"); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(widget), ""); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(widget), 0); } if (ud->preview->pix != NULL) g_object_unref(ud->preview->pix); if (ud->preview->scaled_pix != NULL) g_object_unref(ud->preview->scaled_pix); ud->preview->pix = ghb_get_preview_image(title, ud->preview->frame, ud, &width, &height); if (ud->preview->pix == NULL) return; int pix_width, pix_height; pix_width = gdk_pixbuf_get_width(ud->preview->pix); pix_height = gdk_pixbuf_get_height(ud->preview->pix); preview_set_size(ud, pix_width, pix_height); }
void ghb_subtitle_exclusive_burn_settings(GhbValue *settings, gint index) { GhbValue *subtitle_list; GhbValue *subsettings; gint ii, count; subtitle_list = ghb_dict_get_value(settings, "subtitle_list"); subsettings = ghb_array_get(subtitle_list, index); if (subsettings != NULL) { int track = ghb_dict_get_int(subsettings, "SubtitleTrack"); if (track == -1) { // Allow 2 tracks to be marked burned when one is // foreign audio search. Extra burned track will be // sanitized away if foreign audio search actually finds // something. return; } } count = ghb_array_len(subtitle_list); for (ii = 0; ii < count; ii++) { if (ii != index) { subsettings = ghb_array_get(subtitle_list, ii); int track = ghb_dict_get_int(subsettings, "SubtitleTrack"); if (track != -1) { // Allow 2 tracks to be marked burned when one is // foreign audio search. Extra burned track will be // sanitized away if foreign audio search actually finds // something. ghb_dict_set_bool(subsettings, "SubtitleBurned", FALSE); } } } }
void ghb_preview_set_visible(signal_user_data_t *ud, gboolean visible) { GtkWidget *widget; #if 0 gint title_id, titleindex; const hb_title_t *title; title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); visible &= title != NULL; #endif widget = GHB_WIDGET(ud->builder, "preview_window"); if (visible) { gint x, y; x = ghb_dict_get_int(ud->prefs, "preview_x"); y = ghb_dict_get_int(ud->prefs, "preview_y"); if (x >= 0 && y >= 0) gtk_window_move(GTK_WINDOW(widget), x, y); gtk_window_deiconify(GTK_WINDOW(widget)); } gtk_widget_set_visible(widget, visible); }
void ghb_subtitle_title_change(signal_user_data_t *ud, gboolean show) { GtkWidget *w = GHB_WIDGET(ud->builder, "subtitle_add"); gtk_widget_set_sensitive(w, show); w = GHB_WIDGET(ud->builder, "subtitle_add_all"); gtk_widget_set_sensitive(w, show); w = GHB_WIDGET(ud->builder, "subtitle_reset"); gtk_widget_set_sensitive(w, show); int title_id, titleindex; title_id = ghb_dict_get_int(ud->settings, "title"); const hb_title_t *title = ghb_lookup_title(title_id, &titleindex); if (title != NULL) { w = GHB_WIDGET(ud->builder, "SubtitleSrtDisable"); gtk_widget_set_sensitive(w, !!hb_list_count(title->list_subtitle)); } }
G_MODULE_EXPORT void subtitle_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { GhbValue *subsettings; g_debug("subtitle_track_changed_cb()"); ghb_widget_to_setting(ud->settings, widget); subsettings = subtitle_get_selected_settings(ud, NULL); if (subsettings != NULL) { gint track, source; ghb_widget_to_setting(subsettings, widget); track = ghb_dict_get_int(subsettings, "SubtitleTrack"); source = ghb_subtitle_track_source(ud->settings, track); ghb_dict_set_int(subsettings, "SubtitleSource", source); subtitle_set_track_description(ud->settings, subsettings); subtitle_update_dialog_widgets(ud, subsettings); ghb_subtitle_list_refresh_selected(ud); ghb_live_reset(ud); } }
static void subtitle_update_dialog_widgets(signal_user_data_t *ud, GhbValue *subsettings) { GtkWidget *widget; if (subsettings != NULL) { // Update widgets with subsettings gboolean burn, force, def; const char *mux_id; const hb_container_t *mux; mux_id = ghb_dict_get_string(ud->settings, "FileFormat"); mux = ghb_lookup_container_by_name(mux_id); int source = ghb_dict_get_int(subsettings, "SubtitleSource"); ghb_ui_update_from_settings(ud, "SubtitleTrack", subsettings); ghb_ui_update_from_settings(ud, "SrtLanguage", subsettings); ghb_ui_update_from_settings(ud, "SrtCodeset", subsettings); ghb_ui_update_from_settings(ud, "SrtFile", subsettings); ghb_ui_update_from_settings(ud, "SrtOffset", subsettings); if (source == SRTSUB) { ghb_ui_update(ud, "SubtitleSrtEnable", ghb_boolean_value(TRUE)); } else { ghb_ui_update(ud, "SubtitleSrtDisable", ghb_boolean_value(TRUE)); } widget = GHB_WIDGET(ud->builder, "SubtitleBurned"); gtk_widget_set_sensitive(widget, hb_subtitle_can_burn(source) && hb_subtitle_can_pass(source, mux->format)); widget = GHB_WIDGET(ud->builder, "SubtitleForced"); gtk_widget_set_sensitive(widget, hb_subtitle_can_force(source)); widget = GHB_WIDGET(ud->builder, "SubtitleDefaultTrack"); gtk_widget_set_sensitive(widget, hb_subtitle_can_pass(source, mux->format)); burn = ghb_dict_get_int(subsettings, "SubtitleBurned"); force = ghb_dict_get_int(subsettings, "SubtitleForced"); def = ghb_dict_get_int(subsettings, "SubtitleDefaultTrack"); if (!hb_subtitle_can_burn(source)) { burn = FALSE; } if (!hb_subtitle_can_force(source)) { force = FALSE; } if (!hb_subtitle_can_pass(source, mux->format)) { def = FALSE; burn = TRUE; } ghb_dict_set_bool(subsettings, "SubtitleBurned", burn); ghb_ui_update(ud, "SubtitleBurned", ghb_boolean_value(burn)); ghb_dict_set_bool(subsettings, "SubtitleForced", force); ghb_ui_update(ud, "SubtitleForced", ghb_boolean_value(force)); ghb_dict_set_bool(subsettings, "SubtitleDefaultTrack", def); ghb_ui_update(ud, "SubtitleDefaultTrack", ghb_boolean_value(def)); // Hide regular subtitle widgets widget = GHB_WIDGET(ud->builder, "subtitle_track_box"); gtk_widget_set_visible(widget, source != SRTSUB); // Show SRT subitle widgets widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid"); gtk_widget_set_visible(widget, source == SRTSUB); } else { // Hide SRT subitle widgets widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid"); gtk_widget_set_visible(widget, FALSE); // Show regular subtitle widgets widget = GHB_WIDGET(ud->builder, "subtitle_track_box"); gtk_widget_set_visible(widget, TRUE); } }
G_MODULE_EXPORT void subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud) { // Add the current subtitle settings to the list. GhbValue *subsettings, *backup; gboolean one_burned; gint track; int title_id, titleindex; const hb_title_t *title; title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); if (title == NULL) { return; } // Back up settings in case we need to revert. backup = ghb_value_dup( ghb_dict_get_value(ud->settings, "subtitle_list")); one_burned = subtitle_is_one_burned(ud->settings); const char *mux_id; const hb_container_t *mux; mux_id = ghb_dict_get_string(ud->settings, "FileFormat"); mux = ghb_lookup_container_by_name(mux_id); int count = hb_list_count(title->list_subtitle); for (subsettings = NULL, track = 0; subsettings == NULL && track < count; track++) { subsettings = subtitle_add_track(ud, ud->settings, title, track, mux->format, FALSE, FALSE, FALSE, &one_burned); } if (subsettings == NULL) { subsettings = subtitle_add_track(ud, ud->settings, title, 0, mux->format, FALSE, TRUE, FALSE, &one_burned); } ghb_add_subtitle_to_ui(ud, subsettings); if (subsettings != NULL) { // Pop up the edit dialog GtkResponseType response; GtkWidget *dialog = GHB_WIDGET(ud->builder, "subtitle_dialog"); response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_hide(dialog); if (response != GTK_RESPONSE_OK) { ghb_dict_set(ud->settings, "subtitle_list", backup); subsettings = subtitle_get_selected_settings(ud, NULL); if (subsettings != NULL) { subtitle_update_dialog_widgets(ud, subsettings); } subtitle_refresh_list_ui(ud); } else { ghb_value_free(&backup); } } }
int main(int argc, char *argv[]) { signal_user_data_t *ud; GError *error = NULL; GOptionContext *context; #if defined(_WIN32) // Tell gdk pixbuf where it's loader config file is. _putenv_s("GDK_PIXBUF_MODULE_FILE", "ghb.exe.local/loaders.cache"); _putenv_s("GST_PLUGIN_PATH", "lib/gstreamer-1.0"); #endif hb_global_init(); #ifdef ENABLE_NLS bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain(GETTEXT_PACKAGE); #endif context = g_option_context_new(_("- Transcode media formats")); g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); g_option_context_add_group(context, gtk_get_option_group(TRUE)); #if defined(_ENABLE_GST) g_option_context_add_group(context, gst_init_get_option_group()); #endif g_option_context_parse(context, &argc, &argv, &error); if (error != NULL) { g_warning("%s: %s", G_STRFUNC, error->message); g_clear_error(&error); } g_option_context_free(context); #if defined(_WIN32) if (win32_console) { // Enable console logging if(AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()){ close(STDOUT_FILENO); freopen("CONOUT$", "w", stdout); close(STDERR_FILENO); freopen("CONOUT$", "w", stderr); } } else { // Non-console windows apps do not have a stderr->_file // assigned properly stderr->_file = STDERR_FILENO; stdout->_file = STDOUT_FILENO; } #endif if (argc > 1 && dvd_device == NULL && argv[1][0] != '-') { dvd_device = argv[1]; } gtk_init(&argc, &argv); GtkCssProvider *css = gtk_css_provider_new(); error = NULL; gtk_css_provider_load_from_data(css, MyCSS, -1, &error); if (error == NULL) { GdkScreen *ss = gdk_screen_get_default(); gtk_style_context_add_provider_for_screen(ss, GTK_STYLE_PROVIDER(css), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); } else { g_warning("%s: %s", G_STRFUNC, error->message); g_clear_error(&error); } #if !defined(_WIN32) notify_init("HandBrake"); #endif ghb_resource_init(); ghb_load_icons(); #if !defined(_WIN32) dbus_g_thread_init(); #endif ghb_udev_init(); ghb_write_pid_file(); ud = g_malloc0(sizeof(signal_user_data_t)); ud->debug = ghb_debug; g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG, debug_log_handler, ud); g_log_set_handler("Gtk", G_LOG_LEVEL_WARNING, warn_log_handler, ud); //g_log_set_handler("Gtk", G_LOG_LEVEL_CRITICAL, warn_log_handler, ud); ud->globals = ghb_dict_new(); ud->prefs = ghb_dict_new(); ud->settings_array = ghb_array_new(); ud->settings = ghb_dict_new(); ghb_array_append(ud->settings_array, ud->settings); ud->builder = create_builder_or_die(BUILDER_NAME); // Enable events that alert us to media change events watch_volumes(ud); //GtkWidget *widget = GHB_WIDGET(ud->builder, "PictureDetelecineCustom"); //gtk_entry_set_inner_border(widget, 2); // Since GtkBuilder no longer assigns object ids to widget names // Assign a few that are necessary for style overrides to work #if defined(_NO_UPDATE_CHECK) GtkWidget *widget; widget = GHB_WIDGET(ud->builder, "check_updates_box"); gtk_widget_hide(widget); #endif // Must set the names of the widgets that I want to modify // style for. gtk_widget_set_name(GHB_WIDGET(ud->builder, "preview_hud"), "preview_hud"); gtk_widget_set_name(GHB_WIDGET(ud->builder, "preview_frame"), "preview_frame"); gtk_widget_set_name(GHB_WIDGET(ud->builder, "live_preview_play"), "live_preview_play"); gtk_widget_set_name(GHB_WIDGET(ud->builder, "live_preview_progress"), "live_preview_progress"); gtk_widget_set_name(GHB_WIDGET(ud->builder, "live_encode_progress"), "live_encode_progress"); gtk_widget_set_name(GHB_WIDGET(ud->builder, "live_duration"), "live_duration"); gtk_widget_set_name(GHB_WIDGET(ud->builder, "preview_show_crop"), "preview_show_crop"); gtk_widget_set_name(GHB_WIDGET(ud->builder, "preview_fullscreen"), "preview_fullscreen"); gtk_widget_set_name(GHB_WIDGET(ud->builder, "activity_view"), "activity_view"); // Redirect stderr to the activity window ghb_preview_init(ud); IoRedirect(ud); ghb_log( "%s - %s - %s", HB_PROJECT_TITLE, HB_PROJECT_BUILD_TITLE, HB_PROJECT_URL_WEBSITE ); ghb_init_dep_map(); // Need to connect x264_options textview buffer to the changed signal // since it can't be done automatically GtkTextView *textview; GtkTextBuffer *buffer; textview = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "x264Option")); buffer = gtk_text_view_get_buffer(textview); g_signal_connect(buffer, "changed", (GCallback)x264_entry_changed_cb, ud); textview = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "VideoOptionExtra")); buffer = gtk_text_view_get_buffer(textview); g_signal_connect(buffer, "changed", (GCallback)video_option_changed_cb, ud); textview = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "MetaLongDescription")); buffer = gtk_text_view_get_buffer(textview); g_signal_connect(buffer, "changed", (GCallback)plot_changed_cb, ud); ghb_combo_init(ud); g_debug("ud %p\n", ud); g_debug("ud->builder %p\n", ud->builder); bind_audio_tree_model(ud); bind_subtitle_tree_model(ud); bind_presets_tree_model(ud); bind_queue_tree_model(ud); bind_chapter_tree_model(ud); // Connect up the signals to their callbacks // I wrote my own connector so that I could pass user data // to the callbacks. Builder's standard autoconnect doesn't all this. gtk_builder_connect_signals_full(ud->builder, MyConnect, ud); ghb_init_audio_defaults_ui(ud); ghb_init_subtitle_defaults_ui(ud); // Parsing x264 options "" initializes x264 widgets to proper defaults ghb_x264_init(ud); // Load prefs before presets. Some preset defaults may depend // on preference settings. // First load default values ghb_settings_init(ud->prefs, "Preferences"); ghb_settings_init(ud->globals, "Globals"); ghb_settings_init(ud->settings, "Initialization"); ghb_settings_init(ud->settings, "OneTimeInitialization"); // Load user preferences file ghb_prefs_load(ud); // Store user preferences into ud->prefs ghb_prefs_to_settings(ud->prefs); int logLevel = ghb_dict_get_int(ud->prefs, "LoggingLevel"); ghb_backend_init(logLevel); // Load the presets files ghb_presets_load(ud); // Note that ghb_preset_to_settings(ud->settings) is called when // the default preset is selected. ghb_settings_to_ui(ud, ud->globals); ghb_settings_to_ui(ud, ud->prefs); // Note that ghb_settings_to_ui(ud->settings) happens when initial // empty title is initialized. if (ghb_dict_get_bool(ud->prefs, "hbfd")) { ghb_hbfd(ud, TRUE); } const gchar *source = ghb_dict_get_string(ud->prefs, "default_source"); ghb_dvd_set_current(source, ud); // Populate the presets tree view ghb_presets_list_init(ud, NULL); // Get the first preset name if (arg_preset != NULL) { ghb_select_preset(ud->builder, arg_preset); } else { ghb_select_default_preset(ud->builder); } // Grey out widgets that are dependent on a disabled feature ghb_check_all_depencencies(ud); if (dvd_device != NULL) { // Source overridden from command line option ghb_dict_set_string(ud->globals, "scan_source", dvd_device); g_idle_add((GSourceFunc)ghb_idle_scan, ud); } else { GhbValue *gval = ghb_dict_get_value(ud->prefs, "default_source"); ghb_dict_set(ud->globals, "scan_source", ghb_value_dup(gval)); } // Reload and check status of the last saved queue g_idle_add((GSourceFunc)ghb_reload_queue, ud); // Start timer for monitoring libhb status, 500ms g_timeout_add(200, ghb_timer_cb, (gpointer)ud); // Add dvd devices to File menu ghb_volname_cache_init(); GHB_THREAD_NEW("Cache Volume Names", (GThreadFunc)ghb_cache_volnames, ud); GtkWidget *ghb_window = GHB_WIDGET(ud->builder, "hb_window"); gint window_width, window_height; GdkGeometry geo = { -1, -1, 1920, 768, -1, -1, 10, 10, 0, 0, GDK_GRAVITY_NORTH_WEST }; GdkWindowHints geo_mask; geo_mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_BASE_SIZE; gtk_window_set_geometry_hints(GTK_WINDOW(ghb_window), ghb_window, &geo, geo_mask); window_width = ghb_dict_get_int(ud->prefs, "window_width"); window_height = ghb_dict_get_int(ud->prefs, "window_height"); /* * Filter objects in GtkBuilder xml * Unfortunately, GtkFilter is poorly supported by GtkBuilder, * so a lot of the setup must happen in code. SourceFilterAll SourceFilterVideo SourceFilterTS SourceFilterMPG SourceFilterEVO SourceFilterVOB SourceFilterMKV SourceFilterMP4 SourceFilterAVI SourceFilterMOV SourceFilterOGG SourceFilterFLV SourceFilterWMV */ // Add filters to source chooser GtkFileFilter *filter; GtkFileChooser *chooser; chooser = GTK_FILE_CHOOSER(GHB_WIDGET(ud->builder, "source_dialog")); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterAll")); gtk_file_filter_set_name(filter, _("All")); gtk_file_filter_add_pattern(filter, "*"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterVideo")); gtk_file_filter_set_name(filter, _("Video")); gtk_file_filter_add_mime_type(filter, "video/*"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterTS")); gtk_file_filter_set_name(filter, "TS"); gtk_file_filter_add_pattern(filter, "*.ts"); gtk_file_filter_add_pattern(filter, "*.TS"); gtk_file_filter_add_pattern(filter, "*.m2ts"); gtk_file_filter_add_pattern(filter, "*.M2TS"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterMPG")); gtk_file_filter_set_name(filter, "MPG"); gtk_file_filter_add_pattern(filter, "*.mpg"); gtk_file_filter_add_pattern(filter, "*.MPG"); gtk_file_filter_add_pattern(filter, "*.mepg"); gtk_file_filter_add_pattern(filter, "*.MEPG"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterEVO")); gtk_file_filter_set_name(filter, "EVO"); gtk_file_filter_add_pattern(filter, "*.evo"); gtk_file_filter_add_pattern(filter, "*.EVO"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterVOB")); gtk_file_filter_set_name(filter, "VOB"); gtk_file_filter_add_pattern(filter, "*.vob"); gtk_file_filter_add_pattern(filter, "*.VOB"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterMKV")); gtk_file_filter_set_name(filter, "MKV"); gtk_file_filter_add_pattern(filter, "*.mkv"); gtk_file_filter_add_pattern(filter, "*.MKV"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterMP4")); gtk_file_filter_set_name(filter, "MP4"); gtk_file_filter_add_pattern(filter, "*.mp4"); gtk_file_filter_add_pattern(filter, "*.MP4"); gtk_file_filter_add_pattern(filter, "*.m4v"); gtk_file_filter_add_pattern(filter, "*.M4V"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterMOV")); gtk_file_filter_set_name(filter, "MOV"); gtk_file_filter_add_pattern(filter, "*.mov"); gtk_file_filter_add_pattern(filter, "*.MOV"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterAVI")); gtk_file_filter_set_name(filter, "AVI"); gtk_file_filter_add_pattern(filter, "*.avi"); gtk_file_filter_add_pattern(filter, "*.AVI"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterOGG")); gtk_file_filter_set_name(filter, "OGG"); gtk_file_filter_add_pattern(filter, "*.ogg"); gtk_file_filter_add_pattern(filter, "*.OGG"); gtk_file_filter_add_pattern(filter, "*.ogv"); gtk_file_filter_add_pattern(filter, "*.OGV"); gtk_file_filter_add_pattern(filter, "*.ogm"); gtk_file_filter_add_pattern(filter, "*.OGM"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterFLV")); gtk_file_filter_set_name(filter, "FLV"); gtk_file_filter_add_pattern(filter, "*.flv"); gtk_file_filter_add_pattern(filter, "*.FLV"); gtk_file_chooser_add_filter(chooser, filter); filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterWMV")); gtk_file_filter_set_name(filter, "WMV"); gtk_file_filter_add_pattern(filter, "*.wmv"); gtk_file_filter_add_pattern(filter, "*.WMV"); gtk_file_chooser_add_filter(chooser, filter); // Gtk has a really stupid bug. If the file chooser is showing // hidden files AND there is no filter set, it will not select // the filename when gtk_file_chooser_set_filename is called. // So add a completely unnessary filter to prevent this behavior. filter = GTK_FILE_FILTER(GHB_OBJECT(ud->builder, "SourceFilterAll")); gtk_file_chooser_set_filter(chooser, filter); #if !GTK_CHECK_VERSION(3, 16, 0) PangoFontDescription *font_desc; font_desc = pango_font_description_from_string("monospace 10"); textview = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "activity_view")); gtk_widget_override_font(GTK_WIDGET(textview), font_desc); pango_font_description_free(font_desc); #endif // Grrrr! Gtk developers !!!hard coded!!! the width of the // radio buttons in GtkStackSwitcher to 100!!! // // Thankfully, GtkStackSwitcher is a regular container object // and we can access the buttons to change their width. GList *stack_switcher_children, *link; GtkContainer * stack_switcher = GTK_CONTAINER( GHB_WIDGET(ud->builder, "SettingsStackSwitcher")); link = stack_switcher_children = gtk_container_get_children(stack_switcher); while (link != NULL) { GtkWidget *widget = link->data; gtk_widget_set_size_request(widget, -1, -1); gtk_widget_set_hexpand(widget, TRUE); gtk_widget_set_halign(widget, GTK_ALIGN_FILL); link = link->next; } g_list_free(stack_switcher_children); gtk_window_resize(GTK_WINDOW(ghb_window), window_width, window_height); gtk_widget_show(ghb_window); // Everything should be go-to-go. Lets rock! gtk_main(); ghb_backend_close(); ghb_value_free(&ud->queue); ghb_value_free(&ud->settings_array); ghb_value_free(&ud->prefs); ghb_value_free(&ud->globals); ghb_value_free(&ud->x264_priv); g_io_channel_unref(ud->activity_log); ghb_settings_close(); ghb_resource_free(); #if !defined(_WIN32) notify_uninit(); #endif g_object_unref(ud->builder); g_free(ud->current_dvd_device); g_free(ud); return 0; }
static void update_adv_settings_tooltip(signal_user_data_t *ud) { if (video_option_tooltip == NULL) { GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "VideoOptionExtra")); video_option_tooltip = gtk_widget_get_tooltip_text(eo); } int encoder = ghb_get_video_encoder(ud->settings); if (!ghb_dict_get_bool(ud->settings, "x264UseAdvancedOptions") && (encoder & HB_VCODEC_X264_MASK)) { GString *str = g_string_new(""); const char *preset; const char *tune; const char *profile; const char *level; const char *opts; char *tunes; preset = ghb_dict_get_string(ud->settings, "VideoPreset"); tune = ghb_dict_get_string(ud->settings, "VideoTune"); profile = ghb_dict_get_string(ud->settings, "VideoProfile"); level = ghb_dict_get_string(ud->settings, "VideoLevel"); opts = ghb_dict_get_string(ud->settings, "VideoOptionExtra"); if (tune[0] && strcmp(tune, "none")) { g_string_append_printf(str, "%s", tune); } if (ghb_dict_get_bool(ud->settings, "x264FastDecode")) { g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "fastdecode"); } if (ghb_dict_get_bool(ud->settings, "x264ZeroLatency")) { g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "zerolatency"); } tunes = g_string_free(str, FALSE); char * new_opts; int w = ghb_dict_get_int(ud->settings, "scale_width"); int h = ghb_dict_get_int(ud->settings, "scale_height"); if (w == 0 || h == 0) { if (!ghb_dict_get_bool(ud->settings, "autoscale")) { w = ghb_dict_get_int(ud->settings, "PictureWidth"); h = ghb_dict_get_int(ud->settings, "PictureHeight"); if (h == 0 && w != 0) { h = w * 9 / 16; } if (w == 0 && h != 0) { w = h * 16 / 9; } } if (w == 0 || h == 0) { w = 1280; h = 720; } } if (!strcasecmp(profile, "auto")) { profile = ""; } if (!strcasecmp(level, "auto")) { level = ""; } new_opts = hb_x264_param_unparse(hb_video_encoder_get_depth(encoder), preset, tunes, opts, profile, level, w, h); if (new_opts) ghb_update_x264Option(ud, new_opts); else ghb_update_x264Option(ud, ""); GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "VideoOptionExtra")); char * tt; if (new_opts) tt = g_strdup_printf(_("%s\n\nExpanded Options:\n\"%s\""), video_option_tooltip, new_opts); else tt = g_strdup_printf(_("%s\n\nExpanded Options:\n\"\""), video_option_tooltip); gtk_widget_set_tooltip_text(eo, tt); g_free(tt); g_free(new_opts); g_free(tunes); } else if (ghb_dict_get_bool(ud->settings, "x264UseAdvancedOptions")) { const char *opts = ghb_dict_get_string(ud->settings, "x264Option"); GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "VideoOptionExtra")); char * tt; if (opts) tt = g_strdup_printf(_("%s\n\nExpanded Options:\n\"%s\""), video_option_tooltip, opts); else tt = g_strdup_printf(_("%s\n\nExpanded Options:\n\"\""), video_option_tooltip); gtk_widget_set_tooltip_text(eo, tt); g_free(tt); } }
// Construct the x264 options string // The result is allocated, so someone must free it at some point. static gchar* sanitize_x264opts(signal_user_data_t *ud, const gchar *options) { GString *x264opts = g_string_new(""); gchar **split = g_strsplit(options, ":", -1); gint ii; // Fix up option dependencies gint subme = ghb_settings_combo_int(ud->x264_priv, "x264_subme"); if (subme < 6) { x264_remove_opt(split, x264_psy_syns); } gint trell = ghb_settings_combo_int(ud->x264_priv, "x264_trellis"); if (subme >= 10) { gint aqmode = ghb_lookup_aqmode(options); if (trell != 2 || aqmode == 0) { gint pos = x264_find_opt(split, x264_subme_syns); g_free(split[pos]); split[pos] = g_strdup_printf("subme=9"); } } if (trell < 1) { gint psy; gdouble psy_rd = 0., psy_trell; psy = x264_find_opt(split, x264_psy_syns); if (psy >= 0) { gchar *pos = strchr(split[psy], '='); if (pos != NULL) { x264_parse_psy(pos+1, &psy_rd, &psy_trell); } g_free(split[psy]); split[psy] = g_strdup_printf("psy-rd=%g|0", psy_rd); } } gint bframes = ghb_dict_get_int(ud->x264_priv, "x264_bframes"); if (bframes == 0) { x264_remove_opt(split, x264_direct_syns); x264_remove_opt(split, x264_badapt_syns); } if (bframes <= 1) { x264_remove_opt(split, x264_bpyramid_syns); } // Remove entries that match the defaults for (ii = 0; split[ii] != NULL; ii++) { gchar *val = NULL; gchar *opt = g_strdup(split[ii]); gchar *pos = strchr(opt, '='); if (pos != NULL) { val = pos + 1; *pos = 0; } else { val = "1"; } const gchar *def_val; def_val = x264_opt_get_default(opt); if (strcmp(val, def_val) == 0) { // Matches the default, so remove it split[ii][0] = 0; } g_free(opt); } for (ii = 0; split[ii] != NULL; ii++) { if (split[ii][0] != 0) g_string_append_printf(x264opts, "%s:", split[ii]); } g_strfreev(split); // strip the trailing ":" gchar *result; gint len; result = g_string_free(x264opts, FALSE); len = strlen(result); if (len > 0) result[len - 1] = 0; return result; }
static void subtitle_set_track_description(GhbValue *settings, GhbValue *subsettings) { char *desc = NULL; if (ghb_dict_get_int(subsettings, "SubtitleSource") == SRTSUB) { const gchar *filename, *code; const gchar *lang; lang = ghb_settings_combo_option(subsettings, "SrtLanguage"); code = ghb_dict_get_string(subsettings, "SrtCodeset"); filename = ghb_dict_get_string(subsettings, "SrtFile"); if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { gchar *basename; basename = g_path_get_basename(filename); desc = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename); g_free(basename); } else { desc = g_strdup_printf("%s (%s)(SRT)", lang, code); } } else { int title_id, titleindex; const hb_title_t *title; int track; hb_subtitle_t *subtitle; title_id = ghb_dict_get_int(settings, "title"); title = ghb_lookup_title(title_id, &titleindex); track = ghb_dict_get_int(subsettings, "SubtitleTrack"); if (track < 0) { desc = g_strdup(_("Foreign Audio Search")); } else { subtitle = ghb_get_subtitle_info(title, track); if (subtitle != NULL) { desc = g_strdup_printf("%d - %s (%s)", track + 1, subtitle->lang, hb_subsource_name(subtitle->source)); } } } if (desc != NULL) { ghb_dict_set_string( subsettings, "SubtitleTrackDescription", desc); } else { ghb_dict_set_string( subsettings, "SubtitleTrackDescription", "Error!"); } g_free(desc); }
static void subtitle_refresh_list_row_ui( GtkTreeModel *tm, GtkTreeIter *ti, GhbValue *subsettings) { GtkTreeIter cti; gboolean forced, burned, def; char *info_src, *info_src_2; char *info_dst, *info_dst_2; info_src_2 = NULL; info_dst_2 = NULL; forced = ghb_dict_get_bool(subsettings, "SubtitleForced"); burned = ghb_dict_get_bool(subsettings, "SubtitleBurned"); def = ghb_dict_get_bool(subsettings, "SubtitleDefaultTrack"); info_src = g_strdup_printf("<small>%s</small>", ghb_dict_get_string(subsettings, "SubtitleTrackDescription")); if (ghb_dict_get_int(subsettings, "SubtitleSource") == SRTSUB) { gint offset; offset = ghb_dict_get_int(subsettings, "SrtOffset"); if (offset != 0) { info_dst_2 = g_strdup_printf("Offset: %dms", offset); } } GString *str = g_string_new("<small>"); g_string_append_printf(str, "%s ", burned ? "Burned Into Video" : "Passthrough"); if (forced) { g_string_append_printf(str, "(Forced Subtitles Only)"); } if (def) { g_string_append_printf(str, "(Default)"); } g_string_append_printf(str, "</small>"); info_dst = g_string_free(str, FALSE); gtk_tree_store_set(GTK_TREE_STORE(tm), ti, // These are displayed in list 0, info_src, 1, "-->", 2, info_dst, 3, "hb-edit", 4, "hb-remove", 5, 0.5, -1); if (info_src_2 != NULL || info_dst_2 != NULL) { if (info_src_2 == NULL) info_src_2 = g_strdup(""); if (info_dst_2 == NULL) info_dst_2 = g_strdup(""); if (!gtk_tree_model_iter_children(tm, &cti, ti)) { gtk_tree_store_append(GTK_TREE_STORE(tm), &cti, ti); } gtk_tree_store_set(GTK_TREE_STORE(tm), &cti, // These are displayed in list 0, info_src_2, 2, info_dst_2, 5, 0.0, -1); } else { if (gtk_tree_model_iter_children(tm, &cti, ti)) { gtk_tree_store_remove(GTK_TREE_STORE(tm), &cti); } } g_free(info_src); g_free(info_src_2); g_free(info_dst); g_free(info_dst_2); }
void ghb_set_preview_image(signal_user_data_t *ud) { GtkWidget *widget; gint preview_width, preview_height, target_height, width, height; g_debug("set_preview_button_image ()"); gint title_id, titleindex; const hb_title_t *title; live_preview_stop(ud); title_id = ghb_dict_get_int(ud->settings, "title"); title = ghb_lookup_title(title_id, &titleindex); if (title == NULL) return; widget = GHB_WIDGET (ud->builder, "preview_frame"); ud->preview->frame = ghb_widget_int(widget) - 1; if (ud->preview->encoded[ud->preview->frame]) { widget = GHB_WIDGET(ud->builder, "live_progress_box"); gtk_widget_hide (widget); widget = GHB_WIDGET(ud->builder, "live_preview_progress"); gtk_widget_show (widget); } else { widget = GHB_WIDGET(ud->builder, "live_preview_progress"); gtk_widget_hide (widget); widget = GHB_WIDGET(ud->builder, "live_progress_box"); gtk_widget_show (widget); widget = GHB_WIDGET(ud->builder, "live_encode_progress"); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(widget), ""); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(widget), 0); } if (ud->preview->pix != NULL) g_object_unref(ud->preview->pix); ud->preview->pix = ghb_get_preview_image(title, ud->preview->frame, ud, &width, &height); if (ud->preview->pix == NULL) return; preview_width = gdk_pixbuf_get_width(ud->preview->pix); preview_height = gdk_pixbuf_get_height(ud->preview->pix); widget = GHB_WIDGET (ud->builder, "preview_image"); if (preview_width != ud->preview->width || preview_height != ud->preview->height) { preview_set_size(ud, preview_width, preview_height); } gtk_widget_queue_draw(widget); gchar *text = g_strdup_printf("%d x %d", width, height); widget = GHB_WIDGET (ud->builder, "preview_dims"); gtk_label_set_text(GTK_LABEL(widget), text); g_free(text); g_debug("preview %d x %d", preview_width, preview_height); target_height = MIN(ud->preview->button_height, 200); height = target_height; width = preview_width * height / preview_height; if (width > 400) { width = 400; height = preview_height * width / preview_width; } if ((height >= 16) && (width >= 16)) { GdkPixbuf *scaled_preview; scaled_preview = gdk_pixbuf_scale_simple (ud->preview->pix, width, height, GDK_INTERP_NEAREST); if (scaled_preview != NULL) { widget = GHB_WIDGET (ud->builder, "preview_button_image"); gtk_image_set_from_pixbuf(GTK_IMAGE(widget), scaled_preview); g_object_unref(scaled_preview); } } }