OSDN Git Service

MacGui: Remove Target Size as a rate control option as it doesn't really work correct...
[handbrake-jp/handbrake-jp-git.git] / gtk / src / preview.c
index ef5f8c7..796700d 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * preview.c
- * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
+ * Copyright (C) John Stebbins 2008-2011 <stebbins@stebbins>
  * 
  * preview.c is free software.
  * 
@@ -62,6 +62,7 @@ struct preview_s
        gint encode_frame;
        gint live_id;
        gchar *current;
+       gint live_enabled;
 };
 
 #if defined(_ENABLE_GST)
@@ -82,10 +83,19 @@ ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d)
        GObjectClass *klass;
        GParamSpec *pspec;
 
+       if (!ud->preview->live_enabled)
+               goto fail;
+
        g_value_init(&disp_par, GST_TYPE_FRACTION);
        gst_value_set_fraction(&disp_par, 1, 1);
        g_object_get(ud->preview->play, "video-sink", &xover, NULL);
+       if (xover == NULL)
+               goto fail;
+
        klass = G_OBJECT_GET_CLASS(xover);
+       if (klass == NULL)
+               goto fail;
+
        pspec = g_object_class_find_property(klass, "pixel-aspect_ratio");
        if (pspec)
        {
@@ -104,6 +114,11 @@ ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d)
        *par_n = gst_value_get_fraction_numerator(&disp_par);
        *par_d = gst_value_get_fraction_denominator(&disp_par);
        g_value_unset(&disp_par);
+       return;
+
+fail:
+       *par_n = 1;
+       *par_d = 1;
 #else
        *par_n = 1;
        *par_d = 1;
