Commit 04a1b1dc authored by Sebastian Dröge's avatar Sebastian Dröge

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.
parent e17954aa
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -56,6 +56,7 @@ struct _GstSMPTE {
gint border;
gint depth;
guint64 duration;
gboolean invert;
/* negotiated format */
gint format;
......
......@@ -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;
......
......@@ -52,6 +52,7 @@ struct _GstSMPTEAlpha {
gint border;
gint depth;
gdouble position;
gboolean invert;
/* negotiated format */
GstVideoFormat format;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment