From 04a1b1dc48aa4b28b4bf977a451390a8b218442e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 15 Apr 2010 22:28:58 +0200 Subject: [PATCH] smpte: Add property for inverting the transition mask This converts a left-to-right transition to right-to-left or clock-wise to counter-clock-wise. --- gst/smpte/gstmask.c | 19 ++++++++++++++++--- gst/smpte/gstmask.h | 2 +- gst/smpte/gstsmpte.c | 25 ++++++++++++++++++++----- gst/smpte/gstsmpte.h | 1 + gst/smpte/gstsmptealpha.c | 43 ++++++++++++++++++++++++++++++++++++------- gst/smpte/gstsmptealpha.h | 1 + 6 files changed, 75 insertions(+), 16 deletions(-) diff --git a/gst/smpte/gstmask.c b/gst/smpte/gstmask.c index 9c0ba92..940bf82 100644 --- a/gst/smpte/gstmask.c +++ b/gst/smpte/gstmask.c @@ -69,7 +69,8 @@ gst_mask_find_definition (gint type) } GstMask * -gst_mask_factory_new (gint type, gint bpp, gint width, gint height) +gst_mask_factory_new (gint type, gboolean invert, gint bpp, gint width, + gint height) { GstMaskDefinition *definition; GstMask *mask = NULL; @@ -86,8 +87,20 @@ gst_mask_factory_new (gint type, gint bpp, gint width, gint height) mask->user_data = definition->user_data; mask->data = g_malloc (width * height * sizeof (guint32)); - if (definition->draw_func) - definition->draw_func (mask); + definition->draw_func (mask); + + if (invert) { + gint i, j; + guint32 *datap = mask->data; + guint32 max = (1 << bpp); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + *datap = max - *datap; + datap++; + } + } + } } return mask; diff --git a/gst/smpte/gstmask.h b/gst/smpte/gstmask.h index 7e29246..576475c 100644 --- a/gst/smpte/gstmask.h +++ b/gst/smpte/gstmask.h @@ -56,7 +56,7 @@ void _gst_mask_register (const GstMaskDefinition void _gst_mask_default_destroy (GstMask *mask); const GList* gst_mask_get_definitions (void); -GstMask* gst_mask_factory_new (gint type, gint bpp, gint width, gint height); +GstMask* gst_mask_factory_new (gint type, gboolean invert, gint bpp, gint width, gint height); void gst_mask_destroy (GstMask *mask); void _gst_barboxwipes_register (void); diff --git a/gst/smpte/gstsmpte.c b/gst/smpte/gstsmpte.c index 8f1fcc5..0ef60e2 100644 --- a/gst/smpte/gstsmpte.c +++ b/gst/smpte/gstsmpte.c @@ -87,6 +87,7 @@ enum #define DEFAULT_PROP_DEPTH 16 #define DEFAULT_PROP_FPS 0. #define DEFAULT_PROP_DURATION GST_SECOND +#define DEFAULT_PROP_INVERT FALSE enum { @@ -96,6 +97,7 @@ enum PROP_DEPTH, PROP_FPS, PROP_DURATION, + PROP_INVERT, PROP_LAST, }; @@ -242,6 +244,9 @@ gst_smpte_class_init (GstSMPTEClass * klass) g_param_spec_uint64 ("duration", "Duration", "Duration of the transition effect in nanoseconds", 0, G_MAXUINT64, DEFAULT_PROP_DURATION, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_INVERT, + g_param_spec_boolean ("invert", "Invert", + "Invert transition mask", DEFAULT_PROP_INVERT, G_PARAM_READWRITE)); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_smpte_change_state); } @@ -266,25 +271,27 @@ fill_i420 (guint8 * data, gint width, gint height, gint color) } static gboolean -gst_smpte_update_mask (GstSMPTE * smpte, gint type, gint depth, gint width, - gint height) +gst_smpte_update_mask (GstSMPTE * smpte, gint type, gboolean invert, + gint depth, gint width, gint height) { GstMask *newmask; if (smpte->mask) { if (smpte->type == type && + smpte->invert == invert && smpte->depth == depth && smpte->width == width && smpte->height == height) return TRUE; } - newmask = gst_mask_factory_new (type, depth, width, height); + newmask = gst_mask_factory_new (type, invert, depth, width, height); if (newmask) { if (smpte->mask) { gst_mask_destroy (smpte->mask); } smpte->mask = newmask; smpte->type = type; + smpte->invert = invert; smpte->depth = depth; smpte->width = width; smpte->height = height; @@ -321,8 +328,9 @@ gst_smpte_setcaps (GstPad * pad, GstCaps * caps) GST_DEBUG_OBJECT (smpte, "duration: %d frames", smpte->end_position); - ret = gst_smpte_update_mask (smpte, smpte->type, smpte->depth, smpte->width, - smpte->height); + ret = + gst_smpte_update_mask (smpte, smpte->type, smpte->invert, smpte->depth, + smpte->width, smpte->height); return ret; } @@ -365,6 +373,7 @@ gst_smpte_init (GstSMPTE * smpte) smpte->border = DEFAULT_PROP_BORDER; smpte->depth = DEFAULT_PROP_DEPTH; smpte->duration = DEFAULT_PROP_DURATION; + smpte->invert = DEFAULT_PROP_INVERT; smpte->fps_num = 0; smpte->fps_denom = 1; } @@ -558,6 +567,9 @@ gst_smpte_set_property (GObject * object, guint prop_id, case PROP_DURATION: smpte->duration = g_value_get_uint64 (value); break; + case PROP_INVERT: + smpte->invert = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -588,6 +600,9 @@ gst_smpte_get_property (GObject * object, guint prop_id, case PROP_DURATION: g_value_set_uint64 (value, smpte->duration); break; + case PROP_INVERT: + g_value_set_boolean (value, smpte->invert); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/smpte/gstsmpte.h b/gst/smpte/gstsmpte.h index 44a88c2..dc6bc6d 100644 --- a/gst/smpte/gstsmpte.h +++ b/gst/smpte/gstsmpte.h @@ -56,6 +56,7 @@ struct _GstSMPTE { gint border; gint depth; guint64 duration; + gboolean invert; /* negotiated format */ gint format; diff --git a/gst/smpte/gstsmptealpha.c b/gst/smpte/gstsmptealpha.c index dbebb73..0c962cc 100644 --- a/gst/smpte/gstsmptealpha.c +++ b/gst/smpte/gstsmptealpha.c @@ -88,6 +88,7 @@ enum #define DEFAULT_PROP_BORDER 0 #define DEFAULT_PROP_DEPTH 16 #define DEFAULT_PROP_POSITION 0.0 +#define DEFAULT_PROP_INVERT FALSE enum { @@ -96,6 +97,7 @@ enum PROP_BORDER, PROP_DEPTH, PROP_POSITION, + PROP_INVERT, PROP_LAST, }; @@ -231,6 +233,10 @@ gst_smpte_alpha_class_init (GstSMPTEAlphaClass * klass) g_param_spec_double ("position", "Position", "Position of the transition effect", 0.0, 1.0, DEFAULT_PROP_POSITION, GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_INVERT, + g_param_spec_boolean ("invert", "Invert", + "Invert transition mask", DEFAULT_PROP_POSITION, + GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_smpte_alpha_setcaps); trans_class->get_unit_size = @@ -239,8 +245,8 @@ gst_smpte_alpha_class_init (GstSMPTEAlphaClass * klass) } static gboolean -gst_smpte_alpha_update_mask (GstSMPTEAlpha * smpte, gint type, gint depth, - gint width, gint height) +gst_smpte_alpha_update_mask (GstSMPTEAlpha * smpte, gint type, + gboolean invert, gint depth, gint width, gint height) { GstMask *newmask; @@ -248,12 +254,14 @@ gst_smpte_alpha_update_mask (GstSMPTEAlpha * smpte, gint type, gint depth, * correct */ if (smpte->mask) { if (smpte->type == type && + smpte->invert == invert && smpte->depth == depth && smpte->width == width && smpte->height == height) return TRUE; } smpte->type = type; + smpte->invert = invert; smpte->depth = depth; smpte->width = width; smpte->height = height; @@ -263,7 +271,7 @@ gst_smpte_alpha_update_mask (GstSMPTEAlpha * smpte, gint type, gint depth, return TRUE; } - newmask = gst_mask_factory_new (type, depth, width, height); + newmask = gst_mask_factory_new (type, invert, depth, width, height); if (!newmask) goto mask_failed; @@ -306,8 +314,9 @@ gst_smpte_alpha_setcaps (GstBaseTransform * btrans, GstCaps * incaps, /* try to update the mask now, this will also adjust the width/height on * success */ GST_OBJECT_LOCK (smpte); - ret = gst_smpte_alpha_update_mask (smpte, smpte->type, smpte->depth, - width, height); + ret = + gst_smpte_alpha_update_mask (smpte, smpte->type, smpte->invert, + smpte->depth, width, height); GST_OBJECT_UNLOCK (smpte); if (!ret) goto mask_failed; @@ -383,6 +392,7 @@ gst_smpte_alpha_init (GstSMPTEAlpha * smpte) smpte->border = DEFAULT_PROP_BORDER; smpte->depth = DEFAULT_PROP_DEPTH; smpte->position = DEFAULT_PROP_POSITION; + smpte->invert = DEFAULT_PROP_INVERT; } static void @@ -574,7 +584,7 @@ gst_smpte_alpha_set_property (GObject * object, guint prop_id, * have to wait for the transform lock */ GST_OBJECT_LOCK (smpte); GST_OBJECT_UNLOCK (smpte); - gst_smpte_alpha_update_mask (smpte, type, + gst_smpte_alpha_update_mask (smpte, type, smpte->invert, smpte->depth, smpte->width, smpte->height); GST_BASE_TRANSFORM_UNLOCK (smpte); break; @@ -594,7 +604,7 @@ gst_smpte_alpha_set_property (GObject * object, guint prop_id, * have to wait for the transform lock */ GST_OBJECT_LOCK (smpte); GST_OBJECT_UNLOCK (smpte); - gst_smpte_alpha_update_mask (smpte, smpte->type, + gst_smpte_alpha_update_mask (smpte, smpte->type, smpte->invert, depth, smpte->width, smpte->height); GST_BASE_TRANSFORM_UNLOCK (smpte); break; @@ -604,6 +614,20 @@ gst_smpte_alpha_set_property (GObject * object, guint prop_id, smpte->position = g_value_get_double (value); GST_OBJECT_UNLOCK (smpte); break; + case PROP_INVERT:{ + gboolean invert; + + invert = g_value_get_boolean (value); + GST_BASE_TRANSFORM_LOCK (smpte); + /* also lock with the object lock so that reading the property doesn't + * have to wait for the transform lock */ + GST_OBJECT_LOCK (smpte); + GST_OBJECT_UNLOCK (smpte); + gst_smpte_alpha_update_mask (smpte, smpte->type, invert, + smpte->depth, smpte->width, smpte->height); + GST_BASE_TRANSFORM_UNLOCK (smpte); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -639,6 +663,11 @@ gst_smpte_alpha_get_property (GObject * object, guint prop_id, g_value_set_double (value, smpte->position); GST_OBJECT_UNLOCK (smpte); break; + case PROP_INVERT: + GST_OBJECT_LOCK (smpte); + g_value_set_boolean (value, smpte->invert); + GST_OBJECT_UNLOCK (smpte); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/smpte/gstsmptealpha.h b/gst/smpte/gstsmptealpha.h index 5e8f6fc..df9261e 100644 --- a/gst/smpte/gstsmptealpha.h +++ b/gst/smpte/gstsmptealpha.h @@ -52,6 +52,7 @@ struct _GstSMPTEAlpha { gint border; gint depth; gdouble position; + gboolean invert; /* negotiated format */ GstVideoFormat format; -- 2.7.4