This is an automated email from the git hooks/post-receive script. bluesabre pushed a commit to branch master in repository apps/parole.
commit 8072b2c8c042fc4d7c47c83b203f2c14d013ae0a Author: Sean Davis <[email protected]> Date: Tue Jun 17 23:32:31 2014 -0400 Separate clutter into its own source --- src/Makefile.am | 2 + src/gst/parole-gst.c | 20 +-- src/parole-clutter.c | 359 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/parole-clutter.h | 47 +++++++ src/parole-player.c | 59 +++------ 5 files changed, 434 insertions(+), 53 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index d9646bb..a0955f7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,6 +52,8 @@ parole_SOURCES = \ parole-medialist.h \ parole-mediachooser.c \ parole-mediachooser.h \ + parole-clutter.c \ + parole-clutter.h \ parole-conf.c \ parole-conf.h \ parole-conf-dialog.c \ diff --git a/src/gst/parole-gst.c b/src/gst/parole-gst.c index 08d94db..bcea70b 100644 --- a/src/gst/parole-gst.c +++ b/src/gst/parole-gst.c @@ -2218,6 +2218,7 @@ parole_gst_constructed (GObject *object) ParoleGst *gst; gchar *videosink = NULL; + gchar *playbin = NULL; gst = PAROLE_GST (object); @@ -2226,29 +2227,29 @@ parole_gst_constructed (GObject *object) NULL); #if GST_CHECK_VERSION(1, 0, 0) - gst->priv->playbin = gst_element_factory_make ("playbin", "player"); + playbin = g_strdup("playbin"); #else - gst->priv->playbin = gst_element_factory_make ("playbin2", "player"); + playbin = g_strdup("playbin2"); #endif + /* Configure the playbin */ + gst->priv->playbin = gst_element_factory_make (playbin, "player"); if ( G_UNLIKELY (gst->priv->playbin == NULL) ) { GError *error; error = g_error_new (1, 0, _("Unable to load \"%s\" plugin" ", check your GStreamer installation."), -#if GST_CHECK_VERSION(1, 0, 0) - "playbin"); -#else - "playbin2"); -#endif + playbin); parole_gst_show_error (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gst))), error); g_error_free (error); g_error ("playbin load failed"); } + g_free(playbin); + /* Configure the audio sink */ gst->priv->audio_sink = gst_element_factory_make ("autoaudiosink", "audio"); if ( G_UNLIKELY (gst->priv->audio_sink == NULL) ) { @@ -2261,16 +2262,17 @@ parole_gst_constructed (GObject *object) g_error ("autoaudiosink load failed"); } + /* Configure the video sink */ if (g_strcmp0(videosink, "xvimagesink") == 0) { - gst->priv->video_sink = gst_element_factory_make ("xvimagesink", "video"); gst->priv->image_sink = XVIMAGESINK; + gst->priv->video_sink = gst_element_factory_make ("xvimagesink", "video"); } if (g_strcmp0(videosink, "cluttersink") == 0) { - gst->priv->video_sink = gst_element_factory_make ("cluttersink", "video"); gst->priv->image_sink = CLUTTERSINK; + gst->priv->video_sink = gst_element_factory_make ("cluttersink", "video"); } if ( G_UNLIKELY (gst->priv->video_sink == NULL) ) diff --git a/src/parole-clutter.c b/src/parole-clutter.c new file mode 100644 index 0000000..6e6416f --- /dev/null +++ b/src/parole-clutter.c @@ -0,0 +1,359 @@ +#include <gtk/gtk.h> +#include <glib.h> +#include <gdk/gdkx.h> + +#include <clutter/clutter.h> +#include <clutter-gtk/clutter-gtk.h> + +#include <gst/video/video.h> + +#include <libxfce4util/libxfce4util.h> + +#include "gst/gst-enum-types.h" +#include "parole-gst.h" +#include "parole-clutter.h" + +#define PAROLE_CLUTTER_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_CLUTTER, ParoleClutterPrivate)) + +struct ParoleClutterPrivate +{ + GtkWidget *embed; + + ClutterActor *stage; + ClutterActor *texture; + + ParoleAspectRatio aspect_ratio; + + gpointer conf; + + gint video_w; + gint video_h; +}; + +enum +{ + PROP_0, + PROP_CONF_OBJ +}; + +static gpointer parole_clutter_object = NULL; + +G_DEFINE_TYPE (ParoleClutter, parole_clutter, GTK_TYPE_WIDGET) + +static void +parole_clutter_finalize (GObject *object) +{ + //ParoleClutter *clutter; + + //clutter = PAROLE_CLUTTER (object); + + TRACE ("start"); + + G_OBJECT_CLASS (parole_clutter_parent_class)->finalize (object); +} + +static void +parole_clutter_show (GtkWidget *widget) +{ + if ( gtk_widget_get_window(widget) ) + gdk_window_show (gtk_widget_get_window(widget)); + + if ( GTK_WIDGET_CLASS (parole_clutter_parent_class)->show ) + GTK_WIDGET_CLASS (parole_clutter_parent_class)->show (widget); +} + +static void +parole_clutter_constructed (GObject *object) +{ + //ParoleClutter *clutter; + + //clutter = PAROLE_CLUTTER (object); +} + +static void +parole_clutter_get_video_output_size (ParoleClutter *clutter, gint *ret_w, gint *ret_h) +{ + guint video_w, video_h; + guint video_par_n, video_par_d; + guint dar_n, dar_d; + guint disp_par_n, disp_par_d; + /* + * TODO: FIX Aspect Ratios following change + */ + GtkAllocation *allocation = g_new0 (GtkAllocation, 1); + gtk_widget_get_allocation(GTK_WIDGET(clutter->priv->embed), allocation); + *ret_w = allocation->width; + *ret_h = allocation->height; + g_free(allocation); + + disp_par_n = 1; + disp_par_d = 1; + + video_w = clutter->priv->video_w; + video_h = clutter->priv->video_h; + + if ( video_w != 0 && video_h != 0 ) + { + switch ( clutter->priv->aspect_ratio ) + { + case PAROLE_ASPECT_RATIO_NONE: + return; + case PAROLE_ASPECT_RATIO_AUTO: + *ret_w = video_w; + *ret_h = video_h; + return; + case PAROLE_ASPECT_RATIO_SQUARE: + video_par_n = 1; + video_par_d = 1; + break; + case PAROLE_ASPECT_RATIO_16_9: + video_par_n = 16 * video_h; + video_par_d = 9 * video_w; + break; + case PAROLE_ASPECT_RATIO_4_3: + video_par_n = 4 * video_h; + video_par_d = 3 * video_w; + break; + case PAROLE_ASPECT_RATIO_DVB: + video_par_n = 20 * video_h; + video_par_d = 9 * video_w; + break; + default: + return; + } + + if ( gst_video_calculate_display_ratio (&dar_n, &dar_d, + video_w, video_h, + video_par_n, video_par_d, + disp_par_n, disp_par_d) ) + { + if (video_w % dar_n == 0) + { + *ret_w = video_w; + *ret_h = (guint) gst_util_uint64_scale (video_w, dar_d, dar_n); + } + else + { + *ret_w = (guint) gst_util_uint64_scale (video_h, dar_n, dar_d); + *ret_h = video_h; + } + TRACE ("Got best video size %dx%d fraction, %d/%d\n", *ret_w, *ret_h, disp_par_n, disp_par_d); + } + } +} + +static void +parole_clutter_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + ParoleClutter *clutter; + + g_return_if_fail (allocation != NULL); + + gtk_widget_set_allocation(widget, allocation); + + if ( gtk_widget_get_realized (widget) ) + { + gint w, h; + gdouble ratio, width, height; + + clutter = PAROLE_CLUTTER(parole_clutter_get()); + + w = allocation->width; + h = allocation->height; + + clutter_actor_set_size (clutter->priv->stage, w, h); + + parole_clutter_get_video_output_size (clutter, &w, &h); + + width = w; + height = h; + + if ( (gdouble) allocation->width / width > allocation->height / height) + ratio = (gdouble) allocation->height / height; + else + ratio = (gdouble) allocation->width / width; + + width *= ratio; + height *= ratio; + + clutter_actor_set_size (clutter->priv->texture, width, height); + clutter_actor_set_x (clutter->priv->texture, (allocation->width - width)/2); + clutter_actor_set_y (clutter->priv->texture, (allocation->height - height)/2); + + gtk_widget_queue_draw (widget); + } +} + +static void +parole_clutter_conf_notify_cb (GObject *object, GParamSpec *spec, ParoleClutter *clutter) +{ + GtkAllocation *allocation = g_new0 (GtkAllocation, 1); + if ( !g_strcmp0 ("aspect-ratio", spec->name) ) + { + g_object_get (G_OBJECT (clutter->priv->conf), + "aspect-ratio", &clutter->priv->aspect_ratio, + NULL); + + gtk_widget_get_allocation( GTK_WIDGET (clutter), allocation ); + parole_clutter_size_allocate (GTK_WIDGET (clutter->priv->embed), allocation); + g_free(allocation); + } +} + +static void parole_clutter_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ParoleClutter *clutter; + clutter = PAROLE_CLUTTER (object); + + switch (prop_id) + { + case PROP_CONF_OBJ: + g_value_set_pointer (value, clutter->priv->conf); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void parole_clutter_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ParoleClutter *clutter; + clutter = PAROLE_CLUTTER (object); + + switch (prop_id) + { + case PROP_CONF_OBJ: + clutter->priv->conf = g_value_get_pointer (value); + + if (clutter->priv->conf) + { + g_object_get (G_OBJECT (clutter->priv->conf), + "aspect-ratio", &clutter->priv->aspect_ratio, + NULL); + + g_signal_connect (G_OBJECT (clutter->priv->conf), "notify", + G_CALLBACK (parole_clutter_conf_notify_cb), clutter); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +parole_clutter_class_init (ParoleClutterClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = parole_clutter_finalize; + object_class->constructed = parole_clutter_constructed; + + object_class->set_property = parole_clutter_set_property; + object_class->get_property = parole_clutter_get_property; + + widget_class->show = parole_clutter_show; + + g_object_class_install_property (object_class, + PROP_CONF_OBJ, + g_param_spec_pointer ("conf-object", + NULL, NULL, + G_PARAM_CONSTRUCT_ONLY| + G_PARAM_READWRITE)); + + g_type_class_add_private (klass, sizeof (ParoleClutterPrivate)); +} + +static void +parole_clutter_init (ParoleClutter *clutter) +{ + ClutterColor *black; + GValue value = {0}; + + clutter->priv = PAROLE_CLUTTER_GET_PRIVATE (clutter); + + g_value_init(&value, G_TYPE_BOOLEAN); + g_value_set_boolean(&value, TRUE); + + black = clutter_color_new(0,0,0,255); + + clutter->priv->embed = gtk_clutter_embed_new(); + g_signal_connect (G_OBJECT(clutter->priv->embed), "size-allocate", + G_CALLBACK(parole_clutter_size_allocate), NULL); + + /* Configure the Stage */ + clutter->priv->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (clutter->priv->embed)); + clutter_actor_set_background_color(clutter->priv->stage, black); + + /* Configure the Texture */ + clutter->priv->texture = CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE, NULL)); + clutter_actor_set_x_align(clutter->priv->texture, CLUTTER_ACTOR_ALIGN_CENTER); + clutter_actor_set_y_align(clutter->priv->texture, CLUTTER_ACTOR_ALIGN_CENTER); + g_object_set_property (G_OBJECT(clutter->priv->texture), "keep-aspect-ratio", &value); + clutter_actor_add_child (clutter->priv->stage, clutter->priv->texture); + + gtk_widget_set_can_focus (GTK_WIDGET (clutter), TRUE); + + /* + * Disable double buffering on the video output to avoid + * flickering when resizing the window. + */ + gtk_widget_set_double_buffered (GTK_WIDGET (clutter), FALSE); +} + +GtkWidget * +parole_clutter_new (gpointer conf_obj) +{ + parole_clutter_object = g_object_new (PAROLE_TYPE_CLUTTER, + "conf-object", conf_obj, + NULL); + + g_object_add_weak_pointer (parole_clutter_object, &parole_clutter_object); + + return GTK_WIDGET (parole_clutter_object); +} + +GtkWidget *parole_clutter_get (void) +{ + if ( G_LIKELY (parole_clutter_object != NULL ) ) + { + /* + * Don't increase the reference count of this object as + * we need it to be destroyed immediately when the main + * window is destroyed. + */ + } + else + { + parole_clutter_object = g_object_new (PAROLE_TYPE_CLUTTER, NULL); + g_object_add_weak_pointer (parole_clutter_object, &parole_clutter_object); + } + + return GTK_WIDGET (parole_clutter_object); + +} + +void parole_clutter_set_video_dimensions (ParoleClutter *clutter, gint w, gint h) +{ + clutter->priv->video_w = w; + clutter->priv->video_h = h; +} + +ClutterActor *parole_clutter_get_texture (ParoleClutter *clutter) +{ + return clutter->priv->texture; +} + +GtkWidget *parole_clutter_get_embed_widget (ParoleClutter *clutter) +{ + return clutter->priv->embed; +} diff --git a/src/parole-clutter.h b/src/parole-clutter.h new file mode 100644 index 0000000..b15fbc4 --- /dev/null +++ b/src/parole-clutter.h @@ -0,0 +1,47 @@ + +#ifndef __PAROLE_CLUTTER_H +#define __PAROLE_CLUTTER_H + +#include <glib-object.h> +#include <gst/gst.h> +#include <gtk/gtk.h> + +#include <clutter/clutter.h> +#include <clutter-gtk/clutter-gtk.h> + +G_BEGIN_DECLS + +#define PAROLE_TYPE_CLUTTER (parole_clutter_get_type () ) +#define PAROLE_CLUTTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_CLUTTER, ParoleClutter)) +#define PAROLE_IS_CLUTTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_CLUTTER)) + +typedef struct ParoleClutterPrivate ParoleClutterPrivate; + +typedef struct +{ + GtkWidget parent; + ParoleClutterPrivate *priv; + +} ParoleClutter; + +typedef struct +{ + GtkWidgetClass parent_class; + +} ParoleClutterClass; + +GType parole_clutter_get_type (void) G_GNUC_CONST; +GtkWidget *parole_clutter_new (gpointer conf_obj); +GtkWidget *parole_clutter_get (void); +GtkWidget *parole_clutter_get_embed_widget (ParoleClutter *clutter); + +ClutterActor *parole_clutter_get_texture (ParoleClutter *clutter); + +void +parole_clutter_set_video_dimensions (ParoleClutter *clutter, + gint w, + gint h); + +G_END_DECLS + +#endif /* __PAROLE_CLUTTER_H */ diff --git a/src/parole-player.c b/src/parole-player.c index 1e42918..22fd430 100644 --- a/src/parole-player.c +++ b/src/parole-player.c @@ -70,6 +70,7 @@ #include "parole-button.h" #include "enum-gtypes.h" #include "parole-debug.h" +#include "parole-clutter.h" #include "gst/gst-enum-types.h" @@ -437,8 +438,7 @@ struct ParolePlayerPrivate gboolean buffering; gboolean wait_for_gst_disc_info; - ClutterActor *stage; - ClutterActor *texture; + GtkWidget *clutter; /* Actions */ GSimpleAction *media_next_action; @@ -1382,6 +1382,7 @@ parole_player_playing (ParolePlayer *player, const ParoleStream *stream) gint64 duration; gboolean seekable; gboolean live; + gint height, width; int hide_controls_timeout; @@ -1390,9 +1391,13 @@ parole_player_playing (ParolePlayer *player, const ParoleStream *stream) g_object_get (G_OBJECT (stream), "seekable", &seekable, "duration", &duration, + "video-width", &width, + "video-height", &height, "live", &live, NULL); + parole_clutter_set_video_dimensions (PAROLE_CLUTTER(player->priv->clutter), width, height); + if (player->priv->wait_for_gst_disc_info == TRUE) { parole_media_list_add_cdda_tracks(player->priv->list, parole_gst_get_num_tracks(PAROLE_GST (player->priv->gst))); @@ -2924,8 +2929,6 @@ gboolean parole_player_configure_event_cb (GtkWidget *widget, GdkEventConfigure *ev, ParolePlayer *player) { gint old_w, old_h, new_w, new_h; - gfloat clutter_width, clutter_height, x, y; - GtkAllocation *alloc = g_new(GtkAllocation, 1); /* Get the current window size */ gtk_window_get_size (GTK_WINDOW (widget), &new_w, &new_h); @@ -2950,32 +2953,6 @@ parole_player_configure_event_cb (GtkWidget *widget, GdkEventConfigure *ev, Paro } } - gtk_widget_get_allocation(player->priv->videobox, alloc); - clutter_actor_set_size (player->priv->stage, alloc->width, alloc->height); - - parole_gst_get_video_output_size_from_dimensions (PAROLE_GST(player->priv->gst), alloc->width, alloc->height, &new_w, &new_h); - - x = 0.0; - y = 0.0; - - if ( ((gdouble)alloc->width / (gdouble)new_w) * (gdouble)new_h <= (gdouble)alloc->height ) - { - clutter_height = ((gdouble)alloc->width / (gdouble)new_w) * (gdouble)new_h; - clutter_width = alloc->width; - y = (alloc->height - clutter_height) / 2.0; - } - - else - { - clutter_width = (((gdouble)alloc->height / (gdouble)new_h) * (gdouble)new_w); - clutter_height = alloc->height; - x = (alloc->width - clutter_width) / 2.0; - } - - clutter_actor_set_size (player->priv->texture, clutter_width, clutter_height); - clutter_actor_set_x(player->priv->texture, x); - clutter_actor_set_y(player->priv->texture, y); - return FALSE; } @@ -3574,26 +3551,20 @@ parole_player_init (ParolePlayer *player) { GtkWidget *clutterbox; GstElement *video_sink; - ClutterColor *color = clutter_color_new(0,0,0,255); - GValue value = {0}; - g_value_init(&value, G_TYPE_BOOLEAN); - g_value_set_boolean(&value, TRUE); + ClutterActor *texture; + + player->priv->clutter = parole_clutter_new(player->priv->conf); + clutterbox = parole_clutter_get_embed_widget(PAROLE_CLUTTER(player->priv->clutter)); + texture = parole_clutter_get_texture (PAROLE_CLUTTER(player->priv->clutter)); - clutterbox = gtk_clutter_embed_new(); gtk_box_pack_start (GTK_BOX (player->priv->videobox), clutterbox, TRUE, TRUE, 0); - player->priv->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (clutterbox)); - clutter_actor_set_background_color(player->priv->stage, color); - player->priv->texture = CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE, NULL)); - clutter_actor_set_x_align(player->priv->texture, CLUTTER_ACTOR_ALIGN_CENTER); - clutter_actor_set_y_align(player->priv->texture, CLUTTER_ACTOR_ALIGN_CENTER); - g_object_set_property (G_OBJECT(player->priv->texture), "keep-aspect-ratio", &value); + video_sink = parole_gst_video_sink (PAROLE_GST(player->priv->gst)); - g_object_set (video_sink, "texture", player->priv->texture, NULL); - clutter_actor_add_child (player->priv->stage, player->priv->texture); + g_object_set (video_sink, "texture", texture, NULL); + gtk_widget_show (clutterbox); - g_object_set_property (G_OBJECT(player->priv->texture), "keep-aspect-ratio", &value); } else { -- To stop receiving notification emails like this one, please contact the administrator of this repository. _______________________________________________ Xfce4-commits mailing list [email protected] https://mail.xfce.org/mailman/listinfo/xfce4-commits
