summaryrefslogtreecommitdiffstats
path: root/gtk/src/preview.c
diff options
context:
space:
mode:
authorJohn Stebbins <[email protected]>2016-03-15 11:35:07 -0600
committerJohn Stebbins <[email protected]>2016-03-15 11:36:54 -0600
commit0e309a8f0deb18f759904fa865506f341ff207bd (patch)
tree1c68e4ee5fbcd7c5af6e52a7fd69d74396a3592b /gtk/src/preview.c
parentd961c289a20d9e2e84fd8c763baa1c6abdb4b414 (diff)
LinGui: simplify live preview and preview hud code
This makes live preview playback somewhat less efficient. But the code is more portable and doesn't have some of the glitchy issues with rendering the HUD.
Diffstat (limited to 'gtk/src/preview.c')
-rw-r--r--gtk/src/preview.c989
1 files changed, 310 insertions, 679 deletions
diff --git a/gtk/src/preview.c b/gtk/src/preview.c
index 865702b05..361a5e09d 100644
--- a/gtk/src/preview.c
+++ b/gtk/src/preview.c
@@ -29,19 +29,8 @@
#include <glib-object.h>
#include "ghbcompat.h"
-#if !defined(_WIN32)
-#include <gdk/gdkx.h>
-#else
-#include <gdk/gdkwin32.h>
-#endif
-
#if defined(_ENABLE_GST)
#include <gst/gst.h>
-#if GST_CHECK_VERSION(1, 0, 0)
-#include <gst/video/videooverlay.h>
-#else
-#include <gst/interfaces/xoverlay.h>
-#endif
#include <gst/video/video.h>
#include <gst/pbutils/missing-plugins.h>
#endif
@@ -62,83 +51,40 @@ struct preview_s
{
#if defined(_ENABLE_GST)
GstElement *play;
- gulong xid;
+ GstElement *vsink;
#endif
- gint64 len;
- gint64 pos;
- gboolean seek_lock;
- gboolean progress_lock;
- gint width;
- gint height;
- GtkWidget *view;
- GdkPixbuf *pix;
- gint button_width;
- gint button_height;
- gint frame;
- gint state;
- gboolean pause;
- gboolean encoded[GHB_PREVIEW_MAX];
- gint encode_frame;
- gint live_id;
- gchar *current;
- gint live_enabled;
+ gint64 len;
+ gint64 pos;
+ gboolean seek_lock;
+ gboolean progress_lock;
+ gint width;
+ gint height;
+ GtkWidget * view;
+ GdkPixbuf * pix;
+ gint button_width;
+ gint button_height;
+ gint frame;
+ gint state;
+ gboolean pause;
+ gboolean encoded[GHB_PREVIEW_MAX];
+ gint encode_frame;
+ gint live_id;
+ gchar * current;
+ gint live_enabled;
};
#if defined(_ENABLE_GST)
G_MODULE_EXPORT gboolean live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data);
-static GstBusSyncReply create_window(GstBus *bus, GstMessage *msg,
- gpointer data);
#endif
void
ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d)
{
-#if defined(_ENABLE_GST)
- GValue disp_par = {0,};
- GstElement *xover;
- 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)
- {
- GValue par_prop = {0,};
-
- g_value_init(&par_prop, pspec->value_type);
- g_object_get_property(G_OBJECT(xover), "pixel-aspect-ratio",
- &par_prop);
- if (!g_value_transform(&par_prop, &disp_par))
- {
- g_warning("transform failed");
- gst_value_set_fraction(&disp_par, 1, 1);
- }
- g_value_unset(&par_prop);
- }
- *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:
+ // Assume 1:1
+ // I could get it from GtkWindow->GdkScreen monitor methods.
+ // But it's going to be 1:1 anyway, so why bother.
*par_n = 1;
*par_d = 1;
-#else
- *par_n = 1;
- *par_d = 1;
-#endif
}
void
@@ -162,12 +108,6 @@ ghb_par_scale(signal_user_data_t *ud, gint *width, gint *height, gint par_n, gin
*height = *height * den / num;
}
-static GdkWindow*
-preview_window(GtkWidget *widget)
-{
- return gtk_layout_get_bin_window(GTK_LAYOUT(widget));
-}
-
void
preview_set_size(signal_user_data_t *ud, int width, int height)
{
@@ -175,7 +115,6 @@ preview_set_size(signal_user_data_t *ud, int width, int height)
widget = GHB_WIDGET (ud->builder, "preview_image");
gtk_widget_set_size_request(widget, width, height);
- gtk_layout_set_size(GTK_LAYOUT(widget), width, height);
widget = GHB_WIDGET (ud->builder, "preview_hud_box");
gtk_widget_set_size_request(widget, width, height);
@@ -188,61 +127,21 @@ 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);
-
- ud->preview->pause = TRUE;
+ ud->preview = g_malloc0(sizeof(preview_t));
+ 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);
+ ud->preview->live_id = -1;
- widget = GHB_WIDGET(ud->builder, "preview_hud");
- gtk_widget_realize(widget);
- // Use a native window for the HUD. Client side windows don't get
- // updated properly as video changes benieth them.
- // This also seems to be required to make the preview hud visible
- // on win32. otherwise it is transparent for some reason.
- if (!gdk_window_ensure_native(gtk_widget_get_window(widget)))
- {
- g_message("Couldn't create native window for HUD.");
- }
+ 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 (!gdk_window_ensure_native(preview_window(ud->preview->view)))
- {
- 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;
- }
-#if !defined(_WIN32)
- ud->preview->xid = GDK_WINDOW_XID(preview_window(ud->preview->view));
-#else
- ud->preview->xid = GDK_WINDOW_HWND(preview_window(ud->preview->view));
-#endif
- ud->preview->play = gst_element_factory_make("playbin", "play");
- xover = gst_element_factory_make("gconfvideosink", "xover");
- if (xover == NULL)
- {
- xover = gst_element_factory_make("xvimagesink", "xover");
- }
- if (xover == NULL)
- {
- xover = gst_element_factory_make("ximagesink", "xover");
- }
- if (xover == NULL)
- {
- xover = gst_element_factory_make("autovideosink", "xover");
- }
- if (ud->preview->play == NULL || xover == NULL)
+ ud->preview->play = gst_element_factory_make("playbin", "play");
+ ud->preview->vsink = gst_element_factory_make("gdkpixbufsink", "pixsink");
+ if (ud->preview->play == NULL || ud->preview->vsink == NULL)
{
g_message("Couldn't initialize gstreamer. Disabling live preview.");
GtkWidget *widget = GHB_WIDGET(ud->builder, "live_preview_box");
@@ -253,18 +152,14 @@ ghb_preview_init(signal_user_data_t *ud)
}
else
{
-
- g_object_set(G_OBJECT(ud->preview->play), "video-sink", xover, NULL);
+ g_object_set(ud->preview->vsink, "qos", FALSE,
+ "max-lateness", (gint64) - 1, NULL);
+ g_object_set(ud->preview->play, "video-sink", ud->preview->vsink, NULL);
g_object_set(ud->preview->play, "subtitle-font-desc",
- "sans bold 20", NULL);
+ "sans bold 20", NULL);
bus = gst_pipeline_get_bus(GST_PIPELINE(ud->preview->play));
gst_bus_add_watch(bus, live_preview_cb, ud);
-#if GST_CHECK_VERSION(1, 0, 0)
- gst_bus_set_sync_handler(bus, create_window, ud->preview, NULL);
-#else
- gst_bus_set_sync_handler(bus, create_window, ud->preview);
-#endif
gst_object_unref(bus);
ud->preview->live_enabled = 1;
}
@@ -287,42 +182,101 @@ ghb_preview_cleanup(signal_user_data_t *ud)
}
#if defined(_ENABLE_GST)
-static GstBusSyncReply
-create_window(GstBus *bus, GstMessage *msg, gpointer data)
+void
+live_preview_start(signal_user_data_t *ud)
{
- preview_t *preview = (preview_t*)data;
+ GtkImage *img;
+ gchar *uri;
- switch (GST_MESSAGE_TYPE(msg))
+ if (!ud->preview->live_enabled)
+ return;
+
+ img = GTK_IMAGE(GHB_WIDGET(ud->builder, "live_preview_play_image"));
+ if (!ud->preview->encoded[ud->preview->frame])
{
- case GST_MESSAGE_ELEMENT:
+ gtk_image_set_from_icon_name(img, GHB_PLAY_ICON, GTK_ICON_SIZE_BUTTON);
+ gst_element_set_state(ud->preview->play, GST_STATE_NULL);
+ ud->preview->pause = TRUE;
+ return;
+ }
+
+ if (ud->preview->state != PREVIEW_STATE_LIVE)
{
-#if GST_CHECK_VERSION(1, 0, 0)
- if (!gst_is_video_overlay_prepare_window_handle_message(msg))
- return GST_BUS_PASS;
- gst_video_overlay_set_window_handle(
- GST_VIDEO_OVERLAY(GST_MESSAGE_SRC(msg)), preview->xid);
-#else
- 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);
+#if defined(_WIN32)
+ uri = g_strdup_printf("file:///%s", ud->preview->current);
#else
- gst_directdraw_sink_set_window_id(
- GST_X_OVERLAY(GST_MESSAGE_SRC(msg)), preview->xid);
+ uri = g_strdup_printf("file://%s", ud->preview->current);
+#endif
+ gtk_image_set_from_icon_name(img, GHB_PAUSE_ICON, GTK_ICON_SIZE_BUTTON);
+ ud->preview->state = PREVIEW_STATE_LIVE;
+ g_object_set(G_OBJECT(ud->preview->play), "uri", uri, NULL);
+ g_free(uri);
+ }
+ gst_element_set_state(ud->preview->play, GST_STATE_PLAYING);
+ ud->preview->pause = FALSE;
+}
+
+void
+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_icon_name(img, GHB_PLAY_ICON, GTK_ICON_SIZE_BUTTON);
+ gst_element_set_state(ud->preview->play, GST_STATE_PAUSED);
+ ud->preview->pause = TRUE;
+}
#endif
+
+void
+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_icon_name(img, GHB_PLAY_ICON, GTK_ICON_SIZE_BUTTON);
+#if defined(_ENABLE_GST)
+ gst_element_set_state(ud->preview->play, GST_STATE_NULL);
#endif
- gst_message_unref(msg);
- return GST_BUS_DROP;
- } break;
+ ud->preview->pause = TRUE;
+ ud->preview->state = PREVIEW_STATE_IMAGE;
+
+ progress = GTK_RANGE(GHB_WIDGET(ud->builder, "live_preview_progress"));
+ gtk_range_set_value(progress, 0);
+}
- default:
+void
+ghb_live_reset(signal_user_data_t *ud)
+{
+ gboolean encoded;
+
+ if (ud->preview->live_id >= 0)
{
- } break;
+ ghb_stop_live_encode();
}
- return GST_BUS_PASS;
+ ud->preview->live_id = -1;
+ ud->preview->encode_frame = -1;
+ if (!ud->preview->pause)
+ live_preview_stop(ud);
+ if (ud->preview->current)
+ {
+ g_free(ud->preview->current);
+ ud->preview->current = NULL;
+ }
+ encoded = ud->preview->encoded[ud->preview->frame];
+ memset(ud->preview->encoded, 0, sizeof(gboolean) * GHB_PREVIEW_MAX);
+ if (encoded)
+ ghb_set_preview_image(ud);
}
+#if defined(_ENABLE_GST)
static void
caps_set(GstCaps *caps, signal_user_data_t *ud)
{
@@ -380,7 +334,6 @@ caps_set(GstCaps *caps, signal_user_data_t *ud)
}
}
-#if GST_CHECK_VERSION(1, 0, 0)
static void
update_stream_info(signal_user_data_t *ud)
{
@@ -407,88 +360,10 @@ update_stream_info(signal_user_data_t *ud)
caps_set(caps, ud);
gst_caps_unref(caps);
}
- //g_signal_connect(vpad, "notify::caps", G_CALLBACK(caps_set_cb), preview);
gst_object_unref(vpad);
}
}
-#else
-
-static GList *
-get_stream_info_objects_for_type (GstElement *play, const gchar *typestr)
-{
- GList *info_list = NULL, *link;
- GList *ret = NULL;
-
- if (play == NULL)
- return NULL;
-
- g_object_get(play, "stream-info", &info_list, NULL);
- if (info_list == NULL)
- return NULL;
-
- link = info_list;
- while (link)
- {
- GObject *info_obj = (GObject*)link->data;
- if (info_obj)
- {
- GParamSpec *pspec;
- GEnumValue *value;
- gint type = -1;
-
- g_object_get(info_obj, "type", &type, NULL);
- pspec = g_object_class_find_property(
- G_OBJECT_GET_CLASS (info_obj), "type");
- value = g_enum_get_value(
- G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
- if (value)
- {
- if (g_ascii_strcasecmp (value->value_nick, typestr) == 0 ||
- g_ascii_strcasecmp (value->value_name, typestr) == 0)
- {
- ret = g_list_prepend (ret, g_object_ref (info_obj));
- }
- }
- }
- if (link) link = link->next;
- }
- return g_list_reverse (ret);
-}
-
-static void
-update_stream_info(signal_user_data_t *ud)
-{
- GList *vstreams, *ll;
- GstPad *vpad = NULL;
-
- vstreams = get_stream_info_objects_for_type(ud->preview->play, "video");
- if (vstreams)
- {
- for (ll = vstreams; vpad == NULL && ll != NULL; ll = ll->next)
- {
- g_object_get(ll->data, "object", &vpad, NULL);
- }
- }
- if (vpad)
- {
- GstCaps *caps;
-
- caps = gst_pad_get_negotiated_caps(vpad);
- if (caps)
- {
- caps_set(caps, ud);
- gst_caps_unref(caps);
- }
- //g_signal_connect(vpad, "notify::caps", G_CALLBACK(caps_set_cb), preview);
- gst_object_unref(vpad);
- }
- g_list_foreach(vstreams, (GFunc)g_object_unref, NULL);
- g_list_free(vstreams);
-}
-
-#endif
-
G_MODULE_EXPORT gboolean
live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data)
{
@@ -496,290 +371,232 @@ live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data)
switch (GST_MESSAGE_TYPE(msg))
{
- case GST_MESSAGE_UNKNOWN:
- {
- //printf("unknown");
- } break;
+ case GST_MESSAGE_UNKNOWN:
+ {
+ //printf("unknown");
+ } break;
- case GST_MESSAGE_EOS:
- {
- // Done
- GtkImage *img;
+ case GST_MESSAGE_EOS:
+ {
+ // Done
+ //printf("eos\n");
+ live_preview_stop(ud);
+ gst_element_seek(ud->preview->play, 1.0,
+ GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
+ GST_SEEK_TYPE_SET, 0,
+ GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
+ } break;
+
+ case GST_MESSAGE_ERROR:
+ {
+ //printf("error\n");
+ GError *err;
+ gchar *debug;
+
+ gst_message_parse_error(msg, &err, &debug);
+ g_warning("Gstreamer Error: %s", err->message);
+ g_error_free(err);
+ g_free(debug);
+ } break;
+
+ case GST_MESSAGE_WARNING:
+ case GST_MESSAGE_INFO:
+ case GST_MESSAGE_TAG:
+ case GST_MESSAGE_BUFFERING:
+ case GST_MESSAGE_STATE_CHANGED:
+ {
+ //printf("state change %x\n", state);
+ GstState state, pending;
+ gst_element_get_state(ud->preview->play, &state, &pending, 0);
+ if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING)
+ {
+ update_stream_info(ud);
+ }
+ } break;
- //printf("eos");
- img = GTK_IMAGE(GHB_WIDGET(ud->builder, "live_preview_play_image"));
- gtk_image_set_from_icon_name(img, GHB_PLAY_ICON, GTK_ICON_SIZE_BUTTON);
- gst_element_set_state(ud->preview->play, GST_STATE_PAUSED);
- ud->preview->pause = TRUE;
- gst_element_seek(ud->preview->play, 1.0,
- GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
- GST_SEEK_TYPE_SET, 0,
- GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
- } break;
+ case GST_MESSAGE_STATE_DIRTY:
+ {
+ //printf("state dirty\n");
+ } break;
- case GST_MESSAGE_ERROR:
- {
- //printf("error\n");
- GError *err;
- gchar *debug;
-
- gst_message_parse_error(msg, &err, &debug);
- g_warning("Gstreamer Error: %s", err->message);
- g_error_free(err);
- g_free(debug);
- } break;
-
- case GST_MESSAGE_WARNING:
- case GST_MESSAGE_INFO:
- case GST_MESSAGE_TAG:
- case GST_MESSAGE_BUFFERING:
- case GST_MESSAGE_STATE_CHANGED:
- {
- GstState state, pending;
- gst_element_get_state(ud->preview->play, &state, &pending, 0);
- //printf("state change %x\n", state);
- if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING)
+ case GST_MESSAGE_STEP_DONE:
{
- update_stream_info(ud);
- }
- } break;
+ //printf("step done\n");
+ } break;
- case GST_MESSAGE_STATE_DIRTY:
- {
- //printf("state dirty\n");
- } break;
+ case GST_MESSAGE_CLOCK_PROVIDE:
+ {
+ //printf("clock provide\n");
+ } break;
- case GST_MESSAGE_STEP_DONE:
- {
- //printf("step done\n");
- } break;
+ case GST_MESSAGE_CLOCK_LOST:
+ {
+ //printf("clock lost\n");
+ } break;
- case GST_MESSAGE_CLOCK_PROVIDE:
- {
- //printf("clock provide\n");
- } break;
+ case GST_MESSAGE_NEW_CLOCK:
+ {
+ //printf("new clock\n");
+ } break;
- case GST_MESSAGE_CLOCK_LOST:
- {
- //printf("clock lost\n");
- } break;
+ case GST_MESSAGE_STRUCTURE_CHANGE:
+ {
+ //printf("structure change\n");
+ } break;
- case GST_MESSAGE_NEW_CLOCK:
- {
- //printf("new clock\n");
- } break;
+ case GST_MESSAGE_STREAM_STATUS:
+ {
+ //printf("stream status\n");
+ } break;
- case GST_MESSAGE_STRUCTURE_CHANGE:
- {
- //printf("structure change\n");
- } break;
+ case GST_MESSAGE_APPLICATION:
+ {
+ //printf("application\n");
+ } break;
- case GST_MESSAGE_STREAM_STATUS:
- {
- //printf("stream status\n");
- } break;
+ case GST_MESSAGE_ELEMENT:
+ {
+ //printf("element\n");
+ if (gst_is_missing_plugin_message(msg))
+ {
+ GtkWindow *hb_window;
+ hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window"));
+ gst_element_set_state(ud->preview->play, GST_STATE_PAUSED);
+ gchar *message, *desc;
+ desc = gst_missing_plugin_message_get_description(msg);
+ message = g_strdup_printf(
+ _("Missing GStreamer plugin\n"
+ "Audio or Video may not play as expected\n\n%s"),
+ desc);
+ ghb_message_dialog(hb_window, GTK_MESSAGE_WARNING,
+ message, "Ok", NULL);
+ g_free(message);
+ gst_element_set_state(ud->preview->play, GST_STATE_PLAYING);
+ }
+ else if (msg->src == GST_OBJECT_CAST(ud->preview->vsink))
+ {
+ const GstStructure *gstStruct;
+ const GValue *val;
- case GST_MESSAGE_APPLICATION:
- {
- //printf("application\n");
- } break;
+ gstStruct = gst_message_get_structure(msg);
+ if (gstStruct != NULL &&
+ (gst_structure_has_name(gstStruct, "preroll-pixbuf") ||
+ gst_structure_has_name(gstStruct, "pixbuf")))
+ {
+ val = gst_structure_get_value(gstStruct, "pixbuf");
+ if (val != NULL)
+ {
+ GdkPixbuf *pixbuf;
+ GtkWidget *widget;
+ int width, height;
+
+ pixbuf = GDK_PIXBUF(g_value_dup_object(val));
+ width = gdk_pixbuf_get_width(pixbuf);
+ height = gdk_pixbuf_get_height(pixbuf);
+ if (width != ud->preview->width ||
+ height != ud->preview->height)
+ {
+ GdkPixbuf *tmp;
+ tmp = gdk_pixbuf_scale_simple(pixbuf,
+ ud->preview->width,
+ ud->preview->height,
+ GDK_INTERP_BILINEAR);
+ g_object_unref(pixbuf);
+ pixbuf = tmp;
+ }
+ if (ud->preview->pix != NULL)
+ {
+ g_object_unref(ud->preview->pix);
+ }
+ ud->preview->pix = pixbuf;
+ widget = GHB_WIDGET (ud->builder, "preview_image");
+ gtk_widget_queue_draw(widget);
+ }
+ }
+ }
+ } break;
- case GST_MESSAGE_ELEMENT:
- {
- //printf("element\n");
- if (gst_is_missing_plugin_message(msg))
+ case GST_MESSAGE_SEGMENT_START:
{
- GtkWindow *hb_window;
- hb_window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window"));
- gst_element_set_state(ud->preview->play, GST_STATE_PAUSED);
- gchar *message, *desc;
- desc = gst_missing_plugin_message_get_description(msg);
- message = g_strdup_printf(
- _("Missing GStreamer plugin\n"
- "Audio or Video may not play as expected\n\n%s"),
- desc);
- ghb_message_dialog(hb_window, GTK_MESSAGE_WARNING,
- message, "Ok", NULL);
- g_free(message);
- gst_element_set_state(ud->preview->play, GST_STATE_PLAYING);
- }
- } break;
-
- case GST_MESSAGE_SEGMENT_START:
- {
- //printf("segment start\n");
- } break;
+ //printf("segment start\n");
+ } break;
- case GST_MESSAGE_SEGMENT_DONE:
- {
- //printf("segment done\n");
- } break;
+ case GST_MESSAGE_SEGMENT_DONE:
+ {
+ //printf("segment done\n");
+ } break;
-#if GST_CHECK_VERSION(1, 0, 0)
- case GST_MESSAGE_DURATION_CHANGED:
- {
- //printf("duration change\n");
- };
-#endif
+ case GST_MESSAGE_DURATION_CHANGED:
+ {
+ //printf("duration change\n");
+ };
- case GST_MESSAGE_LATENCY:
- {
- //printf("latency\n");
- };
+ case GST_MESSAGE_LATENCY:
+ {
+ //printf("latency\n");
+ };
- case GST_MESSAGE_ASYNC_START:
- {
- //printf("async start\n");
- } break;
+ case GST_MESSAGE_ASYNC_START:
+ {
+ //printf("async start\n");
+ } break;
- case GST_MESSAGE_ASYNC_DONE:
- {
- //printf("async done\n");
- } break;
+ case GST_MESSAGE_ASYNC_DONE:
+ {
+ //printf("async done\n");
+ } break;
- case GST_MESSAGE_REQUEST_STATE:
- {
- //printf("request state\n");
- } break;
+ case GST_MESSAGE_REQUEST_STATE:
+ {
+ //printf("request state\n");
+ } break;
- case GST_MESSAGE_STEP_START:
- {
- //printf("step start\n");
- } break;
+ case GST_MESSAGE_STEP_START:
+ {
+ //printf("step start\n");
+ } break;
- case GST_MESSAGE_QOS:
- {
- //printf("qos\n");
- } break;
+ case GST_MESSAGE_QOS:
+ {
+ //printf("qos\n");
+ } break;
-#if GST_CHECK_VERSION(1, 0, 0)
- case GST_MESSAGE_PROGRESS:
- {
- //printf("progress\n");
- } break;
+ case GST_MESSAGE_PROGRESS:
+ {
+ //printf("progress\n");
+ } break;
- case GST_MESSAGE_TOC:
- {
- //printf("toc\n");
- } break;
+ case GST_MESSAGE_TOC:
+ {
+ //printf("toc\n");
+ } break;
- case GST_MESSAGE_RESET_TIME:
- {
- //printf("reset time\n");
- } break;
+ case GST_MESSAGE_RESET_TIME:
+ {
+ //printf("reset time\n");
+ } break;
- case GST_MESSAGE_STREAM_START:
- {
- //printf("stream start\n");
- };
-#endif
+ case GST_MESSAGE_STREAM_START:
+ {
+ //printf("stream start\n");
+ };
- case GST_MESSAGE_ANY:
- {
- //printf("any\n");
- } break;
+ case GST_MESSAGE_ANY:
+ {
+ //printf("any\n");
+ } break;
- default:
- {
- // Ignore
- //printf("?msg? %x\n", GST_MESSAGE_TYPE(msg));
- }
+ default:
+ {
+ // Ignore
+ //printf("?msg? %x\n", GST_MESSAGE_TYPE(msg));
+ }
}
return TRUE;
}
-
-void
-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])
- {
- gtk_image_set_from_icon_name(img, GHB_PLAY_ICON, GTK_ICON_SIZE_BUTTON);
- gst_element_set_state(ud->preview->play, GST_STATE_NULL);
- ud->preview->pause = TRUE;
- return;
- }
-
-#if defined(_WIN32)
- uri = g_strdup_printf("file:///%s", ud->preview->current);
-#else
- uri = g_strdup_printf("file://%s", ud->preview->current);
-#endif
- gtk_image_set_from_icon_name(img, GHB_PAUSE_ICON, GTK_ICON_SIZE_BUTTON);
- ud->preview->state = PREVIEW_STATE_LIVE;
- g_object_set(G_OBJECT(ud->preview->play), "uri", uri, NULL);
- gst_element_set_state(ud->preview->play, GST_STATE_PLAYING);
- ud->preview->pause = FALSE;
- g_free(uri);
-}
-
-void
-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_icon_name(img, GHB_PLAY_ICON, GTK_ICON_SIZE_BUTTON);
- gst_element_set_state(ud->preview->play, GST_STATE_PAUSED);
- ud->preview->pause = TRUE;
-}
#endif
-void
-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_icon_name(img, GHB_PLAY_ICON, GTK_ICON_SIZE_BUTTON);
-#if defined(_ENABLE_GST)
- gst_element_set_state(ud->preview->play, GST_STATE_NULL);
-#endif
- ud->preview->pause = TRUE;
- ud->preview->state = PREVIEW_STATE_IMAGE;
-
- progress = GTK_RANGE(GHB_WIDGET(ud->builder, "live_preview_progress"));
- gtk_range_set_value(progress, 0);
-}
-
-void
-ghb_live_reset(signal_user_data_t *ud)
-{
- gboolean encoded;
-
- if (ud->preview->live_id >= 0)
- {
- ghb_stop_live_encode();
- }
- ud->preview->live_id = -1;
- ud->preview->encode_frame = -1;
- if (!ud->preview->pause)
- live_preview_stop(ud);
- if (ud->preview->current)
- {
- g_free(ud->preview->current);
- ud->preview->current = NULL;
- }
- encoded = ud->preview->encoded[ud->preview->frame];
- memset(ud->preview->encoded, 0, sizeof(gboolean) * GHB_PREVIEW_MAX);
- if (encoded)
- ghb_set_preview_image(ud);
-}
-
G_MODULE_EXPORT void
live_preview_start_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
@@ -885,22 +702,14 @@ ghb_live_preview_progress(signal_user_data_t *ud)
return;
ud->preview->progress_lock = TRUE;
-#if GST_CHECK_VERSION(1, 0, 0)
if (gst_element_query_duration(ud->preview->play, fmt, &len))
-#else
- if (gst_element_query_duration(ud->preview->play, &fmt, &len))
-#endif
{
if (len != -1 && fmt == GST_FORMAT_TIME)
{
ud->preview->len = len / GST_MSECOND;
}
}
-#if GST_CHECK_VERSION(1, 0, 0)
if (gst_element_query_position(ud->preview->play, fmt, &pos))
-#else
- if (gst_element_query_position(ud->preview->play, &fmt, &pos))
-#endif
{
if (pos != -1 && fmt == GST_FORMAT_TIME)
{
@@ -1040,181 +849,12 @@ ghb_set_preview_image(signal_user_data_t *ud)
}
}
-static cairo_region_t*
-curved_rect_mask(GtkWidget *widget)
-{
- GdkWindow *window;
- cairo_region_t *shape;
- cairo_surface_t *surface;
- cairo_t *cr;
- double w, h;
- int radius;
-
- if (!gtk_widget_get_realized(widget))
- return NULL;
-
- window = gtk_widget_get_window(widget);
- w = gdk_window_get_width(window);
- h = gdk_window_get_height(window);
- if (w <= 50 || h <= 50)
- return NULL;
- radius = h / 4;
- surface = gdk_window_create_similar_surface(window,
- CAIRO_CONTENT_COLOR_ALPHA,
- w, h);
- cr = cairo_create (surface);
-
- if (radius > w / 2)
- radius = w / 2;
- if (radius > h / 2)
- radius = h / 2;
-
- // fill shape with black
- cairo_save(cr);
- cairo_rectangle (cr, 0, 0, w, h);
- cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
- cairo_fill (cr);
- cairo_restore (cr);
-
- cairo_move_to (cr, 0, radius);
- cairo_curve_to (cr, 0 , 0, 0 , 0, radius, 0);
- cairo_line_to (cr, w - radius, 0);
- cairo_curve_to (cr, w, 0, w, 0, w, radius);
- cairo_line_to (cr, w , h - radius);
- cairo_curve_to (cr, w, h, w, h, w - radius, h);
- cairo_line_to (cr, 0 + radius, h);
- cairo_curve_to (cr, 0, h, 0, h, 0, h - radius);
-
- cairo_close_path(cr);
-
- cairo_set_source_rgb(cr, 1, 1, 1);
- cairo_fill(cr);
-
- cairo_destroy(cr);
- shape = gdk_cairo_region_create_from_surface(surface);
- cairo_surface_destroy(surface);
-
- return shape;
-}
-
-static void
-hud_update_shape(GtkWidget *widget)
-{
- cairo_region_t *shape;
- shape = curved_rect_mask(widget);
- if (shape != NULL)
- {
- gtk_widget_shape_combine_region(widget, shape);
- cairo_region_destroy(shape);
- }
-}
-
-#if defined(_ENABLE_GST)
-#if GST_CHECK_VERSION(1, 0, 0)
-G_MODULE_EXPORT gboolean
-delayed_expose_cb(signal_user_data_t *ud)
-{
- GstElement *vsink;
- GstVideoOverlay *vover;
-
- 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))
- vover = GST_VIDEO_OVERLAY(gst_bin_get_by_interface(
- GST_BIN(vsink), GST_TYPE_VIDEO_OVERLAY));
- else
- vover = GST_VIDEO_OVERLAY(vsink);
- gst_video_overlay_expose(vover);
- // This function is initiated by g_idle_add. Must return false
- // so that it is not called again
- return FALSE;
-}
-#else
-G_MODULE_EXPORT gboolean
-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));
- else
- xover = GST_X_OVERLAY(vsink);
- gst_x_overlay_expose(xover);
- // This function is initiated by g_idle_add. Must return false
- // so that it is not called again
- return FALSE;
-}
-#endif
-#endif
-
G_MODULE_EXPORT gboolean
preview_draw_cb(
GtkWidget *widget,
cairo_t *cr,
signal_user_data_t *ud)
{
-#if defined(_ENABLE_GST)
-#if GST_CHECK_VERSION(1, 0, 0)
- if (ud->preview->live_enabled && ud->preview->state == PREVIEW_STATE_LIVE)
- {
- if (GST_STATE(ud->preview->play) >= GST_STATE_PAUSED)
- {
- GstElement *vsink;
- GstVideoOverlay *vover;
-
- g_object_get(ud->preview->play, "video-sink", &vsink, NULL);
- if (GST_IS_BIN(vsink))
- vover = GST_VIDEO_OVERLAY(gst_bin_get_by_interface(
- GST_BIN(vsink), GST_TYPE_VIDEO_OVERLAY));
- else
- vover = GST_VIDEO_OVERLAY(vsink);
- gst_video_overlay_expose(vover);
- // For some reason, the exposed region doesn't always get
- // cleaned up here. But a delayed gst_x_overlay_expose()
- // takes care of it.
- g_idle_add((GSourceFunc)delayed_expose_cb, ud);
- }
- return FALSE;
- }
-#else
- if (ud->preview->live_enabled && ud->preview->state == PREVIEW_STATE_LIVE)
- {
- if (GST_STATE(ud->preview->play) >= GST_STATE_PAUSED)
- {
- GstElement *vsink;
- GstXOverlay *xover;
-
- g_object_get(ud->preview->play, "video-sink", &vsink, NULL);
- if (GST_IS_BIN(vsink))
- xover = GST_X_OVERLAY(gst_bin_get_by_interface(
- GST_BIN(vsink), GST_TYPE_X_OVERLAY));
- else
- xover = GST_X_OVERLAY(vsink);
- gst_x_overlay_expose(xover);
- // For some reason, the exposed region doesn't always get
- // cleaned up here. But a delayed gst_x_overlay_expose()
- // takes care of it.
- g_idle_add((GSourceFunc)delayed_expose_cb, ud);
- }
- return FALSE;
- }
-#endif
-#endif
-
if (ud->preview->pix != NULL)
{
_draw_pixbuf(cr, ud->preview->pix);
@@ -1487,15 +1127,6 @@ preview_motion_cb(
return FALSE;
}
-G_MODULE_EXPORT void
-hud_size_alloc_cb(
- GtkWidget *widget,
- GtkAllocation *allocation,
- signal_user_data_t *ud)
-{
- hud_update_shape(widget);
-}
-
G_MODULE_EXPORT gboolean
preview_configure_cb(
GtkWidget *widget,