[clutter-gst] add Aspectratio renderer
- From: Lionel Landwerlin <llandwerlin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter-gst] add Aspectratio renderer
- Date: Mon, 18 Mar 2013 23:37:50 +0000 (UTC)
commit ce15e8d18dc60428552c6a009135ca609b7c6065
Author: Lionel Landwerlin <llandwerlin gmail com>
Date: Thu Mar 14 02:10:23 2013 +0000
add Aspectratio renderer
clutter-gst/Makefile.am | 2 +
clutter-gst/clutter-gst-aspectratio.c | 242 +++++++++++++++++++++++++++++++++
clutter-gst/clutter-gst-aspectratio.h | 56 ++++++++
clutter-gst/clutter-gst.h | 1 +
4 files changed, 301 insertions(+), 0 deletions(-)
---
diff --git a/clutter-gst/Makefile.am b/clutter-gst/Makefile.am
index 2feae3d..5c1be5f 100644
--- a/clutter-gst/Makefile.am
+++ b/clutter-gst/Makefile.am
@@ -30,6 +30,7 @@ source_h = \
$(srcdir)/clutter-gst-camera-device.h \
$(srcdir)/clutter-gst-playback.h \
$(srcdir)/clutter-gst-player.h \
+ $(srcdir)/clutter-gst-aspectratio.h \
$(NULL)
source_priv_h = \
@@ -48,6 +49,7 @@ source_c = \
$(srcdir)/clutter-gst-camera-device.c \
$(srcdir)/clutter-gst-playback.c \
$(srcdir)/clutter-gst-util.c \
+ $(srcdir)/clutter-gst-aspectratio.c \
$(glib_enum_c) \
$(NULL)
diff --git a/clutter-gst/clutter-gst-aspectratio.c b/clutter-gst/clutter-gst-aspectratio.c
new file mode 100644
index 0000000..3dd1e47
--- /dev/null
+++ b/clutter-gst/clutter-gst-aspectratio.c
@@ -0,0 +1,242 @@
+/* clutter-gst-aspectratio.c */
+
+#include "clutter-gst-aspectratio.h"
+
+G_DEFINE_TYPE (ClutterGstAspectratio, clutter_gst_aspectratio, CLUTTER_GST_TYPE_ACTOR)
+
+#define ASPECTRATIO_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CLUTTER_GST_TYPE_ASPECTRATIO, ClutterGstAspectratioPrivate))
+
+struct _ClutterGstAspectratioPrivate
+{
+ ClutterGstPlayer *player;
+
+ gint frame_width;
+ gint frame_height;
+ ClutterActorBox paint_box;
+};
+
+/**/
+
+static void
+clutter_gst_aspectratio_get_preferred_width (ClutterActor *actor,
+ gfloat for_height,
+ gfloat *min_width,
+ gfloat *nat_width)
+{
+ ClutterGstAspectratioPrivate *priv = CLUTTER_GST_ASPECTRATIO (actor)->priv;
+
+ if (min_width)
+ *min_width = 0;
+ if (nat_width)
+ {
+ gdouble aspect = (gdouble) priv->frame_width / (gdouble) priv->frame_height;
+
+ if (for_height > 0)
+ *nat_width = for_height * aspect;
+ else
+ *nat_width = priv->frame_width;
+ }
+}
+
+static void
+clutter_gst_aspectratio_get_preferred_height (ClutterActor *actor,
+ gfloat for_width,
+ gfloat *min_height,
+ gfloat *nat_height)
+{
+ ClutterGstAspectratioPrivate *priv = CLUTTER_GST_ASPECTRATIO (actor)->priv;
+
+ if (min_height)
+ *min_height = 0;
+ if (nat_height)
+ {
+ gdouble aspect = (gdouble) priv->frame_width / (gdouble) priv->frame_height;
+
+ if (for_width > 0)
+ *nat_height = for_width / aspect;
+ else
+ *nat_height = priv->frame_height;
+ }
+}
+
+
+static void
+clutter_gst_aspectratio_paint_frame (ClutterGstActor *self,
+ ClutterGstFrame *frame)
+{
+ ClutterGstAspectratioPrivate *priv = CLUTTER_GST_ASPECTRATIO (self)->priv;
+ guint8 paint_opacity;
+
+ paint_opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self));
+ cogl_pipeline_set_color4ub (frame->pipeline,
+ paint_opacity,
+ paint_opacity,
+ paint_opacity,
+ paint_opacity);
+ cogl_set_source (frame->pipeline);
+
+ cogl_rectangle (priv->paint_box.x1, priv->paint_box.y1,
+ priv->paint_box.x2, priv->paint_box.y2);
+}
+
+static void
+_recompute_paint_box (ClutterGstAspectratio *self)
+{
+ ClutterGstAspectratioPrivate *priv = self->priv;
+ ClutterActorBox box;
+ gfloat actor_width, actor_height;
+ gdouble new_width, new_height;
+ gdouble frame_aspect, actor_aspect;
+
+ clutter_actor_get_allocation_box (CLUTTER_ACTOR (self), &box);
+
+ actor_width = box.x2 - box.x1;
+ actor_height = box.y2 - box.y1;
+
+ g_message ("alloc=(%fx%f)", actor_width, actor_height);
+
+ if (actor_width <= 0 || actor_height <= 0)
+ return;
+
+ frame_aspect = (gdouble) priv->frame_width / (gdouble) priv->frame_height;
+ actor_aspect = actor_width / actor_height;
+
+ if (actor_aspect < frame_aspect)
+ {
+ new_width = actor_width;
+ new_height = actor_width / frame_aspect;
+ }
+ else
+ {
+ new_height = actor_height;
+ new_width = actor_height * frame_aspect;
+ }
+
+ priv->paint_box.x1 = (actor_width - new_width) / 2;
+ priv->paint_box.y1 = (actor_height - new_height) / 2;
+ priv->paint_box.x2 = priv->paint_box.x1 + new_width;
+ priv->paint_box.y2 = priv->paint_box.y1 + new_height;
+
+ g_message ("output=(%fx%f) box=(%fx%f-%fx%f)", new_width, new_height,
+ priv->paint_box.x1, priv->paint_box.y1,
+ priv->paint_box.x2, priv->paint_box.y2);
+}
+
+static void
+_player_size_changed (ClutterGstPlayer *player,
+ gint width,
+ gint height,
+ ClutterGstAspectratio *self)
+{
+ ClutterGstAspectratioPrivate *priv = self->priv;
+
+ priv->frame_width = width;
+ priv->frame_height = height;
+
+ _recompute_paint_box (self);
+ clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
+}
+
+static void
+clutter_gst_aspectratio_player_changed (ClutterGstAspectratio *self,
+ GParamSpec *spec,
+ gpointer user_data)
+{
+ ClutterGstAspectratioPrivate *priv = self->priv;
+ ClutterGstPlayer *player = clutter_gst_actor_get_player (CLUTTER_GST_ACTOR (self));
+
+ if (priv->player)
+ g_signal_handlers_disconnect_by_func (priv->player, _player_size_changed, self);
+ priv->player = player;
+ if (priv->player)
+ {
+ ClutterGstFrame *frame = clutter_gst_player_get_frame (player);
+
+ priv->frame_width = frame->resolution.width;
+ priv->frame_height = frame->resolution.height;
+
+ g_signal_connect (priv->player, "size-change",
+ G_CALLBACK (_player_size_changed), self);
+ }
+
+ _recompute_paint_box (self);
+}
+
+
+/**/
+
+static void
+clutter_gst_aspectratio_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+clutter_gst_aspectratio_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+clutter_gst_aspectratio_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (clutter_gst_aspectratio_parent_class)->dispose (object);
+}
+
+static void
+clutter_gst_aspectratio_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (clutter_gst_aspectratio_parent_class)->finalize (object);
+}
+
+static void
+clutter_gst_aspectratio_class_init (ClutterGstAspectratioClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
+ ClutterGstActorClass *gst_actor_class = CLUTTER_GST_ACTOR_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (ClutterGstAspectratioPrivate));
+
+ object_class->get_property = clutter_gst_aspectratio_get_property;
+ object_class->set_property = clutter_gst_aspectratio_set_property;
+ object_class->dispose = clutter_gst_aspectratio_dispose;
+ object_class->finalize = clutter_gst_aspectratio_finalize;
+
+ actor_class->get_preferred_width = clutter_gst_aspectratio_get_preferred_width;
+ actor_class->get_preferred_height = clutter_gst_aspectratio_get_preferred_height;
+
+ gst_actor_class->paint_frame = clutter_gst_aspectratio_paint_frame;
+}
+
+static void
+clutter_gst_aspectratio_init (ClutterGstAspectratio *self)
+{
+ self->priv = ASPECTRATIO_PRIVATE (self);
+
+ g_signal_connect (self, "notify::player",
+ G_CALLBACK (clutter_gst_aspectratio_player_changed), NULL);
+ g_signal_connect_swapped (self, "allocation-changed",
+ G_CALLBACK (_recompute_paint_box), self);
+}
+
+ClutterGstAspectratio *
+clutter_gst_aspectratio_new (void)
+{
+ return g_object_new (CLUTTER_GST_TYPE_ASPECTRATIO, NULL);
+}
diff --git a/clutter-gst/clutter-gst-aspectratio.h b/clutter-gst/clutter-gst-aspectratio.h
new file mode 100644
index 0000000..4f74b51
--- /dev/null
+++ b/clutter-gst/clutter-gst-aspectratio.h
@@ -0,0 +1,56 @@
+/* clutter-gst-aspectratio.h */
+
+#ifndef __CLUTTER_GST_ASPECTRATIO_H__
+#define __CLUTTER_GST_ASPECTRATIO_H__
+
+#include <glib-object.h>
+
+#include <clutter-gst/clutter-gst-actor.h>
+
+G_BEGIN_DECLS
+
+#define CLUTTER_GST_TYPE_ASPECTRATIO clutter_gst_aspectratio_get_type()
+
+#define CLUTTER_GST_ASPECTRATIO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ CLUTTER_GST_TYPE_ASPECTRATIO, ClutterGstAspectratio))
+
+#define CLUTTER_GST_ASPECTRATIO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ CLUTTER_GST_TYPE_ASPECTRATIO, ClutterGstAspectratioClass))
+
+#define CLUTTER_GST_IS_ASPECTRATIO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ CLUTTER_GST_TYPE_ASPECTRATIO))
+
+#define CLUTTER_GST_IS_ASPECTRATIO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ CLUTTER_GST_TYPE_ASPECTRATIO))
+
+#define CLUTTER_GST_ASPECTRATIO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ CLUTTER_GST_TYPE_ASPECTRATIO, ClutterGstAspectratioClass))
+
+typedef struct _ClutterGstAspectratio ClutterGstAspectratio;
+typedef struct _ClutterGstAspectratioClass ClutterGstAspectratioClass;
+typedef struct _ClutterGstAspectratioPrivate ClutterGstAspectratioPrivate;
+
+struct _ClutterGstAspectratio
+{
+ ClutterGstActor parent;
+
+ ClutterGstAspectratioPrivate *priv;
+};
+
+struct _ClutterGstAspectratioClass
+{
+ ClutterGstActorClass parent_class;
+};
+
+GType clutter_gst_aspectratio_get_type (void) G_GNUC_CONST;
+
+ClutterGstAspectratio *clutter_gst_aspectratio_new (void);
+
+G_END_DECLS
+
+#endif /* __CLUTTER_GST_ASPECTRATIO_H__ */
diff --git a/clutter-gst/clutter-gst.h b/clutter-gst/clutter-gst.h
index b3790dd..2156780 100644
--- a/clutter-gst/clutter-gst.h
+++ b/clutter-gst/clutter-gst.h
@@ -33,6 +33,7 @@
#include "clutter-gst-types.h"
#include "clutter-gst-enum-types.h"
#include "clutter-gst-actor.h"
+#include "clutter-gst-aspectratio.h"
#include "clutter-gst-camera-device.h"
#include "clutter-gst-camera.h"
#include "clutter-gst-util.h"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]