@@ -122,12 +137,17 @@ ghb_par_scale(signal_user_data_t *ud, gint *width, gint *height, gint par_n, gin
        num = par_n * disp_par_d;
        den = par_d * disp_par_n;
 
-       *width = *width * num / den;
+       if (par_n > par_d)
+               *width = *width * num / den;
+       else
+               *height = *height * den / num;
 }
 
 void
 ghb_preview_init(signal_user_data_t *ud)
 {
+       GtkWidget *widget;
+
        ud->preview = g_malloc0(sizeof(preview_t));
        ud->preview->view = GHB_WIDGET(ud->builder, "preview_image");
        gtk_widget_realize(ud->preview->view);
@@ -137,25 +157,64 @@ ghb_preview_init(signal_user_data_t *ud)
        ud->preview->pause = TRUE;
        ud->preview->encode_frame = -1;
        ud->preview->live_id = -1;
-
+       widget = GHB_WIDGET (ud->builder, "preview_button_image");
+       gtk_widget_get_size_request(widget, &ud->preview->button_width, &ud->preview->button_height);
+       
 #if defined(_ENABLE_GST)
        GstBus *bus;
        GstElement *xover;
 
+#if GTK_CHECK_VERSION(2,18,0)
+       if (!gdk_window_ensure_native(ud->preview->view->window))
+       {
+               g_message("Couldn't create native window for GstXOverlay. Disabling live preview.");
+               GtkWidget *widget = GHB_WIDGET(ud->builder, "live_preview_box");
+               gtk_widget_hide (widget);
+               widget = GHB_WIDGET(ud->builder, "live_preview_duration_box");
+               gtk_widget_hide (widget);
+               return;
+       }
+#endif
+
+#if !defined(_WIN32)
        ud->preview->xid = GDK_DRAWABLE_XID(ud->preview->view->window);
+#else
+       ud->preview->xid = GDK_WINDOW_HWND(ud->preview->view->window);
+#endif
        ud->preview->play = gst_element_factory_make("playbin", "play");
-       //xover = gst_element_factory_make("xvimagesink", "xover");
-       //xover = gst_element_factory_make("ximagesink", "xover");
        xover = gst_element_factory_make("gconfvideosink", "xover");
-       g_object_set(G_OBJECT(ud->preview->play), "video-sink", xover, NULL);
-       //g_object_set(G_OBJECT(xover), "force-aspect-ratio", TRUE, NULL);
+       if (xover == NULL)
+       {
+               xover = gst_element_factory_make("xvimagesink", "xover");
+       }
+       if (xover == NULL)
+       {
+               xover = gst_element_factory_make("ximagesink", "xover");
+       }
+       if (ud->preview->play == NULL || xover == NULL)
+       {
+               g_message("Couldn't initialize gstreamer. Disabling live preview.");
+               GtkWidget *widget = GHB_WIDGET(ud->builder, "live_preview_box");
+               gtk_widget_hide (widget);
+               widget = GHB_WIDGET(ud->builder, "live_preview_duration_box");
+               gtk_widget_hide (widget);
+               return;
+       }
+       else
+       {
+
+               g_object_set(G_OBJECT(ud->preview->play), "video-sink", xover, NULL);
+               g_object_set(ud->preview->play, "subtitle-font-desc", 
+                                       "sans bold 20", NULL);
 
-       bus = gst_pipeline_get_bus(GST_PIPELINE(ud->preview->play));
-       gst_bus_add_watch(bus, live_preview_cb, ud);
-       gst_bus_set_sync_handler(bus, create_window, ud->preview);
-       gst_object_unref(bus);
+               bus = gst_pipeline_get_bus(GST_PIPELINE(ud->preview->play));
+               gst_bus_add_watch(bus, live_preview_cb, ud);
+               gst_bus_set_sync_handler(bus, create_window, ud->preview);
+               gst_object_unref(bus);
+               ud->preview->live_enabled = 1;
+       }
 #else
-       GtkWidget *widget = GHB_WIDGET(ud->builder, "live_preview_box");
+       widget = GHB_WIDGET(ud->builder, "live_preview_box");
        gtk_widget_hide (widget);
        widget = GHB_WIDGET(ud->builder, "live_preview_duration_box");
        gtk_widget_hide (widget);
@@ -184,8 +243,13 @@ create_window(GstBus *bus, GstMessage *msg, gpointer data)
        {
                if (!gst_structure_has_name(msg->structure, "prepare-xwindow-id"))
                        return GST_BUS_PASS;
+#if !defined(_WIN32)
                gst_x_overlay_set_xwindow_id(
                        GST_X_OVERLAY(GST_MESSAGE_SRC(msg)), preview->xid);
+#else
+               gst_directdraw_sink_set_window_id(
+                       GST_X_OVERLAY(GST_MESSAGE_SRC(msg)), preview->xid);
+#endif
                gst_message_unref(msg);
                return GST_BUS_DROP;
        } break;
@@ -407,6 +471,9 @@ live_preview_start(signal_user_data_t *ud)
        GtkImage *img;
        gchar *uri;
 
+       if (!ud->preview->live_enabled)
+               return;
+
        img = GTK_IMAGE(GHB_WIDGET(ud->builder, "live_preview_play_image"));
        if (!ud->preview->encoded[ud->preview->frame])
        {
@@ -430,6 +497,9 @@ live_preview_pause(signal_user_data_t *ud)
 {
        GtkImage *img;
 
+       if (!ud->preview->live_enabled)
+               return;
+
        img = GTK_IMAGE(GHB_WIDGET(ud->builder, "live_preview_play_image"));
        gtk_image_set_from_stock(img, "gtk-media-play", GTK_ICON_SIZE_BUTTON);
        gst_element_set_state(ud->preview->play, GST_STATE_PAUSED);
@@ -443,6 +513,9 @@ live_preview_stop(signal_user_data_t *ud)
        GtkImage *img;
        GtkRange *progress;
 
+       if (!ud->preview->live_enabled)
+               return;
+
        img = GTK_IMAGE(GHB_WIDGET(ud->builder, "live_preview_play_image"));
        gtk_image_set_from_stock(img, "gtk-media-play", GTK_ICON_SIZE_BUTTON);
 #if defined(_ENABLE_GST)
@@ -479,8 +552,6 @@ ghb_live_reset(signal_user_data_t *ud)
                ghb_set_preview_image(ud);
 }
 
-extern void hb_get_tempory_directory(hb_handle_t *h, char path[512]);
-
 G_MODULE_EXPORT void
 live_preview_start_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
@@ -567,6 +638,9 @@ ghb_live_preview_progress(signal_user_data_t *ud)
        GstFormat fmt = GST_FORMAT_TIME;
        gint64 len = -1, pos = -1;
 
+       if (!ud->preview->live_enabled)
+               return;
+
        if (ud->preview->state != PREVIEW_STATE_LIVE || ud->preview->seek_lock)
                return;
 
@@ -616,6 +690,9 @@ live_preview_seek_cb(GtkWidget *widget, signal_user_data_t *ud)
        gdouble dval;
        gint64 pos;
 
+       if (!ud->preview->live_enabled)
+               return;
+
        if (ud->preview->progress_lock)
                return;
 
@@ -667,7 +744,7 @@ ghb_set_preview_image(signal_user_data_t *ud)
 
        ud->preview->pix = 
                ghb_get_preview_image(titleindex, ud->preview->frame, 
-                                                               ud, TRUE, &width, &height);
+                                                               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);
@@ -689,9 +766,14 @@ ghb_set_preview_image(signal_user_data_t *ud)
        g_free(text);
        
        g_debug("preview %d x %d", preview_width, preview_height);
-       target_height = MIN(ud->preview->button_height, 128);
+       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))
        {
@@ -714,7 +796,13 @@ delayed_expose_cb(signal_user_data_t *ud)
        GstElement *vsink;
        GstXOverlay *xover;
 
+       if (!ud->preview->live_enabled)
+               return FALSE;
+
        g_object_get(ud->preview->play, "video-sink", &vsink, NULL);
+       if (vsink == NULL)
+               return FALSE;
+
        if (GST_IS_BIN(vsink))
                xover = GST_X_OVERLAY(gst_bin_get_by_interface(
                                                                GST_BIN(vsink), GST_TYPE_X_OVERLAY));
@@ -734,7 +822,7 @@ preview_expose_cb(
        signal_user_data_t *ud)
 {
 #if defined(_ENABLE_GST)
-       if (ud->preview->state == PREVIEW_STATE_LIVE)
+       if (ud->preview->live_enabled && ud->preview->state == PREVIEW_STATE_LIVE)
        {
                if (GST_STATE(ud->preview->play) >= GST_STATE_PAUSED)
                {
@@ -798,27 +886,40 @@ set_visible(GtkWidget *widget, gboolean visible)
        }
 }
 
-G_MODULE_EXPORT void
-preview_button_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
+void
+ghb_preview_set_visible(signal_user_data_t *ud)
 {
        gint titleindex;
+       GtkWidget *widget;
+       gboolean settings_active;
 
-       g_debug("preview_button_clicked_cb()");
+       settings_active = ghb_settings_get_boolean(ud->settings, "show_picture");
+       widget = GHB_WIDGET (ud->builder, "preview_window");
        titleindex = ghb_settings_combo_int(ud->settings, "title");
-       if (titleindex >= 0)
+       if (settings_active && titleindex >= 0)
        {
                gint x, y;
-               GtkWidget *widget = GHB_WIDGET (ud->builder, "preview_window");
                x = ghb_settings_get_int(ud->settings, "preview_x");
                y = ghb_settings_get_int(ud->settings, "preview_y");
                if (x >= 0 && y >= 0)
                        gtk_window_move(GTK_WINDOW(widget), x, y);
-               set_visible(widget, gtk_toggle_button_get_active(
-                                                       GTK_TOGGLE_BUTTON(xwidget)));
+               set_visible(widget, 
+                                       ghb_settings_get_boolean(ud->settings, "show_preview"));
+       }
+       else
+       {
+               set_visible(widget, FALSE);
        }
+}
+
+G_MODULE_EXPORT void
+preview_button_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
+{
+       g_debug("preview_button_clicked_cb()");
        ghb_widget_to_setting (ud->settings, xwidget);
-       ghb_check_dependency(ud, xwidget);
-       const gchar *name = gtk_widget_get_name(xwidget);
+       ghb_preview_set_visible(ud);
+       ghb_check_dependency(ud, xwidget, NULL);
+       const gchar *name = ghb_get_setting_key(xwidget);
        ghb_pref_save(ud->settings, name);
 }
 
@@ -826,29 +927,22 @@ G_MODULE_EXPORT void
 picture_settings_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *widget;
-       gboolean active;
+       gboolean active, hide_settings;
        gint x, y;
 
        g_debug("picture_settings_clicked_cb()");
+       ghb_widget_to_setting (ud->settings, xwidget);
+
+       hide_settings = ghb_settings_get_boolean(ud->settings, "hide_settings");
+
+       active = ghb_settings_get_boolean(ud->settings, "show_picture");
        widget = GHB_WIDGET (ud->builder, "settings_window");
-       active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(xwidget));
        x = ghb_settings_get_int(ud->settings, "settings_x");
        y = ghb_settings_get_int(ud->settings, "settings_y");
        if (x >= 0 && y >= 0)
                gtk_window_move(GTK_WINDOW(widget), x, y);
-       set_visible(widget, active);
-       if (ghb_settings_get_boolean(ud->settings, "show_preview"))
-       {
-               widget = GHB_WIDGET (ud->builder, "preview_window");
-               x = ghb_settings_get_int(ud->settings, "preview_x");
-               y = ghb_settings_get_int(ud->settings, "preview_y");
-               if (x >= 0 && y >= 0)
-                       gtk_window_move(GTK_WINDOW(widget), x, y);
-               set_visible(widget, active);
-               // The window may be hidden behind the main window, raise it
-               if (active)
-                       gtk_window_present(GTK_WINDOW(widget));
-       }
+       set_visible(widget, active && !hide_settings);
+       ghb_preview_set_visible(ud);
 }
 
 G_MODULE_EXPORT void
