[longomatch] Use separete drawing areas for video and logo
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch] Use separete drawing areas for video and logo
- Date: Sat, 10 Nov 2012 20:08:44 +0000 (UTC)
commit ed00b3e4f78bf7370ffc1f3a677432ab92af4160
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Sat Nov 10 21:08:11 2012 +0100
Use separete drawing areas for video and logo
libcesarplayer/bacon-video-widget-gst-0.10.c | 262 +++++++++++++++-----------
libcesarplayer/bacon-video-widget.h | 4 +-
2 files changed, 155 insertions(+), 111 deletions(-)
---
diff --git a/libcesarplayer/bacon-video-widget-gst-0.10.c b/libcesarplayer/bacon-video-widget-gst-0.10.c
index a58e99e..67fa4ab 100644
--- a/libcesarplayer/bacon-video-widget-gst-0.10.c
+++ b/libcesarplayer/bacon-video-widget-gst-0.10.c
@@ -168,6 +168,8 @@ struct BaconVideoWidgetPrivate
gboolean got_redirect;
+ GtkWidget *video_da;
+ GtkWidget *logo_da;
guintptr window_handle;
GdkCursor *cursor;
@@ -360,9 +362,8 @@ bacon_video_widget_configure_event (GtkWidget * widget,
}
static void
-bacon_video_widget_realize_event (GtkWidget * widget)
+bacon_video_widget_realize_event (GtkWidget * widget, BaconVideoWidget *bvw)
{
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
GdkWindow *window = gtk_widget_get_window (widget);
if (!gdk_window_ensure_native (window))
@@ -376,11 +377,10 @@ bacon_video_widget_realize_event (GtkWidget * widget)
}
static gboolean
-bacon_video_widget_expose_event (GtkWidget * widget, GdkEventExpose * event)
+bacon_video_widget_video_expose_event (GtkWidget * widget, GdkEventExpose * event,
+ BaconVideoWidget *bvw)
{
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
GstXOverlay *xoverlay;
- gboolean draw_logo;
GdkWindow *win;
if (event && event->count > 0)
@@ -389,125 +389,155 @@ bacon_video_widget_expose_event (GtkWidget * widget, GdkEventExpose * event)
if (event == NULL)
return TRUE;
+ g_mutex_lock (bvw->priv->lock);
+
xoverlay = bvw->priv->xoverlay;
if (xoverlay != NULL) {
gst_object_ref (xoverlay);
gst_set_window_handle (xoverlay, bvw->priv->window_handle);
}
- win = gtk_widget_get_window (widget);
+ if (bvw->priv->logo_mode)
+ goto exit;
+
+ /* no logo, pass the expose to gst */
+ if (xoverlay != NULL && GST_IS_X_OVERLAY (xoverlay)){
+ g_object_set (GST_ELEMENT (bvw->priv->xoverlay), "force-aspect-ratio", TRUE, NULL);
+ gst_x_overlay_expose (xoverlay);
+ }
+ else {
+ /* No xoverlay to expose yet */
+ win = gtk_widget_get_window (bvw->priv->video_da);
+ gdk_window_clear_area (win,
+ 0, 0, widget->allocation.width, widget->allocation.height);
+ }
+
+exit:
+
+ if (xoverlay != NULL)
+ gst_object_unref (xoverlay);
+
+ g_mutex_unlock (bvw->priv->lock);
+ return TRUE;
+}
+
+static gboolean
+bacon_video_widget_logo_expose_event (GtkWidget * widget, GdkEventExpose * event,
+ BaconVideoWidget *bvw)
+{
+ gboolean draw_logo;
+ GdkWindow *win;
+
+ if (event && event->count > 0)
+ return TRUE;
+
+ if (event == NULL)
+ return TRUE;
+
+ g_mutex_lock (bvw->priv->lock);
/* 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_mode && !draw_logo)
+ goto exit;
- if (bvw->priv->logo_pixbuf != NULL) {
- GdkPixbuf *frame;
- GdkPixbuf *drawing;
- guchar *pixels;
- int rowstride;
- gint width, height, alloc_width, alloc_height, logo_x, logo_y;
- gfloat ratio;
+ win = gtk_widget_get_window (bvw->priv->logo_da);
- /* Checking if allocated space is smaller than our 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;
+ guchar *pixels;
+ int rowstride;
+ gint width, height, alloc_width, alloc_height, logo_x, logo_y;
+ gfloat ratio;
- width = gdk_pixbuf_get_width (bvw->priv->logo_pixbuf);
- height = gdk_pixbuf_get_height (bvw->priv->logo_pixbuf);
- alloc_width = widget->allocation.width;
- alloc_height = widget->allocation.height;
+ /* Checking if allocated space is smaller than our logo */
- if ((gfloat) alloc_width / width > (gfloat) alloc_height / height) {
- ratio = (gfloat) alloc_height / height;
- } else {
- ratio = (gfloat) alloc_width / width;
- }
- width *= ratio;
- height *= ratio;
+ width = gdk_pixbuf_get_width (bvw->priv->logo_pixbuf);
+ height = gdk_pixbuf_get_height (bvw->priv->logo_pixbuf);
+ alloc_width = widget->allocation.width;
+ alloc_height = widget->allocation.height;
- logo_x = (alloc_width / 2) - (width / 2);
- logo_y = (alloc_height / 2) - (height / 2);
+ if ((gfloat) alloc_width / width > (gfloat) alloc_height / height) {
+ ratio = (gfloat) alloc_height / height;
+ } else {
+ ratio = (gfloat) alloc_width / width;
+ }
+ width *= ratio;
+ height *= ratio;
- /* Drawing our frame */
+ logo_x = (alloc_width / 2) - (width / 2);
+ logo_y = (alloc_height / 2) - (height / 2);
- if (bvw->priv->expand_logo && !bvw->priv->drawing_mode) {
- /* Scaling to available space */
- frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- FALSE, 8, widget->allocation.width, widget->allocation.height);
+ /* Drawing our frame */
- gdk_pixbuf_composite (bvw->priv->logo_pixbuf,
- frame,
- 0, 0,
- alloc_width, alloc_height,
- logo_x, logo_y, ratio, ratio, GDK_INTERP_BILINEAR, 255);
+ if (bvw->priv->expand_logo && !bvw->priv->drawing_mode) {
+ /* Scaling to available space */
- rowstride = gdk_pixbuf_get_rowstride (frame);
+ frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ FALSE, 8, widget->allocation.width, widget->allocation.height);
- pixels = gdk_pixbuf_get_pixels (frame) +
- rowstride * event->area.y + event->area.x * 3;
+ gdk_pixbuf_composite (bvw->priv->logo_pixbuf,
+ frame,
+ 0, 0,
+ alloc_width, alloc_height,
+ logo_x, logo_y, ratio, ratio, GDK_INTERP_BILINEAR, 255);
- gdk_draw_rgb_image_dithalign (widget->window,
- widget->style->black_gc,
- event->area.x, event->area.y,
- event->area.width,
- event->area.height,
- GDK_RGB_DITHER_NORMAL, pixels,
- rowstride, event->area.x, event->area.y);
+ rowstride = gdk_pixbuf_get_rowstride (frame);
- g_object_unref (frame);
- } else {
- if (width <= 1 || height <= 1) {
- if (xoverlay != NULL)
- gst_object_unref (xoverlay);
- gdk_window_end_paint (win);
- return TRUE;
- }
+ pixels = gdk_pixbuf_get_pixels (frame) +
+ rowstride * event->area.y + event->area.x * 3;
- frame = gdk_pixbuf_scale_simple (bvw->priv->logo_pixbuf,
- width, height, GDK_INTERP_BILINEAR);
- gdk_draw_pixbuf (win, gtk_widget_get_style (widget)->fg_gc[0],
- frame, 0, 0, logo_x, logo_y, width, height,
- GDK_RGB_DITHER_NONE, 0, 0);
-
- if (bvw->priv->drawing_mode && bvw->priv->drawing_pixbuf != NULL) {
- drawing =
- gdk_pixbuf_scale_simple (bvw->priv->drawing_pixbuf, width,
- height, GDK_INTERP_BILINEAR);
- gdk_draw_pixbuf (win,
- gtk_widget_get_style (widget)->fg_gc[0],
- drawing, 0, 0, logo_x, logo_y, width,
- height, GDK_RGB_DITHER_NONE, 0, 0);
- g_object_unref (drawing);
- }
+ gdk_draw_rgb_image_dithalign (widget->window,
+ widget->style->black_gc,
+ event->area.x, event->area.y,
+ event->area.width,
+ event->area.height,
+ GDK_RGB_DITHER_NORMAL, pixels,
+ rowstride, event->area.x, event->area.y);
- g_object_unref (frame);
+ g_object_unref (frame);
+ } else {
+ if (width <= 1 || height <= 1) {
+ gdk_window_end_paint (win);
+ goto exit;
}
- } else if (win) {
- /* No pixbuf, just draw a black background then */
- gdk_window_clear_area (win,
- 0, 0, widget->allocation.width, widget->allocation.height);
- }
- } else {
- /* no logo, pass the expose to gst */
- if (xoverlay != NULL && GST_IS_X_OVERLAY (xoverlay)){
- gst_x_overlay_expose (xoverlay);
- }
- else {
- /* No xoverlay to expose yet */
- gdk_window_clear_area (win,
- 0, 0, widget->allocation.width, widget->allocation.height);
+
+ frame = gdk_pixbuf_scale_simple (bvw->priv->logo_pixbuf,
+ width, height, GDK_INTERP_BILINEAR);
+ gdk_draw_pixbuf (win, gtk_widget_get_style (widget)->fg_gc[0],
+ frame, 0, 0, logo_x, logo_y, width, height,
+ GDK_RGB_DITHER_NONE, 0, 0);
+
+ if (bvw->priv->drawing_mode && bvw->priv->drawing_pixbuf != NULL) {
+ drawing =
+ gdk_pixbuf_scale_simple (bvw->priv->drawing_pixbuf, width,
+ height, GDK_INTERP_BILINEAR);
+ gdk_draw_pixbuf (win,
+ gtk_widget_get_style (widget)->fg_gc[0],
+ drawing, 0, 0, logo_x, logo_y, width,
+ height, GDK_RGB_DITHER_NONE, 0, 0);
+ g_object_unref (drawing);
+ }
+
+ g_object_unref (frame);
}
+ } else if (win) {
+ /* No pixbuf, just draw a black background then */
+ gdk_window_clear_area (win,
+ 0, 0, widget->allocation.width, widget->allocation.height);
}
- if (xoverlay != NULL)
- gst_object_unref (xoverlay);
+exit:
+ g_mutex_unlock (bvw->priv->lock);
return TRUE;
}
@@ -529,15 +559,11 @@ static void
bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
{
GObjectClass *object_class;
- GtkWidgetClass *widget_class;
object_class = (GObjectClass *) klass;
- widget_class = (GtkWidgetClass *) klass;
parent_class = g_type_class_peek_parent (klass);
- widget_class->expose_event = bacon_video_widget_expose_event;
-
g_type_class_add_private (object_class, sizeof (BaconVideoWidgetPrivate));
/* GObject */
@@ -681,7 +707,6 @@ bacon_video_widget_init (BaconVideoWidget * bvw)
BaconVideoWidgetPrivate *priv;
GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_CAN_FOCUS);
- GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
bvw->priv = priv =
G_TYPE_INSTANCE_GET_PRIVATE (bvw, BACON_TYPE_VIDEO_WIDGET,
@@ -697,12 +722,27 @@ bacon_video_widget_init (BaconVideoWidget * bvw)
bvw->priv->missing_plugins = NULL;
bvw->priv->plugin_install_in_progress = FALSE;
- gtk_widget_add_events (GTK_WIDGET (bvw),
+ bvw->priv->video_da = gtk_drawing_area_new ();
+ bvw->priv->logo_da = gtk_drawing_area_new ();
+
+ GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw->priv->video_da), GTK_DOUBLE_BUFFERED);
+
+ gtk_box_pack_start (GTK_BOX (bvw), bvw->priv->video_da, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (bvw), bvw->priv->logo_da, TRUE, TRUE, 0);
+
+ gtk_widget_add_events (GTK_WIDGET (bvw->priv->video_da),
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);
+ g_signal_connect (GTK_WIDGET (bvw->priv->video_da), "realize",
+ G_CALLBACK (bacon_video_widget_realize_event), bvw);
+
+ g_signal_connect (GTK_WIDGET (bvw->priv->logo_da), "expose-event",
+ G_CALLBACK (bacon_video_widget_logo_expose_event), bvw);
+ g_signal_connect (GTK_WIDGET (bvw->priv->video_da), "expose-event",
+ G_CALLBACK (bacon_video_widget_video_expose_event), bvw);
+
+ bacon_video_widget_set_logo_mode (bvw, TRUE);
}
static gboolean bvw_query_timeout (BaconVideoWidget * bvw);
@@ -1447,10 +1487,6 @@ bacon_video_widget_finalize (GObject * object)
g_free (bvw->priv->mrl);
bvw->priv->mrl = NULL;
-
-
-
-
if (bvw->priv->play != NULL && GST_IS_ELEMENT (bvw->priv->play)) {
gst_element_set_state (bvw->priv->play, GST_STATE_NULL);
gst_object_unref (bvw->priv->play);
@@ -3144,22 +3180,28 @@ bacon_video_widget_set_logo_mode (BaconVideoWidget * bvw, gboolean logo_mode)
logo_mode = logo_mode != FALSE;
+ g_mutex_lock (bvw->priv->lock);
+
if (priv->logo_mode != logo_mode) {
priv->logo_mode = logo_mode;
if (logo_mode) {
- /*gdk_window_hide (priv->video_window);*/
- GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
+ gtk_widget_show (priv->logo_da);
+ gtk_widget_hide (priv->video_da);
} else {
- /*gdk_window_show (priv->video_window);*/
- GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
+ gtk_widget_show (priv->video_da);
+ gtk_widget_hide (priv->logo_da);
}
+ g_mutex_unlock (bvw->priv->lock);
+
g_object_notify (G_OBJECT (bvw), "logo_mode");
g_object_notify (G_OBJECT (bvw), "seekable");
/* Queue a redraw of the widget */
gtk_widget_queue_draw (GTK_WIDGET (bvw));
+ } else {
+ g_mutex_unlock (bvw->priv->lock);
}
}
@@ -4439,7 +4481,7 @@ bacon_video_widget_get_current_frame (BaconVideoWidget * bvw)
/* */
/* =========================================== */
-G_DEFINE_TYPE (BaconVideoWidget, bacon_video_widget, GTK_TYPE_DRAWING_AREA)
+G_DEFINE_TYPE (BaconVideoWidget, bacon_video_widget, GTK_TYPE_HBOX)
/* applications must use exactly one of bacon_video_widget_get_option_group()
* OR bacon_video_widget_init_backend(), but not both */
/**
@@ -4556,6 +4598,8 @@ bacon_video_widget_new (int width, int height, BvwUseType type, GError ** err)
/* show the gui. */
gtk_widget_show_all (GTK_WIDGET(bvw));
+ bacon_video_widget_set_logo_mode (bvw, TRUE);
+
bvw->priv->use_type = type;
GST_INFO ("use_type = %d", type);
diff --git a/libcesarplayer/bacon-video-widget.h b/libcesarplayer/bacon-video-widget.h
index 8dbe388..5a2753d 100644
--- a/libcesarplayer/bacon-video-widget.h
+++ b/libcesarplayer/bacon-video-widget.h
@@ -52,13 +52,13 @@ typedef struct BaconVideoWidgetPrivate BaconVideoWidgetPrivate;
typedef struct
{
- GtkDrawingArea parent;
+ GtkHBox parent;
BaconVideoWidgetPrivate *priv;
} BaconVideoWidget;
typedef struct
{
- GtkDrawingAreaClass parent_class;
+ GtkHBoxClass parent_class;
void (*error) (BaconVideoWidget * bvw, const char *message);
void (*eos) (BaconVideoWidget * bvw);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]