[Xfce4-commits] [apps/parole] 01/02: Separate clutter into its own source
noreply at xfce.org
noreply at xfce.org
Wed Jun 18 06:37:35 CEST 2014
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 <smd.seandavis at gmail.com>
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.
More information about the Xfce4-commits
mailing list