@@ -881,8 +975,8 @@ fullscreen_clicked_cb(GtkWidget *toggle, signal_user_data_t *ud)
 
        g_debug("fullscreen_clicked_cb()");
        ghb_widget_to_setting (ud->settings, toggle);
-       ghb_check_dependency(ud, toggle);
-       const gchar *name = gtk_widget_get_name(toggle);
+       ghb_check_dependency(ud, toggle, NULL);
+       const gchar *name = ghb_get_setting_key(toggle);
        ghb_pref_save(ud->settings, name);
 
        window = GTK_WINDOW(GHB_WIDGET (ud->builder, "preview_window"));
@@ -910,49 +1004,31 @@ picture_settings_alt2_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
        GtkWidget *toggle;
        gboolean active;
-       gint signal_id;
-       gint handler_id = 0;
+       GtkWidget *window;
 
        g_debug("picture_settings_alt2_clicked_cb()");
-       toggle = GHB_WIDGET (ud->builder, "show_picture");
-       active = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(toggle));
-       if (active)
+       ghb_widget_to_setting (ud->settings, xwidget);
+       active = ghb_settings_get_boolean(ud->settings, "hide_settings");
+
+       toggle = GHB_WIDGET (ud->builder, "hide_settings");
+       window = GHB_WIDGET(ud->builder, "settings_window");
+       if (!active)
        {
-               // I don't want deleting the settings window to also remove the
-               // preview window, but changing the toggle will do this, so temporarily
-               // ignore the toggled signal
-               signal_id = g_signal_lookup("toggled", GTK_TYPE_TOGGLE_TOOL_BUTTON);
-               if (signal_id > 0)
-               {
-                       // Valid signal id found.  This should always succeed.
-                       handler_id = g_signal_handler_find((gpointer)toggle, 
-                                                                                               G_SIGNAL_MATCH_ID, 
-                                                                                               signal_id, 0, 0, 0, 0);
-                       if (handler_id > 0)
-                       {
-                               // This should also always succeed
-                               g_signal_handler_block ((gpointer)toggle, handler_id);
-                       }
-               }
+               gtk_button_set_label(GTK_BUTTON(toggle), "Hide Settings");
+               gtk_widget_set_tooltip_text(toggle, 
+                       "Hide the picture settings window while "
+                       "leaving the preview visible.");
+               gtk_widget_show(window);
        }
