[longomatch] player: simplify widget using a DrawingArea
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch] player: simplify widget using a DrawingArea
- Date: Sun, 4 Nov 2012 16:35:54 +0000 (UTC)
commit 8f4a93bbc1365a379be5bb354e1d45d500e4918f
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Sun Nov 4 17:35:25 2012 +0100
player: simplify widget using a DrawingArea
libcesarplayer/Makefile.am | 2 +-
libcesarplayer/bacon-video-widget-gst-0.10.c | 959 ++------------------------
libcesarplayer/bacon-video-widget.h | 4 +-
libcesarplayer/video-utils.c | 17 +-
libcesarplayer/video-utils.h | 3 +-
5 files changed, 67 insertions(+), 918 deletions(-)
---
diff --git a/libcesarplayer/Makefile.am b/libcesarplayer/Makefile.am
index 94f6a2d..d1ac415 100644
--- a/libcesarplayer/Makefile.am
+++ b/libcesarplayer/Makefile.am
@@ -45,7 +45,7 @@ libcesarplayer_la_SOURCES = \
bacon-resize.h\
video-utils.c\
video-utils.h\
- macros.h
+ macros.h
libcesarplayer_la_LDFLAGS = \
$(CESARPLAYER_LIBS)
diff --git a/libcesarplayer/bacon-video-widget-gst-0.10.c b/libcesarplayer/bacon-video-widget-gst-0.10.c
index 7d57076..9db40f2 100644
--- a/libcesarplayer/bacon-video-widget-gst-0.10.c
+++ b/libcesarplayer/bacon-video-widget-gst-0.10.c
@@ -169,7 +169,7 @@ struct BaconVideoWidgetPrivate
gboolean got_redirect;
- GdkWindow *video_window;
+ guintptr window_handle;
GdkCursor *cursor;
@@ -229,13 +229,8 @@ static void bacon_video_widget_set_property (GObject * object,
guint property_id, const GValue * value, GParamSpec * pspec);
static void bacon_video_widget_get_property (GObject * object,
guint property_id, GValue * value, GParamSpec * pspec);
-static void bvw_update_interface_implementations (BaconVideoWidget * bvw);
static void bacon_video_widget_finalize (GObject * object);
-static void bvw_update_interface_implementations (BaconVideoWidget * bvw);
-static gboolean bacon_video_widget_configure_event (GtkWidget * widget,
- GdkEventConfigure * event, BaconVideoWidget * bvw);
-static void size_changed_cb (GdkScreen * screen, BaconVideoWidget * bvw);
static void bvw_process_pending_tag_messages (BaconVideoWidget * bvw);
static void bvw_stop_play_pipeline (BaconVideoWidget * bvw);
static GError *bvw_error_from_gst_error (BaconVideoWidget * bvw,
@@ -348,259 +343,6 @@ bvw_error_msg (BaconVideoWidget * bvw, GstMessage * msg)
g_free (dbg);
}
-static void
-get_media_size (BaconVideoWidget * bvw, gint * width, gint * height)
-{
- if (bvw->priv->logo_mode) {
- if (bvw->priv->logo_pixbuf) {
- *width = gdk_pixbuf_get_width (bvw->priv->logo_pixbuf);
- *height = gdk_pixbuf_get_height (bvw->priv->logo_pixbuf);
- } else {
- *width = 0;
- *height = 0;
- }
- } else {
- if (bvw->priv->media_has_video) {
- GValue *disp_par = NULL;
- guint movie_par_n, movie_par_d, disp_par_n, disp_par_d, num, den;
-
- /* Create and init the fraction value */
- disp_par = g_new0 (GValue, 1);
- g_value_init (disp_par, GST_TYPE_FRACTION);
-
- /* Square pixel is our default */
- gst_value_set_fraction (disp_par, 1, 1);
-
- /* Now try getting display's pixel aspect ratio */
- if (bvw->priv->xoverlay) {
- GObjectClass *klass;
- GParamSpec *pspec;
-
- klass = G_OBJECT_GET_CLASS (bvw->priv->xoverlay);
- pspec = g_object_class_find_property (klass, "pixel-aspect-ratio");
-
- if (pspec != NULL) {
- GValue disp_par_prop = { 0, };
-
- g_value_init (&disp_par_prop, pspec->value_type);
- g_object_get_property (G_OBJECT (bvw->priv->xoverlay),
- "pixel-aspect-ratio", &disp_par_prop);
-
- if (!g_value_transform (&disp_par_prop, disp_par)) {
- GST_WARNING ("Transform failed, assuming pixel-aspect-ratio = 1/1");
- gst_value_set_fraction (disp_par, 1, 1);
- }
-
- g_value_unset (&disp_par_prop);
- }
- }
-
- disp_par_n = gst_value_get_fraction_numerator (disp_par);
- disp_par_d = gst_value_get_fraction_denominator (disp_par);
-
- GST_DEBUG ("display PAR is %d/%d", disp_par_n, disp_par_d);
-
- /* If movie pixel aspect ratio is enforced, use that */
- if (bvw->priv->ratio_type != BVW_RATIO_AUTO) {
- switch (bvw->priv->ratio_type) {
- case BVW_RATIO_SQUARE:
- movie_par_n = 1;
- movie_par_d = 1;
- break;
- case BVW_RATIO_FOURBYTHREE:
- movie_par_n = 4 * bvw->priv->video_height;
- movie_par_d = 3 * bvw->priv->video_width;
- break;
- case BVW_RATIO_ANAMORPHIC:
- movie_par_n = 16 * bvw->priv->video_height;
- movie_par_d = 9 * bvw->priv->video_width;
- break;
- case BVW_RATIO_DVB:
- movie_par_n = 20 * bvw->priv->video_height;
- movie_par_d = 9 * bvw->priv->video_width;
- break;
- /* handle these to avoid compiler warnings */
- case BVW_RATIO_AUTO:
- default:
- movie_par_n = 0;
- movie_par_d = 0;
- g_assert_not_reached ();
- }
- } else {
- /* Use the movie pixel aspect ratio if any */
- if (bvw->priv->movie_par) {
- movie_par_n = gst_value_get_fraction_numerator (bvw->priv->movie_par);
- movie_par_d =
- gst_value_get_fraction_denominator (bvw->priv->movie_par);
- } else {
- /* Square pixels */
- movie_par_n = 1;
- movie_par_d = 1;
- }
- }
-
- GST_DEBUG ("movie PAR is %d/%d", movie_par_n, movie_par_d);
-
- if (bvw->priv->video_width == 0 || bvw->priv->video_height == 0) {
- GST_DEBUG ("width and/or height 0, assuming 1/1 ratio");
- num = 1;
- den = 1;
- } else if (!gst_video_calculate_display_ratio (&num, &den,
- bvw->priv->video_width,
- bvw->priv->video_height,
- movie_par_n, movie_par_d, disp_par_n, disp_par_d)) {
- GST_WARNING ("overflow calculating display aspect ratio!");
- num = 1; /* FIXME: what values to use here? */
- den = 1;
- }
-
- GST_DEBUG ("calculated scaling ratio %d/%d for video %dx%d", num,
- den, bvw->priv->video_width, bvw->priv->video_height);
-
- /* now find a width x height that respects this display ratio.
- * prefer those that have one of w/h the same as the incoming video
- * using wd / hd = num / den */
-
- /* start with same height, because of interlaced video */
- /* check hd / den is an integer scale factor, and scale wd with the PAR */
- if (bvw->priv->video_height % den == 0) {
- GST_DEBUG ("keeping video height");
- bvw->priv->video_width_pixels =
- (guint) gst_util_uint64_scale (bvw->priv->video_height, num, den);
- bvw->priv->video_height_pixels = bvw->priv->video_height;
- } else if (bvw->priv->video_width % num == 0) {
- GST_DEBUG ("keeping video width");
- bvw->priv->video_width_pixels = bvw->priv->video_width;
- bvw->priv->video_height_pixels =
- (guint) gst_util_uint64_scale (bvw->priv->video_width, den, num);
- } else {
- GST_DEBUG ("approximating while keeping video height");
- bvw->priv->video_width_pixels =
- (guint) gst_util_uint64_scale (bvw->priv->video_height, num, den);
- bvw->priv->video_height_pixels = bvw->priv->video_height;
- }
- GST_DEBUG ("scaling to %dx%d", bvw->priv->video_width_pixels,
- bvw->priv->video_height_pixels);
-
- *width = bvw->priv->video_width_pixels;
- *height = bvw->priv->video_height_pixels;
-
- /* Free the PAR fraction */
- g_value_unset (disp_par);
- g_free (disp_par);
- } else {
- *width = 0;
- *height = 0;
- }
- }
-}
-
-static void
-bacon_video_widget_realize (GtkWidget * widget)
-{
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
- GdkWindowAttr attributes;
- gint attributes_mask, w, h;
- GdkColor colour;
- GdkWindow *window;
- GdkEventMask event_mask;
-
- event_mask = gtk_widget_get_events (widget)
- | GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK;
- gtk_widget_set_events (widget, event_mask);
-
- GTK_WIDGET_CLASS (parent_class)->realize (widget);
-
- window = gtk_widget_get_window (widget);
-
- /* Creating our video window */
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.x = 0;
- attributes.y = 0;
- attributes.width = widget->allocation.width;
- attributes.height = widget->allocation.height;
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.event_mask = gtk_widget_get_events (widget);
- attributes.event_mask |= GDK_EXPOSURE_MASK |
- GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK;
- attributes_mask = GDK_WA_X | GDK_WA_Y;
-
- bvw->priv->video_window = gdk_window_new (window,
- &attributes, attributes_mask);
- gdk_window_set_user_data (bvw->priv->video_window, widget);
- gdk_window_ensure_native(bvw->priv->video_window);
-
- gdk_color_parse ("black", &colour);
- gdk_colormap_alloc_color (gtk_widget_get_colormap (widget),
- &colour, TRUE, TRUE);
- gdk_window_set_background (window, &colour);
- gtk_widget_set_style (widget,
- gtk_style_attach (gtk_widget_get_style (widget), window));
-
- GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-
- /* Connect to configure event on the top level window */
- g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (widget)),
- "configure-event", G_CALLBACK (bacon_video_widget_configure_event), bvw);
-
- /* get screen size changes */
- g_signal_connect (G_OBJECT (gtk_widget_get_screen (widget)),
- "size-changed", G_CALLBACK (size_changed_cb), bvw);
-
- /* nice hack to show the logo fullsize, while still being resizable */
- get_media_size (BACON_VIDEO_WIDGET (widget), &w, &h);
-
- /*ANDONI
- totem_widget_set_preferred_size (widget, w, h); */
-
- bvw->priv->bacon_resize = bacon_resize_new (widget);
-}
-
-static void
-bacon_video_widget_unrealize (GtkWidget * widget)
-{
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
-
- g_object_unref (bvw->priv->bacon_resize);
- gdk_window_set_user_data (bvw->priv->video_window, NULL);
- gdk_window_destroy (bvw->priv->video_window);
- bvw->priv->video_window = NULL;
-
- GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
-}
-
-static void
-bacon_video_widget_show (GtkWidget * widget)
-{
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
- GdkWindow *window;
-
- window = gtk_widget_get_window (widget);
- if (window)
- gdk_window_show (window);
- if (bvw->priv->video_window)
- gdk_window_show (bvw->priv->video_window);
-
- if (GTK_WIDGET_CLASS (parent_class)->show)
- GTK_WIDGET_CLASS (parent_class)->show (widget);
-}
-
-static void
-bacon_video_widget_hide (GtkWidget * widget)
-{
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
- GdkWindow *window;
-
- window = gtk_widget_get_window (widget);
- if (window)
- gdk_window_hide (window);
- if (bvw->priv->video_window)
- gdk_window_hide (bvw->priv->video_window);
-
- if (GTK_WIDGET_CLASS (parent_class)->hide)
- GTK_WIDGET_CLASS (parent_class)->hide (widget);
-}
-
static gboolean
bacon_video_widget_configure_event (GtkWidget * widget,
GdkEventConfigure * event, BaconVideoWidget * bvw)
@@ -620,10 +362,19 @@ bacon_video_widget_configure_event (GtkWidget * widget,
}
static void
-size_changed_cb (GdkScreen * screen, BaconVideoWidget * bvw)
+bacon_video_widget_realize_event (GtkWidget * widget)
{
- /* FIXME:Used for visualization */
- //setup_vis (bvw);
+ BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
+ GdkWindow *window = gtk_widget_get_window (widget);
+
+ if (!gdk_window_ensure_native (window))
+ g_error ("Couldn't create native window needed for GstXOverlay!");
+
+ /* Connect to configure event on the top level window */
+ g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (widget)),
+ "configure-event", G_CALLBACK (bacon_video_widget_configure_event), bvw);
+
+ bvw->priv->window_handle = gst_get_window_handle (window);
}
static gboolean
@@ -637,31 +388,25 @@ bacon_video_widget_expose_event (GtkWidget * widget, GdkEventExpose * event)
if (event && event->count > 0)
return TRUE;
- g_mutex_lock (bvw->priv->lock);
+ if (event == NULL)
+ return TRUE;
+
xoverlay = bvw->priv->xoverlay;
- if (xoverlay == NULL) {
- bvw_update_interface_implementations (bvw);
- xoverlay = bvw->priv->xoverlay;
- }
- if (xoverlay != NULL)
+ if (xoverlay != NULL) {
gst_object_ref (xoverlay);
-
- g_mutex_unlock (bvw->priv->lock);
-
-
- if (xoverlay != NULL && GST_IS_X_OVERLAY (xoverlay)) {
- gst_set_window_handle(xoverlay, bvw->priv->video_window);
+ gst_set_window_handle (xoverlay, bvw->priv->window_handle);
}
- /* Start with a nice black canvas */
win = gtk_widget_get_window (widget);
- gdk_draw_rectangle (win, gtk_widget_get_style (widget)->black_gc, TRUE, 0,
- 0, widget->allocation.width, widget->allocation.height);
/* if there's only audio and no visualisation, draw the logo as well */
draw_logo = bvw->priv->media_has_audio && !bvw->priv->media_has_video;
if (bvw->priv->logo_mode || draw_logo) {
+ /* Start with a nice black canvas */
+ gdk_draw_rectangle (win, gtk_widget_get_style (widget)->black_gc, TRUE, 0,
+ 0, widget->allocation.width, widget->allocation.height);
+
if (bvw->priv->logo_pixbuf != NULL) {
GdkPixbuf *frame;
GdkPixbuf *drawing;
@@ -720,9 +465,6 @@ bacon_video_widget_expose_event (GtkWidget * widget, GdkEventExpose * event)
g_object_unref (frame);
} else {
- gdk_window_clear_area (win,
- 0, 0, widget->allocation.width, widget->allocation.height);
-
if (width <= 1 || height <= 1) {
if (xoverlay != NULL)
gst_object_unref (xoverlay);
@@ -774,168 +516,6 @@ bacon_video_widget_expose_event (GtkWidget * widget, GdkEventExpose * event)
return TRUE;
}
-static GstNavigation *
-bvw_get_navigation_iface (BaconVideoWidget * bvw)
-{
- GstNavigation *nav = NULL;
- g_mutex_lock (bvw->priv->lock);
- if (bvw->priv->navigation == NULL)
- bvw_update_interface_implementations (bvw);
- if (bvw->priv->navigation)
- nav = gst_object_ref (GST_OBJECT (bvw->priv->navigation));
- g_mutex_unlock (bvw->priv->lock);
-
- return nav;
-}
-
-/* need to use gstnavigation interface for these vmethods, to allow for the sink
- to map screen coordinates to video coordinates in the presence of e.g.
- hardware scaling */
-
-static gboolean
-bacon_video_widget_motion_notify (GtkWidget * widget, GdkEventMotion * event)
-{
- gboolean res = FALSE;
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
-
- g_return_val_if_fail (bvw->priv->play != NULL, FALSE);
-
- if (!bvw->priv->logo_mode) {
- GstNavigation *nav = bvw_get_navigation_iface (bvw);
- if (nav) {
- gst_navigation_send_mouse_event (nav, "mouse-move", 0, event->x,
- event->y);
- gst_object_unref (GST_OBJECT (nav));
- }
- }
-
- if (GTK_WIDGET_CLASS (parent_class)->motion_notify_event)
- res |= GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event);
-
- return res;
-}
-
-static gboolean
-bacon_video_widget_button_press (GtkWidget * widget, GdkEventButton * event)
-{
- gboolean res = FALSE;
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
-
- g_return_val_if_fail (bvw->priv->play != NULL, FALSE);
-
- if (!bvw->priv->logo_mode) {
- GstNavigation *nav = bvw_get_navigation_iface (bvw);
- if (nav) {
- gst_navigation_send_mouse_event (nav,
- "mouse-button-press", event->button, event->x, event->y);
- gst_object_unref (GST_OBJECT (nav));
-
- /* FIXME need to check whether the backend will have handled
- * the button press
- res = TRUE; */
- }
- }
-
- if (GTK_WIDGET_CLASS (parent_class)->button_press_event)
- res |= GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event);
-
- return res;
-}
-
-static gboolean
-bacon_video_widget_button_release (GtkWidget * widget, GdkEventButton * event)
-{
- gboolean res = FALSE;
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
-
- g_return_val_if_fail (bvw->priv->play != NULL, FALSE);
-
- if (!bvw->priv->logo_mode) {
- GstNavigation *nav = bvw_get_navigation_iface (bvw);
- if (nav) {
- gst_navigation_send_mouse_event (nav,
- "mouse-button-release", event->button, event->x, event->y);
- gst_object_unref (GST_OBJECT (nav));
-
- res = TRUE;
- }
- }
-
- if (GTK_WIDGET_CLASS (parent_class)->button_release_event)
- res |=
- GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event);
-
- return res;
-}
-
-static void
-bacon_video_widget_size_request (GtkWidget * widget,
- GtkRequisition * requisition)
-{
- requisition->width = 240;
- requisition->height = 180;
-}
-
-static void
-resize_video_window (BaconVideoWidget * bvw)
-{
- const GtkAllocation *allocation;
- gfloat width, height, ratio, x, y;
- int w, h;
-
- g_return_if_fail (bvw != NULL);
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
-
- allocation = >K_WIDGET (bvw)->allocation;
-
- get_media_size (bvw, &w, &h);
- if (!w || !h) {
- w = allocation->width;
- h = allocation->height;
- }
- width = w;
- height = h;
-
- /* calculate ratio for fitting video into the available space */
- if ((gfloat) allocation->width / width > (gfloat) allocation->height / height) {
- ratio = (gfloat) allocation->height / height;
- } else {
- ratio = (gfloat) allocation->width / width;
- }
-
- /* apply zoom factor */
- ratio = ratio * bvw->priv->zoom;
-
- width *= ratio;
- height *= ratio;
- x = (allocation->width - width) / 2;
- y = (allocation->height - height) / 2;
-
- gdk_window_move_resize (bvw->priv->video_window, x, y, width, height);
- gtk_widget_queue_draw (GTK_WIDGET (bvw));
-}
-
-static void
-bacon_video_widget_size_allocate (GtkWidget * widget,
- GtkAllocation * allocation)
-{
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (widget));
-
- widget->allocation = *allocation;
-
- if (GTK_WIDGET_REALIZED (widget)) {
-
- gdk_window_move_resize (gtk_widget_get_window (widget),
- allocation->x, allocation->y, allocation->width, allocation->height);
-
- resize_video_window (bvw);
- }
-}
-
-
static gboolean
bvw_boolean_handled_accumulator (GSignalInvocationHint * ihint,
GValue * return_accu, const GValue * handler_return, gpointer foobar)
@@ -961,20 +541,9 @@ bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (object_class, sizeof (BaconVideoWidgetPrivate));
-
- /* GtkWidget */
- widget_class->size_request = bacon_video_widget_size_request;
- widget_class->size_allocate = bacon_video_widget_size_allocate;
- widget_class->realize = bacon_video_widget_realize;
- widget_class->unrealize = bacon_video_widget_unrealize;
- widget_class->show = bacon_video_widget_show;
- widget_class->hide = bacon_video_widget_hide;
widget_class->expose_event = bacon_video_widget_expose_event;
- widget_class->motion_notify_event = bacon_video_widget_motion_notify;
- widget_class->button_press_event = bacon_video_widget_button_press;
- widget_class->button_release_event = bacon_video_widget_button_release;
+ g_type_class_add_private (object_class, sizeof (BaconVideoWidgetPrivate));
/* GObject */
object_class->set_property = bacon_video_widget_set_property;
@@ -1132,16 +701,13 @@ bacon_video_widget_init (BaconVideoWidget * bvw)
bvw->priv->missing_plugins = NULL;
bvw->priv->plugin_install_in_progress = FALSE;
-}
-static void
-shrink_toplevel (BaconVideoWidget * bvw)
-{
- GtkWidget *toplevel, *widget;
- widget = GTK_WIDGET (bvw);
- toplevel = gtk_widget_get_toplevel (widget);
- if (toplevel != widget && GTK_IS_WINDOW (toplevel) != FALSE)
- gtk_window_resize (GTK_WINDOW (toplevel), 1, 1);
+ gtk_widget_add_events (GTK_WIDGET (bvw),
+ GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
+
+ g_signal_connect (GTK_WIDGET (bvw), "realize",
+ G_CALLBACK (bacon_video_widget_realize_event), NULL);
}
static gboolean bvw_query_timeout (BaconVideoWidget * bvw);
@@ -1165,7 +731,6 @@ static void
bvw_handle_application_message (BaconVideoWidget * bvw, GstMessage * msg)
{
const gchar *msg_name;
- GdkWindow *window;
msg_name = gst_structure_get_name (msg->structure);
g_return_if_fail (msg_name != NULL);
@@ -1174,33 +739,6 @@ bvw_handle_application_message (BaconVideoWidget * bvw, GstMessage * msg)
if (strcmp (msg_name, "stream-changed") == 0) {
bvw_update_stream_info (bvw);
- } else if (strcmp (msg_name, "video-size") == 0) {
- /* if we're not interactive, we want to announce metadata
- * only later when we can be sure we got it all */
- if (bvw->priv->use_type == BVW_USE_TYPE_VIDEO ||
- bvw->priv->use_type == BVW_USE_TYPE_AUDIO) {
- g_signal_emit (bvw, bvw_signals[SIGNAL_GOT_METADATA], 0, NULL);
- }
-
- if (bvw->priv->auto_resize
- && !bvw->priv->fullscreen_mode && !bvw->priv->window_resized) {
- bacon_video_widget_set_scale_ratio (bvw, 1);
- } else {
- bacon_video_widget_size_allocate (GTK_WIDGET (bvw),
- >K_WIDGET (bvw)->allocation);
-
- /* Uhm, so this ugly hack here makes media loading work for
- * weird laptops with NVIDIA graphics cards... Dunno what the
- * bug is really, but hey, it works. :). */
- window = gtk_widget_get_window (GTK_WIDGET (bvw));
- if (window) {
- gdk_window_hide (window);
- gdk_window_show (window);
-
- bacon_video_widget_expose_event (GTK_WIDGET (bvw), NULL);
- }
- }
- bvw->priv->window_resized = TRUE;
} else {
g_message ("Unhandled application message %s", msg_name);
}
@@ -1836,9 +1374,6 @@ parse_stream_info (BaconVideoWidget * bvw)
gint i;
bvw->priv->media_has_video = TRUE;
- if (bvw->priv->video_window)
- gdk_window_show (bvw->priv->video_window);
-
for (i = 0; i < n_video && videopad == NULL; i++)
g_signal_emit_by_name (bvw->priv->play, "get-video-pad", i, &videopad);
}
@@ -1846,16 +1381,16 @@ parse_stream_info (BaconVideoWidget * bvw)
bvw->priv->media_has_audio = FALSE;
if (n_audio > 0) {
bvw->priv->media_has_audio = TRUE;
- if (!bvw->priv->media_has_video && bvw->priv->video_window) {
- gint flags;
+ if (!bvw->priv->media_has_video) {
+ /*gint flags;*/
- g_object_get (bvw->priv->play, "flags", &flags, NULL);
+ /*g_object_get (bvw->priv->play, "flags", &flags, NULL);*/
- gdk_window_hide (bvw->priv->video_window);
- GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
- flags &= ~GST_PLAY_FLAGS_VIS;
+ /*gdk_window_hide (bvw->priv->video_window);*/
+ /*GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);*/
+ /*flags &= ~GST_PLAY_FLAGS_VIS;*/
- g_object_set (bvw->priv->play, "flags", flags, NULL);
+ /*g_object_set (bvw->priv->play, "flags", flags, NULL);*/
}
}
@@ -3267,7 +2802,7 @@ bacon_video_widget_seek_to_previous_frame (BaconVideoWidget * bvw,
g_return_val_if_fail (GST_IS_ELEMENT (bvw->priv->play), FALSE);
- //Round framerate to the nearest integer
+ //Round framerate to the nearest integer
fps = (bvw->priv->video_fps_n + bvw->priv->video_fps_d / 2) /
bvw->priv->video_fps_d;
pos = bacon_video_widget_get_accurate_current_time (bvw);
@@ -3612,14 +3147,12 @@ bacon_video_widget_set_logo_mode (BaconVideoWidget * bvw, gboolean logo_mode)
if (priv->logo_mode != logo_mode) {
priv->logo_mode = logo_mode;
- if (priv->video_window) {
- if (logo_mode) {
- gdk_window_hide (priv->video_window);
- GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
- } else {
- gdk_window_show (priv->video_window);
- GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
- }
+ if (logo_mode) {
+ /*gdk_window_hide (priv->video_window);*/
+ GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
+ } else {
+ /*gdk_window_show (priv->video_window);*/
+ GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
}
g_object_notify (G_OBJECT (bvw), "logo_mode");
@@ -3971,225 +3504,6 @@ bacon_video_widget_get_aspect_ratio (BaconVideoWidget * bvw)
}
/**
- * bacon_video_widget_set_scale_ratio:
- * @bvw: a #BaconVideoWidget
- * @ratio: the new scale ratio
- *
- * Sets the ratio by which the widget will scale videos when they are
- * displayed. If @ratio is set to %0, the highest ratio possible will
- * be chosen.
- **/
-void
-bacon_video_widget_set_scale_ratio (BaconVideoWidget * bvw, gfloat ratio)
-{
- gint w, h;
-
- g_return_if_fail (bvw != NULL);
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
- g_return_if_fail (GST_IS_ELEMENT (bvw->priv->play));
-
- GST_DEBUG ("ratio = %.2f", ratio);
-
- if (bvw->priv->video_window == NULL)
- return;
-
- get_media_size (bvw, &w, &h);
-
-
- if (ratio == 0.0) {
- if (totem_ratio_fits_screen (bvw->priv->video_window, w, h, 2.0))
- ratio = 2.0;
- else if (totem_ratio_fits_screen (bvw->priv->video_window, w, h, 1.0))
- ratio = 1.0;
- else if (totem_ratio_fits_screen (bvw->priv->video_window, w, h, 0.5))
- ratio = 0.5;
- else
- return;
- } else {
- if (!totem_ratio_fits_screen (bvw->priv->video_window, w, h, ratio)) {
- GST_DEBUG ("movie doesn't fit on screen @ %.1fx (%dx%d)", w, h, ratio);
- return;
- }
- }
- w = (gfloat) w *ratio;
- h = (gfloat) h *ratio;
-
- shrink_toplevel (bvw);
-
- GST_DEBUG ("setting preferred size %dx%d", w, h);
- totem_widget_set_preferred_size (GTK_WIDGET (bvw), w, h);
-}
-
-/**
- * bacon_video_widget_set_zoom:
- * @bvw: a #BaconVideoWidget
- * @zoom: a percentage zoom factor
- *
- * Sets the zoom factor applied to the video when it is displayed,
- * as an integeric percentage between %0 and %1
- * (e.g. set @zoom to %1 to not zoom at all).
- **/
-void
-bacon_video_widget_set_zoom (BaconVideoWidget * bvw, double zoom)
-{
- g_return_if_fail (bvw != NULL);
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
-
- bvw->priv->zoom = zoom;
- if (bvw->priv->video_window != NULL)
- resize_video_window (bvw);
-}
-
-/**
- * bacon_video_widget_get_zoom:
- * @bvw: a #BaconVideoWidget
- *
- * Returns the zoom factor applied to videos displayed by the widget,
- * as an integeric percentage between %0 and %1
- * (e.g. %1 means no zooming at all).
- *
- * Return value: the zoom factor
- **/
-double
-bacon_video_widget_get_zoom (BaconVideoWidget * bvw)
-{
- g_return_val_if_fail (bvw != NULL, 1.0);
- g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), 1.0);
-
- return bvw->priv->zoom;
-}
-
-
-/* Search for the color balance channel corresponding to type and return it. */
-static GstColorBalanceChannel *
-bvw_get_color_balance_channel (GstColorBalance * color_balance,
- BvwVideoProperty type)
-{
- const GList *channels;
-
- channels = gst_color_balance_list_channels (color_balance);
-
- for (; channels != NULL; channels = channels->next) {
- GstColorBalanceChannel *c = channels->data;
-
- if (type == BVW_VIDEO_BRIGHTNESS && g_strrstr (c->label, "BRIGHTNESS"))
- return g_object_ref (c);
- else if (type == BVW_VIDEO_CONTRAST && g_strrstr (c->label, "CONTRAST"))
- return g_object_ref (c);
- else if (type == BVW_VIDEO_SATURATION && g_strrstr (c->label, "SATURATION"))
- return g_object_ref (c);
- else if (type == BVW_VIDEO_HUE && g_strrstr (c->label, "HUE"))
- return g_object_ref (c);
- }
-
- return NULL;
-}
-
-/**
- * bacon_video_widget_get_video_property:
- * @bvw: a #BaconVideoWidget
- * @type: the type of property
- *
- * Returns the given property of the video, such as its brightness or saturation.
- *
- * It is returned as a percentage in the full range of integer values; from %0
- * to %G_MAXINT, where %G_MAXINT/2 is the default.
- *
- * Return value: the property's value, in the range %0 to %G_MAXINT
- **/
-int
-bacon_video_widget_get_video_property (BaconVideoWidget * bvw,
- BvwVideoProperty type)
-{
- int ret;
-
- g_return_val_if_fail (bvw != NULL, 65535 / 2);
- g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), 65535 / 2);
-
- g_mutex_lock (bvw->priv->lock);
-
- ret = 0;
-
- if (bvw->priv->balance && GST_IS_COLOR_BALANCE (bvw->priv->balance)) {
- GstColorBalanceChannel *found_channel = NULL;
-
- found_channel = bvw_get_color_balance_channel (bvw->priv->balance, type);
-
- if (found_channel && GST_IS_COLOR_BALANCE_CHANNEL (found_channel)) {
- gint cur;
-
- cur = gst_color_balance_get_value (bvw->priv->balance, found_channel);
-
- GST_DEBUG ("channel %s: cur=%d, min=%d, max=%d",
- found_channel->label, cur, found_channel->min_value,
- found_channel->max_value);
-
- ret = floor (0.5 +
- ((double) cur - found_channel->min_value) * 65535 /
- ((double) found_channel->max_value - found_channel->min_value));
-
- GST_DEBUG ("channel %s: returning value %d", found_channel->label, ret);
- g_object_unref (found_channel);
- goto done;
- } else {
- ret = -1;
- }
- }
-
-done:
-
- g_mutex_unlock (bvw->priv->lock);
- return ret;
-}
-
-/**
- * bacon_video_widget_set_video_property:
- * @bvw: a #BaconVideoWidget
- * @type: the type of property
- * @value: the property's value, in the range %0 to %G_MAXINT
- *
- * Sets the given property of the video, such as its brightness or saturation.
- *
- * It should be given as a percentage in the full range of integer values; from %0
- * to %G_MAXINT, where %G_MAXINT/2 is the default.
- **/
-void
-bacon_video_widget_set_video_property (BaconVideoWidget * bvw,
- BvwVideoProperty type, int value)
-{
- g_return_if_fail (bvw != NULL);
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
-
- GST_DEBUG ("set video property type %d to value %d", type, value);
-
- if (!(value <= 65535 && value >= 0))
- return;
-
- if (bvw->priv->balance && GST_IS_COLOR_BALANCE (bvw->priv->balance)) {
- GstColorBalanceChannel *found_channel = NULL;
-
- found_channel = bvw_get_color_balance_channel (bvw->priv->balance, type);
-
- if (found_channel && GST_IS_COLOR_BALANCE_CHANNEL (found_channel)) {
- int i_value;
-
- i_value = floor (0.5 + value * ((double) found_channel->max_value -
- found_channel->min_value) / 65535 + found_channel->min_value);
-
- GST_DEBUG ("channel %s: set to %d/65535", found_channel->label, value);
-
- gst_color_balance_set_value (bvw->priv->balance, found_channel, i_value);
-
- GST_DEBUG ("channel %s: val=%d, min=%d, max=%d",
- found_channel->label, i_value, found_channel->min_value,
- found_channel->max_value);
-
- g_object_unref (found_channel);
- }
- }
-}
-
-/**
* bacon_video_widget_get_position:
* @bvw: a #BaconVideoWidget
*
@@ -5125,7 +4439,7 @@ bacon_video_widget_get_current_frame (BaconVideoWidget * bvw)
/* */
/* =========================================== */
-G_DEFINE_TYPE (BaconVideoWidget, bacon_video_widget, GTK_TYPE_EVENT_BOX)
+G_DEFINE_TYPE (BaconVideoWidget, bacon_video_widget, GTK_TYPE_DRAWING_AREA)
/* applications must use exactly one of bacon_video_widget_get_option_group()
* OR bacon_video_widget_init_backend(), but not both */
/**
@@ -5172,151 +4486,6 @@ bacon_video_widget_error_quark (void)
return q;
}
-/* fold function to pick the best colorspace element */
-static gboolean
-find_colorbalance_element (GstElement * element, GValue * ret, GstElement ** cb)
-{
- GstColorBalanceClass *cb_class;
-
- GST_DEBUG ("Checking element %s ...", GST_OBJECT_NAME (element));
-
- if (!GST_IS_COLOR_BALANCE (element))
- return TRUE;
-
- GST_DEBUG ("Element %s is a color balance", GST_OBJECT_NAME (element));
-
- cb_class = GST_COLOR_BALANCE_GET_CLASS (element);
- if (GST_COLOR_BALANCE_TYPE (cb_class) == GST_COLOR_BALANCE_HARDWARE) {
- gst_object_replace ((GstObject **) cb, (GstObject *) element);
- /* shortcuts the fold */
- return FALSE;
- } else if (*cb == NULL) {
- gst_object_replace ((GstObject **) cb, (GstObject *) element);
- return TRUE;
- } else {
- return TRUE;
- }
-}
-
-static gboolean
-bvw_update_interfaces_delayed (BaconVideoWidget * bvw)
-{
- GST_DEBUG ("Delayed updating interface implementations");
- g_mutex_lock (bvw->priv->lock);
- bvw_update_interface_implementations (bvw);
- bvw->priv->interface_update_id = 0;
- g_mutex_unlock (bvw->priv->lock);
-
- return FALSE;
-}
-
-/* Must be called with bvw->priv->lock held */
-static void
-bvw_update_interface_implementations (BaconVideoWidget * bvw)
-{
- GstColorBalance *old_balance = bvw->priv->balance;
- GstXOverlay *old_xoverlay = bvw->priv->xoverlay;
- GstElement *video_sink = NULL;
- GstElement *element = NULL;
- GstIterator *iter;
-
- if (g_thread_self () != gui_thread) {
- if (bvw->priv->balance)
- gst_object_unref (bvw->priv->balance);
- bvw->priv->balance = NULL;
- if (bvw->priv->xoverlay)
- gst_object_unref (bvw->priv->xoverlay);
- bvw->priv->xoverlay = NULL;
- if (bvw->priv->navigation)
- gst_object_unref (bvw->priv->navigation);
- bvw->priv->navigation = NULL;
-
- if (bvw->priv->interface_update_id)
- g_source_remove (bvw->priv->interface_update_id);
- bvw->priv->interface_update_id =
- g_idle_add ((GSourceFunc) bvw_update_interfaces_delayed, bvw);
- return;
- }
-
- g_object_get (bvw->priv->play, "video-sink", &video_sink, NULL);
- g_assert (video_sink != NULL);
-
- /* We try to get an element supporting XOverlay interface */
- if (GST_IS_BIN (video_sink)) {
- GST_DEBUG ("Retrieving xoverlay from bin ...");
- element = gst_bin_get_by_interface (GST_BIN (video_sink),
- GST_TYPE_X_OVERLAY);
- } else {
- element = gst_object_ref (video_sink);
- }
-
- if (GST_IS_X_OVERLAY (element)) {
- GST_DEBUG ("Found xoverlay: %s", GST_OBJECT_NAME (element));
- bvw->priv->xoverlay = GST_X_OVERLAY (element);
- } else {
- GST_DEBUG ("No xoverlay found");
- if (element)
- gst_object_unref (element);
- bvw->priv->xoverlay = NULL;
- }
-
- /* Try to find the navigation interface */
- if (GST_IS_BIN (video_sink)) {
- GST_DEBUG ("Retrieving navigation from bin ...");
- element = gst_bin_get_by_interface (GST_BIN (video_sink),
- GST_TYPE_NAVIGATION);
- } else {
- element = gst_object_ref (video_sink);
- }
-
- if (GST_IS_NAVIGATION (element)) {
- GST_DEBUG ("Found navigation: %s", GST_OBJECT_NAME (element));
- bvw->priv->navigation = GST_NAVIGATION (element);
- } else {
- GST_DEBUG ("No navigation found");
- if (element)
- gst_object_unref (element);
- bvw->priv->navigation = NULL;
- }
-
- /* Find best color balance element (using custom iterator so
- * we can prefer hardware implementations to software ones) */
-
- /* FIXME: this doesn't work reliably yet, most of the time
- * the fold function doesn't even get called, while sometimes
- * it does ... */
- iter = gst_bin_iterate_all_by_interface (GST_BIN (bvw->priv->play),
- GST_TYPE_COLOR_BALANCE);
- /* naively assume no resync */
- element = NULL;
- gst_iterator_fold (iter, (GstIteratorFoldFunction)
- find_colorbalance_element, NULL, &element);
- gst_iterator_free (iter);
-
- if (element) {
- bvw->priv->balance = GST_COLOR_BALANCE (element);
- GST_DEBUG ("Best colorbalance found: %s",
- GST_OBJECT_NAME (bvw->priv->balance));
- } else if (GST_IS_COLOR_BALANCE (bvw->priv->xoverlay)) {
- bvw->priv->balance = GST_COLOR_BALANCE (bvw->priv->xoverlay);
- gst_object_ref (bvw->priv->balance);
- GST_DEBUG ("Colorbalance backup found: %s",
- GST_OBJECT_NAME (bvw->priv->balance));
- } else {
- GST_DEBUG ("No colorbalance found");
- bvw->priv->balance = NULL;
- }
-
- if (old_xoverlay)
- gst_object_unref (GST_OBJECT (old_xoverlay));
-
- if (old_balance)
- gst_object_unref (GST_OBJECT (old_balance));
-
- gst_object_unref (video_sink);
-}
-
-
static void
bvw_element_msg_sync (GstBus * bus, GstMessage * msg, gpointer data)
{
@@ -5333,10 +4502,6 @@ bvw_element_msg_sync (GstBus * bus, GstMessage * msg, gpointer data)
if (gst_structure_has_name (msg->structure, "prepare-xwindow-id")) {
GST_INFO ("Handling sync prepare-xwindow-id message");
- g_mutex_lock (bvw->priv->lock);
- bvw_update_interface_implementations (bvw);
- g_mutex_unlock (bvw->priv->lock);
-
if (bvw->priv->xoverlay == NULL) {
GstObject *sender = GST_MESSAGE_SRC (msg);
if (sender && GST_IS_X_OVERLAY (sender))
@@ -5344,25 +4509,14 @@ bvw_element_msg_sync (GstBus * bus, GstMessage * msg, gpointer data)
}
g_return_if_fail (bvw->priv->xoverlay != NULL);
- g_return_if_fail (bvw->priv->video_window != NULL);
-
- gst_set_window_handle(bvw->priv->xoverlay, bvw->priv->video_window);
+ g_return_if_fail (bvw->priv->window_handle != 0);
+ g_object_set (GST_ELEMENT (bvw->priv->xoverlay), "force-aspect-ratio", TRUE, NULL);
+ gst_set_window_handle(bvw->priv->xoverlay, bvw->priv->window_handle);
+ gtk_widget_queue_draw (GTK_WIDGET(bvw));
}
}
-static void
-got_new_video_sink_bin_element (GstBin * video_sink, GstElement * element,
- gpointer data)
-{
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (data);
-
- g_mutex_lock (bvw->priv->lock);
- bvw_update_interface_implementations (bvw);
- g_mutex_unlock (bvw->priv->lock);
-
-}
-
/**
* bacon_video_widget_new:
* @width: initial or expected video width, in pixels, or %-1
@@ -5399,6 +4553,9 @@ bacon_video_widget_new (int width, int height, BvwUseType type, GError ** err)
bvw = g_object_new (bacon_video_widget_get_type (), NULL);
+ /* show the gui. */
+ gtk_widget_show_all (GTK_WIDGET(bvw));
+
bvw->priv->use_type = type;
GST_INFO ("use_type = %d", type);
@@ -5415,7 +4572,6 @@ bacon_video_widget_new (int width, int height, BvwUseType type, GError ** err)
}
bvw->priv->bus = gst_element_get_bus (bvw->priv->play);
-
gst_bus_add_signal_watch (bvw->priv->bus);
bvw->priv->sig_bus_async =
@@ -5602,7 +4758,7 @@ bacon_video_widget_new (int width, int height, BvwUseType type, GError ** err)
if (type == BVW_USE_TYPE_VIDEO) {
GstStateChangeReturn ret;
- /* wait for video sink to finish changing to READY state,
+ /* wait for video sink to finish changing to READY state,
* otherwise we won't be able to detect the colorbalance interface */
ret = gst_element_get_state (video_sink, NULL, NULL, 5 * GST_SECOND);
@@ -5614,7 +4770,6 @@ bacon_video_widget_new (int width, int height, BvwUseType type, GError ** err)
"Please select another video output in the Multimedia Systems Selector."));
return NULL;
}
- bvw_update_interface_implementations (bvw);
}
@@ -5625,16 +4780,6 @@ bacon_video_widget_new (int width, int height, BvwUseType type, GError ** err)
g_signal_connect (bvw->priv->bus, "sync-message::element",
G_CALLBACK (bvw_element_msg_sync), bvw);
- if (GST_IS_BIN (video_sink)) {
- /* video sink bins like gsettingsvideosink might remove their children and
- * create new ones when set to NULL state, and they are currently set
- * to NULL state whenever playbin re-creates its internal video bin
- * (it sets all elements to NULL state before gst_bin_remove()ing them) */
- g_signal_connect (video_sink, "element-added",
- G_CALLBACK (got_new_video_sink_bin_element), bvw);
- }
-
-
return GTK_WIDGET (bvw);
/* errors */
diff --git a/libcesarplayer/bacon-video-widget.h b/libcesarplayer/bacon-video-widget.h
index d2e5746..8dbe388 100644
--- a/libcesarplayer/bacon-video-widget.h
+++ b/libcesarplayer/bacon-video-widget.h
@@ -52,13 +52,13 @@ typedef struct BaconVideoWidgetPrivate BaconVideoWidgetPrivate;
typedef struct
{
- GtkEventBox parent;
+ GtkDrawingArea parent;
BaconVideoWidgetPrivate *priv;
} BaconVideoWidget;
typedef struct
{
- GtkEventBoxClass parent_class;
+ GtkDrawingAreaClass parent_class;
void (*error) (BaconVideoWidget * bvw, const char *message);
void (*eos) (BaconVideoWidget * bvw);
diff --git a/libcesarplayer/video-utils.c b/libcesarplayer/video-utils.c
index a1cd54f..6dab75d 100644
--- a/libcesarplayer/video-utils.c
+++ b/libcesarplayer/video-utils.c
@@ -262,24 +262,27 @@ totem_ratio_fits_screen (GdkWindow * video_window, int video_width,
return TRUE;
}
-void
-gst_set_window_handle(GstXOverlay *xoverlay, GdkWindow *window)
+guintptr
+gst_get_window_handle(GdkWindow *window)
{
guintptr window_handle;
/* Retrieve window handler from GDK */
#if defined (GDK_WINDOWING_WIN32)
window_handle = (guintptr)GDK_WINDOW_HWND (window);
- gst_x_overlay_set_window_handle (xoverlay, window_handle);
#elif defined (GDK_WINDOWING_QUARTZ)
window_handle = gdk_quartz_window_get_nsview (window);
- gst_x_overlay_set_window_handle (xoverlay, window_handle);
#elif defined (GDK_WINDOWING_X11)
- gdk_threads_enter ();
window_handle = GDK_WINDOW_XID (window);
- gst_x_overlay_set_window_handle (xoverlay, window_handle);
- gdk_threads_leave ();
#endif
+
+ return window_handle;
+}
+
+void
+gst_set_window_handle(GstXOverlay *xoverlay, guintptr window_handle)
+{
+ gst_x_overlay_set_window_handle (xoverlay, window_handle);
}
void
diff --git a/libcesarplayer/video-utils.h b/libcesarplayer/video-utils.h
index ee87196..4fd9704 100644
--- a/libcesarplayer/video-utils.h
+++ b/libcesarplayer/video-utils.h
@@ -63,7 +63,8 @@ gboolean totem_ratio_fits_screen (GdkWindow * window, int video_width,
int video_height, gfloat ratio);
void init_backend (int argc, char **argv);
-void gst_set_window_handle (GstXOverlay *overlay, GdkWindow *window);
+guintptr gst_get_window_handle (GdkWindow *window);
+void gst_set_window_handle (GstXOverlay *overlay, guintptr window_handle);
void init_debug();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]