G_MODULE_EXPORT void srt_file_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { GValue *subsettings; g_debug("srt_file_changed_cb()"); ghb_check_dependency(ud, widget, NULL); ghb_widget_to_setting(ud->settings, widget); subsettings = subtitle_get_selected_settings(ud, NULL); if (subsettings != NULL) { gchar *filename, *dirname; ghb_widget_to_setting(subsettings, widget); subtitle_set_track_description(ud->settings, subsettings); ghb_subtitle_list_refresh_selected(ud); ghb_live_reset(ud); // Update SrtDir preference filename = ghb_settings_get_string(subsettings, "SrtFile"); if (g_file_test(filename, G_FILE_TEST_IS_DIR)) { ghb_settings_set_string(ud->prefs, "SrtDir", filename); } else { dirname = g_path_get_dirname(filename); ghb_settings_set_string(ud->prefs, "SrtDir", dirname); g_free(dirname); } ghb_pref_save(ud->prefs, "SrtDir"); g_free(filename); } }
G_MODULE_EXPORT void audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { GValue *asettings; g_debug("audio_track_changed_cb ()"); if (block_updates) { ghb_check_dependency(ud, widget, NULL); ghb_grey_combo_options (ud); return; } ghb_adjust_audio_rate_combos(ud); ghb_check_dependency(ud, widget, NULL); ghb_grey_combo_options(ud); asettings = get_selected_asettings(ud); if (asettings != NULL) { const gchar *track; ghb_widget_to_setting(asettings, widget); ghb_audio_list_refresh_selected(ud); track = ghb_settings_combo_option(asettings, "AudioTrack"); ghb_settings_set_string(asettings, "AudioTrackDescription", track); } ghb_live_reset(ud); }
static void subtitle_set_track_description(GValue *settings, GValue *subsettings) { char *desc; if (ghb_settings_get_int(subsettings, "SubtitleSource") == SRTSUB) { gchar *filename, *code; const gchar *lang; lang = ghb_settings_combo_option(subsettings, "SrtLanguage"); code = ghb_settings_get_string(subsettings, "SrtCodeset"); filename = ghb_settings_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); } g_free(code); } else { int title_id, titleindex; const hb_title_t *title; int track; hb_subtitle_t *subtitle; title_id = ghb_settings_get_int(settings, "title"); title = ghb_lookup_title(title_id, &titleindex); track = ghb_settings_get_int(subsettings, "SubtitleTrack"); if (track < 0) { desc = g_strdup(_("Foreign Audio Search")); } else { subtitle = ghb_get_subtitle_info(title, track); desc = g_strdup_printf("%d - %s (%s)", track + 1, subtitle->lang, hb_subsource_name(subtitle->source)); } } ghb_settings_set_string( subsettings, "SubtitleTrackDescription", desc); g_free(desc); }
static gboolean ghb_add_audio_to_settings(GValue *settings, GValue *asettings) { GValue *audio_list; const gchar * track; int count; audio_list = ghb_settings_get_value(settings, "audio_list"); if (audio_list == NULL) { audio_list = ghb_array_value_new(8); ghb_settings_set_value(settings, "audio_list", audio_list); } count = ghb_array_len(audio_list); // Don't allow more than 99 // This is a hard limit imposed by libhb/reader.c:GetFifoForId() if (count >= 99) { ghb_value_free(asettings); return FALSE; } int title_no = ghb_settings_get_int(settings, "title_no"); int track_no = ghb_settings_get_int(asettings, "AudioTrack"); track = ghb_audio_track_description(track_no, title_no); ghb_settings_set_string(asettings, "AudioTrackDescription", track); GValue *aname; aname = ghb_dict_lookup(asettings, "AudioTrackName"); if (aname == NULL) { ghb_settings_set_string(asettings, "AudioTrackName", ""); } if (ghb_array_len(audio_list) >= 99) { ghb_value_free(asettings); return FALSE; } ghb_array_append(audio_list, asettings); return TRUE; }
static void subtitle_update_pref_lang(signal_user_data_t *ud, const iso639_lang_t *lang) { GtkLabel *label; GtkButton *button; gchar *str; const char * name = _("None"); const char * code = "und"; label = GTK_LABEL(GHB_WIDGET(ud->builder, "subtitle_preferred_language")); if (lang != NULL) { code = lang->iso639_2; if (strncmp(code, "und", 4)) { name = lang->native_name && lang->native_name[0] ? lang->native_name : lang->eng_name; } } str = g_strdup_printf(_("Preferred Language: %s"), name); gtk_label_set_text(label, str); g_free(str); ghb_settings_set_string(ud->settings, "PreferredLanguage", code); button = GTK_BUTTON(GHB_WIDGET(ud->builder, "SubtitleAddForeignAudioSubtitle")); str = g_strdup_printf(_("Add %s subtitle track if default audio is not %s"), name, name); gtk_button_set_label(button, str); g_free(str); // If there is no preferred language, hide options that require // a preferred language to be set. gboolean visible = !(lang == NULL || !strncmp(code, "und", 4)); gtk_widget_set_visible(GTK_WIDGET(button), visible); button = GTK_BUTTON(GHB_WIDGET(ud->builder, "SubtitleAddForeignAudioSearch")); gtk_widget_set_visible(GTK_WIDGET(button), visible); }
static void subtitle_set_track_description(GValue *subsettings) { char *track; if (ghb_settings_get_int(subsettings, "SubtitleSource") == SRTSUB) { gchar *filename, *code; const gchar *lang; lang = ghb_settings_combo_option(subsettings, "SrtLanguage"); code = ghb_settings_get_string(subsettings, "SrtCodeset"); filename = ghb_settings_get_string(subsettings, "SrtFile"); if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) { gchar *basename; basename = g_path_get_basename(filename); track = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename); g_free(basename); } else { track = g_strdup_printf("%s (%s)(SRT)", lang, code); } g_free(code); } else { track = g_strdup( ghb_settings_combo_option(subsettings, "SubtitleTrack")); } ghb_settings_set_string( subsettings, "SubtitleTrackDescription", track); g_free(track); }
static GValue* subtitle_add_track( signal_user_data_t *ud, GValue *settings, const hb_title_t *title, int track, int mux, gboolean default_track, gboolean srt, gboolean *burned) { int source = 0; if (track >= 0 && !srt) { hb_subtitle_t *subtitle = hb_list_item(title->list_subtitle, track); source = subtitle->source; } else if (srt) { source = SRTSUB; } if (*burned && !hb_subtitle_can_pass(source, mux)) { // Can only burn one. Skip others that must be burned. return NULL; } GValue *subsettings = ghb_dict_value_new(); ghb_settings_set_int(subsettings, "SubtitleTrack", track); ghb_settings_set_int(subsettings, "SubtitleSource", source); // Set default SRT settings gchar *pref_lang, *dir, *filename; pref_lang = ghb_settings_get_string(settings, "PreferredLanguage"); ghb_settings_set_string(subsettings, "SrtLanguage", pref_lang); g_free(pref_lang); ghb_settings_set_string(subsettings, "SrtCodeset", "UTF-8"); dir = ghb_settings_get_string(ud->prefs, "SrtDir"); filename = g_strdup_printf("%s/none", dir); ghb_settings_set_string(subsettings, "SrtFile", filename); g_free(dir); g_free(filename); ghb_settings_set_int(subsettings, "SrtOffset", 0); subtitle_set_track_description(settings, subsettings); if (!hb_subtitle_can_pass(source, mux)) { ghb_settings_set_boolean(subsettings, "SubtitleBurned", TRUE); *burned = TRUE; } else { ghb_settings_set_boolean(subsettings, "SubtitleBurned", FALSE); } if (track == -1) { // Foreign audio search "track" ghb_settings_set_boolean(subsettings, "SubtitleForced", TRUE); } else { ghb_settings_set_boolean(subsettings, "SubtitleForced", FALSE); } if (default_track) { ghb_settings_set_boolean(subsettings, "SubtitleDefaultTrack", TRUE); } else { ghb_settings_set_boolean(subsettings, "SubtitleDefaultTrack", FALSE); } subtitle_add_to_settings(settings, subsettings); return subsettings; }
int main (int argc, char *argv[]) { signal_user_data_t *ud; GValue *preset; GError *error = NULL; GOptionContext *context; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #endif if (!g_thread_supported()) g_thread_init(NULL); 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); g_option_context_free(context); if (argc > 1 && dvd_device == NULL && argv[1][0] != '-') { dvd_device = argv[1]; } gtk_init (&argc, &argv); gtk_rc_parse_string(hud_rcstyle); g_type_class_unref(g_type_class_ref(GTK_TYPE_BUTTON)); g_object_set(gtk_settings_get_default(), "gtk-button-images", TRUE, NULL); #if !defined(_WIN32) notify_init("HandBrake"); #endif ghb_register_transforms(); 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->settings = ghb_settings_new(); 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 GtkWidget *widget; #if defined(_NO_UPDATE_CHECK) widget = GHB_WIDGET(ud->builder, "check_updates_box"); gtk_widget_hide(widget); #endif widget = GHB_WIDGET(ud->builder, "preview_hud"); gtk_widget_set_name(widget, "preview_hud"); widget = GHB_WIDGET(ud->builder, "preview_window"); gtk_widget_set_name(widget, "preview_window"); // Set up the "hud" control overlay for the preview window GtkWidget *draw, *hud, *blender, *align; align = GHB_WIDGET(ud->builder, "preview_window_alignment"); draw = GHB_WIDGET(ud->builder, "preview_image_align"); hud = GHB_WIDGET(ud->builder, "preview_hud"); // Set up compositing for hud blender = ghb_compositor_new(); gtk_container_add(GTK_CONTAINER(align), blender); ghb_compositor_zlist_insert(GHB_COMPOSITOR(blender), draw, 1, 1); ghb_compositor_zlist_insert(GHB_COMPOSITOR(blender), hud, 2, .85); gtk_widget_show(blender); // 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); 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); // Load all internal settings ghb_settings_init(ud); // Load the presets files ghb_presets_load(ud); ghb_prefs_load(ud); ghb_prefs_to_ui(ud); gint logLevel; logLevel = ghb_settings_get_int(ud->settings, "LoggingLevel"); ghb_backend_init(logLevel); if (ghb_settings_get_boolean(ud->settings, "hbfd")) { ghb_hbfd(ud, TRUE); } gchar *source = ghb_settings_get_string(ud->settings, "default_source"); ghb_dvd_set_current(source, ud); g_free(source); // Parsing x264 options "" initializes x264 widgets to proper defaults ghb_x264_parse_options(ud, ""); // Populate the presets tree view ghb_presets_list_init(ud, NULL, 0); // Get the first preset name if (arg_preset != NULL) { preset = ghb_parse_preset_path(arg_preset); if (preset) { ghb_select_preset(ud->builder, preset); ghb_value_free(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_settings_set_string(ud->settings, "scan_source", dvd_device); g_idle_add((GSourceFunc)ghb_idle_scan, ud); } // 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 (500, ghb_timer_cb, (gpointer)ud); // Add dvd devices to File menu ghb_volname_cache_init(); g_thread_create((GThreadFunc)ghb_cache_volnames, ud, FALSE, NULL); #if defined(_USE_APP_IND) GtkUIManager * uim = GTK_UI_MANAGER(GHB_OBJECT(ud->builder, "uimanager1")); GtkMenu *ai_menu = GTK_MENU(gtk_ui_manager_get_widget(uim, "/ui/tray_menu")); ud->ai = app_indicator_new("HandBrake", "hb-icon", APP_INDICATOR_CATEGORY_APPLICATION_STATUS); app_indicator_set_menu( ud->ai, ai_menu ); app_indicator_set_label( ud->ai, "", "99.99%"); if (ghb_settings_get_boolean(ud->settings, "show_status")) { app_indicator_set_status( ud->ai, APP_INDICATOR_STATUS_ACTIVE ); } else { app_indicator_set_status( ud->ai, APP_INDICATOR_STATUS_PASSIVE ); } GtkStatusIcon *si; si = GTK_STATUS_ICON(GHB_OBJECT(ud->builder, "hb_status")); gtk_status_icon_set_visible(si, FALSE ); #else GtkStatusIcon *si; si = GTK_STATUS_ICON(GHB_OBJECT(ud->builder, "hb_status")); gtk_status_icon_set_visible(si, ghb_settings_get_boolean(ud->settings, "show_status")); #if GTK_CHECK_VERSION(2, 16, 0) gtk_status_icon_set_has_tooltip(si, TRUE); g_signal_connect(si, "query-tooltip", status_icon_query_tooltip_cb, ud); #else gtk_status_icon_set_tooltip(si, "HandBrake"); #endif #endif // Ugly hack to keep subtitle table from bouncing around as I change // which set of controls are visible GtkRequisition req; gint width, height; widget = GHB_WIDGET(ud->builder, "SrtCodeset"); gtk_widget_size_request( widget, &req ); height = req.height; widget = GHB_WIDGET(ud->builder, "srt_code_label"); gtk_widget_size_request( widget, &req ); height += req.height; widget = GHB_WIDGET(ud->builder, "subtitle_table"); gtk_widget_set_size_request(widget, -1, height); widget = GHB_WIDGET (ud->builder, "hb_window"); GdkGeometry geo = { -1, -1, 1024, 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(widget), widget, &geo, geo_mask); width = ghb_settings_get_int(ud->settings, "window_width"); height = ghb_settings_get_int(ud->settings, "window_height"); gtk_window_resize(GTK_WINDOW(widget), width, height); gtk_widget_show(widget); /* * 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); PangoFontDescription *font_desc; font_desc = pango_font_description_from_string ("monospace 10"); textview = GTK_TEXT_VIEW(GHB_WIDGET (ud->builder, "activity_view")); gtk_widget_modify_font(GTK_WIDGET(textview), font_desc); pango_font_description_free (font_desc); // Everything should be go-to-go. Lets rock! gtk_main (); gtk_status_icon_set_visible(si, FALSE); ghb_backend_close(); if (ud->queue) ghb_value_free(ud->queue); ghb_value_free(ud->settings); g_io_channel_unref(ud->activity_log); ghb_settings_close(); #if !defined(_WIN32) notify_uninit(); #endif g_free(ud); return 0; }
G_MODULE_EXPORT void x264_setting_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { static char *tt = NULL; if (tt == NULL) { GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); tt = gtk_widget_get_tooltip_text(eo); } ghb_widget_to_setting(ud->settings, widget); int x264Preset = ghb_settings_get_int(ud->settings, "x264PresetSlider"); const char *preset; preset = hb_video_encoder_get_presets(HB_VCODEC_X264)[x264Preset]; ghb_settings_set_string(ud->settings, "x264Preset", preset); if (!ghb_settings_get_boolean(ud->settings, "x264UseAdvancedOptions")) { GString *str = g_string_new(""); char *preset; char *tune; char *profile; char *level; char *opts; char *tunes; preset = ghb_settings_get_string(ud->settings, "x264Preset"); tune = ghb_settings_get_string(ud->settings, "x264Tune"); profile = ghb_settings_get_string(ud->settings, "h264Profile"); level = ghb_settings_get_string(ud->settings, "h264Level"); opts = ghb_settings_get_string(ud->settings, "x264OptionExtra"); if (tune[0] && strcmp(tune, "none")) { g_string_append_printf(str, "%s", tune); } if (ghb_settings_get_boolean(ud->settings, "x264FastDecode")) { g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "fastdecode"); } if (ghb_settings_get_boolean(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_settings_get_int(ud->settings, "scale_width"); int h = ghb_settings_get_int(ud->settings, "scale_height"); if (w == 0 || h == 0) { if (!ghb_settings_get_boolean(ud->settings, "autoscale")) { w = ghb_settings_get_int(ud->settings, "PictureWidth"); h = ghb_settings_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[0] = 0; } if (!strcasecmp(level, "auto")) { level[0] = 0; } new_opts = hb_x264_param_unparse( preset, tunes, opts, profile, level, w, h); if (new_opts) ghb_ui_update(ud, "x264Option", ghb_string_value(new_opts)); else ghb_ui_update(ud, "x264Option", ghb_string_value("")); GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); char * new_tt; if (new_opts) new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"%s\"", tt, new_opts); else new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"\"", tt); gtk_widget_set_tooltip_text(eo, new_tt); g_free(new_tt); g_free(new_opts); g_free(preset); g_free(tune); g_free(profile); g_free(level); g_free(opts); g_free(tunes); } else { char *opts = ghb_settings_get_string(ud->settings, "x264Option"); GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); char * new_tt; if (opts) new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"%s\"", tt, opts); else new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"\"", tt); gtk_widget_set_tooltip_text(eo, new_tt); g_free(new_tt); g_free(opts); } ghb_check_dependency(ud, widget, NULL); ghb_clear_presets_selection(ud); }
static void x264_update_combo(signal_user_data_t *ud, const gchar *name, const gchar *val) { ghb_settings_set_string(ud->x264_priv, name, val); }
void ghb_set_pref_audio_settings(gint titleindex, GValue *settings) { gint track; gchar *source_lang; hb_audio_config_t *aconfig; GHashTable *track_indices; gint mux; const GValue *pref_audio; const GValue *audio, *drc, *gain, *enable_qual; gint acodec, bitrate, mix; gdouble rate, quality; gint count, ii, list_count; g_debug("set_pref_audio"); mux = ghb_settings_combo_int(settings, "FileFormat"); track_indices = g_hash_table_new_full(g_int_hash, g_int_equal, free_audio_hash_key_value, free_audio_hash_key_value); // Clear the audio list ghb_clear_audio_list_settings(settings); // Find "best" audio based on audio preferences if (!ghb_settings_get_boolean(settings, "AudioDUB")) { source_lang = g_strdup(ghb_get_source_audio_lang(titleindex, 0)); } else { source_lang = ghb_settings_get_string(settings, "PreferredLanguage"); } pref_audio = ghb_settings_get_value(settings, "AudioList"); list_count = 0; count = ghb_array_len(pref_audio); for (ii = 0; ii < count; ii++) { gint select_acodec; gint fallback; audio = ghb_array_get_nth(pref_audio, ii); acodec = ghb_settings_combo_int(audio, "AudioEncoder"); fallback = ghb_select_fallback(settings, mux, acodec); gint copy_mask = ghb_get_copy_mask(settings); select_acodec = ghb_select_audio_codec(mux, NULL, acodec, fallback, copy_mask); bitrate = ghb_settings_combo_int(audio, "AudioBitrate"); rate = ghb_settings_combo_double(audio, "AudioSamplerate"); mix = ghb_settings_combo_int(audio, "AudioMixdown"); drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider"); gain = ghb_settings_get_value(audio, "AudioTrackGain"); enable_qual = ghb_settings_get_value(audio, "AudioTrackQualityEnable"); quality = ghb_settings_get_double(audio, "AudioTrackQuality"); // If there are multiple audios using the same codec, then // select sequential tracks for each. The hash keeps track // of the tracks used for each codec. track = ghb_find_audio_track(titleindex, source_lang, select_acodec, fallback, track_indices); // Check to see if: // 1. pref codec is passthru // 2. source codec is not passthru // 3. next pref is enabled aconfig = ghb_get_scan_audio_info(titleindex, track); if (aconfig && ghb_audio_is_passthru (acodec)) { // HB_ACODEC_* are bit fields. Treat acodec as mask if (!(aconfig->in.codec & select_acodec & HB_ACODEC_PASS_MASK)) { if (acodec != HB_ACODEC_AUTO_PASS) acodec = fallback; // If we can't substitute the passthru with a suitable // encoder and // If there's more audio to process, or we've already // placed one in the list, then we can skip this one if (!(select_acodec & fallback) && ((ii + 1 < count) || (list_count != 0))) { // Skip this audio acodec = 0; } } else { select_acodec &= aconfig->in.codec | HB_ACODEC_PASS_FLAG; } } if (titleindex >= 0 && track < 0) acodec = 0; if (acodec != 0) { GValue *asettings = ghb_dict_value_new(); ghb_settings_set_int(asettings, "AudioTrack", track); ghb_settings_set_string(asettings, "AudioEncoder", ghb_lookup_combo_string("AudioEncoder", ghb_int_value(acodec))); ghb_settings_set_value(asettings, "AudioEncoderActual", ghb_lookup_audio_encoder_value(select_acodec)); ghb_settings_set_value(asettings, "AudioTrackQualityEnable", enable_qual); ghb_settings_set_double(asettings, "AudioTrackQuality", quality); // This gets set autimatically if the codec is passthru ghb_settings_set_string(asettings, "AudioBitrate", ghb_lookup_combo_string("AudioBitrate", ghb_int_value(bitrate))); ghb_settings_set_string(asettings, "AudioSamplerate", ghb_lookup_combo_string("AudioSamplerate", ghb_int_value(rate))); mix = ghb_get_best_mix( aconfig, select_acodec, mix); ghb_settings_set_string(asettings, "AudioMixdown", ghb_lookup_combo_string("AudioMixdown", ghb_int_value(mix))); ghb_settings_set_value(asettings, "AudioTrackDRCSlider", drc); ghb_settings_set_value(asettings, "AudioTrackGain", gain); ghb_sanitize_audio(settings, asettings); ghb_add_audio_to_settings(settings, asettings); } } g_free(source_lang); g_hash_table_destroy(track_indices); }
void ghb_sanitize_audio(GValue *settings, GValue *asettings) { gint titleindex, track, acodec, select_acodec, mix; hb_audio_config_t *aconfig; gint mux; gint bitrate; gint sr; g_debug("ghb_santiize_audio ()"); mux = ghb_settings_combo_int(settings, "FileFormat"); titleindex = ghb_settings_get_int(settings, "title_no"); track = ghb_settings_combo_int(asettings, "AudioTrack"); acodec = ghb_settings_combo_int(asettings, "AudioEncoder"); mix = ghb_settings_combo_int(asettings, "AudioMixdown"); bitrate = ghb_settings_combo_int(asettings, "AudioBitrate"); sr = ghb_settings_combo_int(asettings, "AudioSamplerate"); aconfig = ghb_get_scan_audio_info(titleindex, track); if (sr == 0) { sr = aconfig ? aconfig->in.samplerate : 48000; } gint fallback = ghb_select_fallback(settings, mux, acodec); gint copy_mask = ghb_get_copy_mask(settings); select_acodec = ghb_select_audio_codec(mux, aconfig, acodec, fallback, copy_mask); if (ghb_audio_is_passthru (select_acodec)) { if (aconfig) { bitrate = aconfig->in.bitrate / 1000; // Set the values for bitrate and samplerate to the input rates mix = 0; ghb_settings_set_string(asettings, "AudioMixdown", ghb_lookup_combo_string("AudioMixdown", ghb_int_value(mix))); select_acodec &= aconfig->in.codec | HB_ACODEC_PASS_FLAG; ghb_settings_set_string(asettings, "AudioSamplerate", ghb_lookup_combo_string("AudioSamplerate", ghb_int_value(0))); } else { mix = 0; ghb_settings_set_string(asettings, "AudioMixdown", ghb_lookup_combo_string("AudioMixdown", ghb_int_value(mix))); ghb_settings_set_string(asettings, "AudioSamplerate", ghb_lookup_combo_string("AudioSamplerate", ghb_int_value(0))); bitrate = 448; } ghb_settings_set_double(asettings, "AudioTrackDRCSlider", 0.0); } else { if (mix == 0) mix = ghb_get_best_mix( aconfig, select_acodec, 0); bitrate = hb_audio_bitrate_get_best(select_acodec, bitrate, sr, mix); ghb_settings_set_string(asettings, "AudioMixdown", ghb_lookup_combo_string("AudioMixdown", ghb_int_value(mix))); } ghb_settings_set_string(asettings, "AudioBitrate", ghb_lookup_combo_string("AudioBitrate", ghb_int_value(bitrate))); ghb_settings_take_value(asettings, "AudioEncoderActual", ghb_lookup_audio_encoder_value(select_acodec)); }
int main (int argc, char *argv[]) { signal_user_data_t *ud; GValue *preset; GError *error = NULL; GOptionContext *context; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #endif if (!g_thread_supported()) g_thread_init(NULL); context = g_option_context_new ("- Rip and encode DVD or MPEG file"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); g_option_context_add_group (context, gtk_get_option_group (TRUE)); #if !defined(_WIN32) g_option_context_add_group (context, gst_init_get_option_group ()); #endif g_option_context_parse (context, &argc, &argv, &error); g_option_context_free(context); if (argc > 1 && dvd_device == NULL && argv[1][0] != '-') { dvd_device = argv[1]; } gtk_set_locale (); gtk_init (&argc, &argv); gtk_rc_parse_string(hud_rcstyle); g_type_class_unref(g_type_class_ref(GTK_TYPE_BUTTON)); g_object_set(gtk_settings_get_default(), "gtk-button-images", TRUE, NULL); #if !defined(_WIN32) notify_init("HandBrake"); #endif ghb_register_transforms(); 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->settings = ghb_settings_new(); 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 GtkWidget *widget; #if defined(_NO_UPDATE_CHECK) widget = GHB_WIDGET(ud->builder, "check_updates_box"); gtk_widget_hide(widget); #endif widget = GHB_WIDGET(ud->builder, "preview_hud"); gtk_widget_set_name(widget, "preview_hud"); widget = GHB_WIDGET(ud->builder, "preview_window"); gtk_widget_set_name(widget, "preview_window"); // Set up the "hud" control overlay for the preview window GtkWidget *draw, *hud, *blender, *align; align = GHB_WIDGET(ud->builder, "preview_window_alignment"); draw = GHB_WIDGET(ud->builder, "preview_image_align"); hud = GHB_WIDGET(ud->builder, "preview_hud"); // Set up compositing for hud blender = ghb_compositor_new(); gtk_container_add(GTK_CONTAINER(align), blender); ghb_compositor_zlist_insert(GHB_COMPOSITOR(blender), draw, 1, 1); ghb_compositor_zlist_insert(GHB_COMPOSITOR(blender), hud, 2, .85); gtk_widget_show(blender); // 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); 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); // Load all internal settings ghb_settings_init(ud); // Load the presets files ghb_presets_load(ud); ghb_prefs_load(ud); ghb_prefs_to_ui(ud); gint logLevel; logLevel = ghb_settings_get_int(ud->settings, "LoggingLevel"); ghb_backend_init(logLevel); if (ghb_settings_get_boolean(ud->settings, "hbfd")) { ghb_hbfd(ud, TRUE); } gchar *source = ghb_settings_get_string(ud->settings, "default_source"); ghb_dvd_set_current(source, ud); g_free(source); // Parsing x264 options "" initializes x264 widgets to proper defaults ghb_x264_parse_options(ud, ""); // Populate the presets tree view ghb_presets_list_init(ud, NULL, 0); // Get the first preset name if (arg_preset != NULL) { preset = ghb_parse_preset_path(arg_preset); if (preset) { ghb_select_preset(ud->builder, preset); ghb_value_free(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_settings_set_string(ud->settings, "scan_source", dvd_device); g_idle_add((GSourceFunc)ghb_idle_scan, ud); } // 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 (500, ghb_timer_cb, (gpointer)ud); // Add dvd devices to File menu ghb_volname_cache_init(); g_thread_create((GThreadFunc)ghb_cache_volnames, ud, FALSE, NULL); GtkStatusIcon *si; si = GTK_STATUS_ICON(GHB_OBJECT(ud->builder, "hb_status")); gtk_status_icon_set_visible(si, ghb_settings_get_boolean(ud->settings, "show_status")); #if GTK_CHECK_VERSION(2, 16, 0) gtk_status_icon_set_has_tooltip(si, TRUE); g_signal_connect(si, "query-tooltip", status_icon_query_tooltip_cb, ud); #else gtk_status_icon_set_tooltip(si, "HandBrake"); #endif // Ugly hack to keep subtitle table from bouncing around as I change // which set of controls are visible GtkRequisition req; gint height; widget = GHB_WIDGET(ud->builder, "SrtCodeset"); gtk_widget_size_request( widget, &req ); height = req.height; widget = GHB_WIDGET(ud->builder, "srt_code_label"); gtk_widget_size_request( widget, &req ); height += req.height; widget = GHB_WIDGET(ud->builder, "subtitle_table"); gtk_widget_set_size_request(widget, -1, height); // Everything should be go-to-go. Lets rock! gtk_main (); gtk_status_icon_set_visible(si, FALSE); ghb_backend_close(); if (ud->queue) ghb_value_free(ud->queue); ghb_value_free(ud->settings); g_io_channel_unref(ud->activity_log); ghb_settings_close(); #if !defined(_WIN32) notify_uninit(); #endif g_free(ud); return 0; }