-
-       GtkWidget *widget = GHB_WIDGET (ud->builder, "settings_window");
-       gint x, y;
-
-       x = ghb_settings_get_int(ud->settings, "settings_x");
-       y = ghb_settings_get_int(ud->settings, "settings_y");
-       if (x >= 0 && y >= 0)
-               gtk_window_move(GTK_WINDOW(widget), x, y);
-       set_visible(widget, !active);
-       gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toggle), !active);
-
-       if (handler_id > 0)
+       else
        {
-               g_signal_handler_unblock ((gpointer)toggle, handler_id);
+               gtk_button_set_label(GTK_BUTTON(toggle), "Show Settings");
+               gtk_widget_set_tooltip_text(toggle, "Show picture settings.");
+               gtk_widget_hide(window);
        }
 }
 
-void
+G_MODULE_EXPORT void
 preview_frame_value_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        if (ud->preview->live_id >= 0)
@@ -971,44 +1047,21 @@ preview_window_delete_cb(
        signal_user_data_t *ud)
 {
        live_preview_stop(ud);
-       gtk_widget_hide(widget);
+       widget = GHB_WIDGET (ud->builder, "show_picture");
+       gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), FALSE);
        return TRUE;
 }
 
-gboolean
+G_MODULE_EXPORT gboolean
 settings_window_delete_cb(
        GtkWidget *widget, 
        GdkEvent *event, 
        signal_user_data_t *ud)
 {
-       gint signal_id;
-       gint handler_id = 0;
-
-       gtk_widget_hide(widget);
+       live_preview_stop(ud);
        widget = GHB_WIDGET (ud->builder, "show_picture");
-
-       // I don't want deleting the settings window to also remove the
-       // preview window, but changing the toggle will do this, so temporarily
-       // ignore the toggled signal
-       signal_id = g_signal_lookup("toggled", GTK_TYPE_TOGGLE_TOOL_BUTTON);
-       if (signal_id > 0)
-       {
-               // Valid signal id found.  This should always succeed.
-               handler_id = g_signal_handler_find((gpointer)widget, G_SIGNAL_MATCH_ID, 
-                                                                                       signal_id, 0, 0, 0, 0);
-               if (handler_id > 0)
-               {
-                       // This should also always succeed
-                       g_signal_handler_block ((gpointer)widget, handler_id);
-               }
-       }
-
        gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), FALSE);
 
-       if (handler_id > 0)
-       {
-               g_signal_handler_unblock ((gpointer)widget, handler_id);
-       }
        return TRUE;
 }
 
@@ -1018,8 +1071,8 @@ preview_duration_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        g_debug("preview_duration_changed_cb ()");
        ghb_live_reset(ud);
        ghb_widget_to_setting (ud->settings, widget);
-       ghb_check_dependency(ud, widget);
-       const gchar *name = gtk_widget_get_name(widget);
+       ghb_check_dependency(ud, widget, NULL);
+       const gchar *name = ghb_get_setting_key(widget);
        ghb_pref_save(ud->settings, name);
 }
 
@@ -1115,7 +1168,7 @@ ghb_curved_rect_mask(gint width, gint height, gint radius)
        double w, h;
 
        if (!width || !height)
-       return NULL;
+               return NULL;
 
        shape = (GdkDrawable *)gdk_pixmap_new (NULL, width, height, 1);