2 * Copyright (C) <2008> Wim Taymans <wim.taymans@gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 * SECTION:element-smptealpha
23 * smptealpha can accept an I420 or AYUV video stream. An alpha channel is added
24 * using an effect specific SMPTE mask in the I420 input case. In the AYUV case,
25 * the alpha channel is modified using the effect specific SMPTE mask.
27 * The #GstSmpteAlpha:position property is a controllabe double between 0.0 and
28 * 1.0 that specifies the position in the transition. 0.0 is the start of the
29 * transition with the alpha channel to complete opaque where 1.0 has the alpha
30 * channel set to completely transparent.
32 * The #GstSmpteAlpha:depth property defines the precision in bits of the mask.
33 * A higher presision will create a mask with smoother gradients in order to
37 * <title>Sample pipelines</title>
39 * Here is a pipeline to demonstrate the smpte transition :
41 * gst-launch-1.0 -v videotestsrc ! smptealpha border=20000 type=44
42 * position=0.5 ! videomixer ! videoconvert ! ximagesink
44 * This shows a midway bowtie-h transition a from a videotestsrc to a
45 * transparent image. The edges of the transition are smoothed with a
56 #include "gstsmptealpha.h"
59 GST_DEBUG_CATEGORY_STATIC (gst_smpte_alpha_debug);
60 #define GST_CAT_DEFAULT gst_smpte_alpha_debug
62 static GstStaticPadTemplate gst_smpte_alpha_src_template =
63 GST_STATIC_PAD_TEMPLATE ("src",
66 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("AYUV") ";"
67 GST_VIDEO_CAPS_MAKE ("ARGB") ";" GST_VIDEO_CAPS_MAKE ("BGRA") ";"
68 GST_VIDEO_CAPS_MAKE ("RGBA") ";" GST_VIDEO_CAPS_MAKE ("ARGB"))
71 static GstStaticPadTemplate gst_smpte_alpha_sink_template =
72 GST_STATIC_PAD_TEMPLATE ("sink",
75 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420") ";"
76 GST_VIDEO_CAPS_MAKE ("YV12")
77 ";" GST_VIDEO_CAPS_MAKE ("AYUV")
78 ";" GST_VIDEO_CAPS_MAKE ("ARGB") ";" GST_VIDEO_CAPS_MAKE ("BGRA")
79 ";" GST_VIDEO_CAPS_MAKE ("RGBA") ";" GST_VIDEO_CAPS_MAKE ("ARGB"))
82 /* SMPTE signals and properties */
84 #define DEFAULT_PROP_TYPE 1
85 #define DEFAULT_PROP_BORDER 0
86 #define DEFAULT_PROP_DEPTH 16
87 #define DEFAULT_PROP_POSITION 0.0
88 #define DEFAULT_PROP_INVERT FALSE
100 #define AYUV_SIZE(w,h) ((w) * (h) * 4)
102 #define GST_TYPE_SMPTE_TRANSITION_TYPE (gst_smpte_alpha_transition_type_get_type())
104 gst_smpte_alpha_transition_type_get_type (void)
106 static GType smpte_transition_type = 0;
107 GEnumValue *smpte_transitions;
109 if (!smpte_transition_type) {
110 const GList *definitions;
113 definitions = gst_mask_get_definitions ();
115 g_new0 (GEnumValue, g_list_length ((GList *) definitions) + 1);
117 while (definitions) {
118 GstMaskDefinition *definition = (GstMaskDefinition *) definitions->data;
120 definitions = g_list_next (definitions);
122 smpte_transitions[i].value = definition->type;
123 /* older GLib versions have the two fields as non-const, hence the cast */
124 smpte_transitions[i].value_nick = (gchar *) definition->short_name;
125 smpte_transitions[i].value_name = (gchar *) definition->long_name;
130 smpte_transition_type =
131 g_enum_register_static ("GstSMPTEAlphaTransitionType",
134 return smpte_transition_type;
138 static void gst_smpte_alpha_finalize (GstSMPTEAlpha * smpte);
140 static void gst_smpte_alpha_set_property (GObject * object, guint prop_id,
141 const GValue * value, GParamSpec * pspec);
142 static void gst_smpte_alpha_get_property (GObject * object, guint prop_id,
143 GValue * value, GParamSpec * pspec);
145 static gboolean gst_smpte_alpha_set_info (GstVideoFilter * vfilter,
146 GstCaps * incaps, GstVideoInfo * in_info,
147 GstCaps * outcaps, GstVideoInfo * out_info);
148 static GstFlowReturn gst_smpte_alpha_transform_frame (GstVideoFilter * vfilter,
149 GstVideoFrame * in_frame, GstVideoFrame * out_frame);
150 static void gst_smpte_alpha_before_transform (GstBaseTransform * trans,
152 static GstCaps *gst_smpte_alpha_transform_caps (GstBaseTransform * trans,
153 GstPadDirection direction, GstCaps * from, GstCaps * filter);
155 #define gst_smpte_alpha_parent_class parent_class
156 G_DEFINE_TYPE (GstSMPTEAlpha, gst_smpte_alpha, GST_TYPE_VIDEO_FILTER);
159 gst_smpte_alpha_class_init (GstSMPTEAlphaClass * klass)
161 GObjectClass *gobject_class = (GObjectClass *) klass;
162 GstElementClass *element_class = (GstElementClass *) (klass);
163 GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
164 GstVideoFilterClass *vfilter_class = (GstVideoFilterClass *) klass;
166 gobject_class->set_property = gst_smpte_alpha_set_property;
167 gobject_class->get_property = gst_smpte_alpha_get_property;
169 gobject_class->finalize = (GObjectFinalizeFunc) gst_smpte_alpha_finalize;
173 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TYPE,
174 g_param_spec_enum ("type", "Type", "The type of transition to use",
175 GST_TYPE_SMPTE_TRANSITION_TYPE, DEFAULT_PROP_TYPE,
176 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
177 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BORDER,
178 g_param_spec_int ("border", "Border",
179 "The border width of the transition", 0, G_MAXINT,
181 GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
182 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEPTH,
183 g_param_spec_int ("depth", "Depth", "Depth of the mask in bits", 1, 24,
184 DEFAULT_PROP_DEPTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
185 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_POSITION,
186 g_param_spec_double ("position", "Position",
187 "Position of the transition effect", 0.0, 1.0, DEFAULT_PROP_POSITION,
188 GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
190 * GstSMPTEAlpha:invert:
192 * Set to TRUE to invert the transition mask (ie. flip it horizontally).
194 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_INVERT,
195 g_param_spec_boolean ("invert", "Invert",
196 "Invert transition mask", DEFAULT_PROP_POSITION,
197 GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
199 trans_class->before_transform =
200 GST_DEBUG_FUNCPTR (gst_smpte_alpha_before_transform);
201 trans_class->transform_caps =
202 GST_DEBUG_FUNCPTR (gst_smpte_alpha_transform_caps);
204 vfilter_class->set_info = GST_DEBUG_FUNCPTR (gst_smpte_alpha_set_info);
205 vfilter_class->transform_frame =
206 GST_DEBUG_FUNCPTR (gst_smpte_alpha_transform_frame);
208 gst_element_class_add_static_pad_template (element_class,
209 &gst_smpte_alpha_sink_template);
210 gst_element_class_add_static_pad_template (element_class,
211 &gst_smpte_alpha_src_template);
212 gst_element_class_set_static_metadata (element_class, "SMPTE transitions",
213 "Filter/Editor/Video",
214 "Apply the standard SMPTE transitions as alpha on video images",
215 "Wim Taymans <wim.taymans@gmail.com>");
219 gst_smpte_alpha_update_mask (GstSMPTEAlpha * smpte, gint type,
220 gboolean invert, gint depth, gint width, gint height)
224 /* try to avoid regenerating the mask if we already have one that is
227 if (smpte->type == type &&
228 smpte->invert == invert &&
229 smpte->depth == depth &&
230 smpte->width == width && smpte->height == height)
235 smpte->invert = invert;
236 smpte->depth = depth;
237 smpte->width = width;
238 smpte->height = height;
240 /* Not negotiated yet */
241 if (width == 0 || height == 0) {
245 newmask = gst_mask_factory_new (type, invert, depth, width, height);
250 gst_mask_destroy (smpte->mask);
252 smpte->mask = newmask;
259 GST_ERROR_OBJECT (smpte, "failed to create a mask");
265 gst_smpte_alpha_init (GstSMPTEAlpha * smpte)
267 smpte->type = DEFAULT_PROP_TYPE;
268 smpte->border = DEFAULT_PROP_BORDER;
269 smpte->depth = DEFAULT_PROP_DEPTH;
270 smpte->position = DEFAULT_PROP_POSITION;
271 smpte->invert = DEFAULT_PROP_INVERT;
274 #define CREATE_ARGB_FUNC(name, A, R, G, B) \
276 gst_smpte_alpha_process_##name##_##name (GstSMPTEAlpha * smpte, \
277 const GstVideoFrame * in_frame, GstVideoFrame * out_frame, GstMask * mask, \
278 gint border, gint pos) \
281 const guint32 *maskp; \
284 gint width, height; \
286 gint src_wrap, dest_wrap; \
291 min = pos - border; \
293 GST_DEBUG_OBJECT (smpte, "pos %d, min %d, max %d, border %d", pos, min, max, \
296 maskp = mask->data; \
298 width = GST_VIDEO_FRAME_WIDTH (out_frame); \
299 height = GST_VIDEO_FRAME_HEIGHT (out_frame); \
301 in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0); \
302 out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0); \
303 src_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0) - (width << 2); \
304 dest_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0) - (width << 2); \
306 /* we basically copy the source to dest but we scale the alpha channel with \
308 for (i = 0; i < height; i++) { \
309 for (j = 0; j < width; j++) { \
311 out[A] = (in[A] * ((CLAMP (value, min, max) - min) << 8) / border) >> 8; \
323 CREATE_ARGB_FUNC (argb, 0, 1, 2, 3);
324 CREATE_ARGB_FUNC (bgra, 3, 2, 1, 0);
325 CREATE_ARGB_FUNC (abgr, 0, 3, 2, 1);
326 CREATE_ARGB_FUNC (rgba, 3, 0, 1, 2);
329 gst_smpte_alpha_process_ayuv_ayuv (GstSMPTEAlpha * smpte,
330 const GstVideoFrame * in_frame, GstVideoFrame * out_frame, GstMask * mask,
331 gint border, gint pos)
334 const guint32 *maskp;
339 gint src_wrap, dest_wrap;
346 GST_DEBUG_OBJECT (smpte, "pos %d, min %d, max %d, border %d", pos, min, max,
351 width = GST_VIDEO_FRAME_WIDTH (out_frame);
352 height = GST_VIDEO_FRAME_HEIGHT (out_frame);
354 in = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
355 out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
356 src_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0) - (width << 2);
357 dest_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0) - (width << 2);
359 /* we basically copy the source to dest but we scale the alpha channel with
361 for (i = 0; i < height; i++) {
362 for (j = 0; j < width; j++) {
364 *out++ = (*in++ * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
375 gst_smpte_alpha_process_i420_ayuv (GstSMPTEAlpha * smpte,
376 const GstVideoFrame * in_frame, GstVideoFrame * out_frame, GstMask * mask,
377 gint border, gint pos)
384 gint src_wrap, src_u_wrap, src_v_wrap, dest_wrap;
385 gint y_stride, u_stride, v_stride;
387 const guint32 *maskp;
397 GST_DEBUG_OBJECT (smpte, "pos %d, min %d, max %d, border %d", pos, min, max,
402 width = GST_VIDEO_FRAME_WIDTH (out_frame);
403 height = GST_VIDEO_FRAME_HEIGHT (out_frame);
405 y_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 0);
406 u_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 1);
407 v_stride = GST_VIDEO_FRAME_COMP_STRIDE (in_frame, 2);
409 src_wrap = y_stride - width;
410 src_u_wrap = u_stride - (width / 2);
411 src_v_wrap = v_stride - (width / 2);
413 srcY = GST_VIDEO_FRAME_COMP_DATA (in_frame, 0);
414 srcU = GST_VIDEO_FRAME_COMP_DATA (in_frame, 1);
415 srcV = GST_VIDEO_FRAME_COMP_DATA (in_frame, 2);
417 out = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
418 dest_wrap = GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0) - (width << 2);
420 odd_width = (width % 2 != 0);
422 for (i = 0; i < height; i++) {
423 for (j = 0; j < width / 2; j++) {
425 *out++ = (0xff * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
430 *out++ = (0xff * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
435 /* Might have one odd column left to do */
438 *out++ = (0xff * ((CLAMP (value, min, max) - min) << 8) / border) >> 8;
456 gst_smpte_alpha_before_transform (GstBaseTransform * trans, GstBuffer * buf)
458 GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (trans);
459 GstClockTime timestamp, stream_time;
461 /* first sync the controller to the current stream_time of the buffer */
462 timestamp = GST_BUFFER_TIMESTAMP (buf);
464 gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);
466 GST_DEBUG_OBJECT (smpte, "sync to %" GST_TIME_FORMAT,
467 GST_TIME_ARGS (timestamp));
469 if (GST_CLOCK_TIME_IS_VALID (stream_time))
470 gst_object_sync_values (GST_OBJECT (smpte), stream_time);
474 gst_smpte_alpha_transform_frame (GstVideoFilter * vfilter,
475 GstVideoFrame * in_frame, GstVideoFrame * out_frame)
477 GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (vfilter);
481 if (G_UNLIKELY (!smpte->process))
484 GST_OBJECT_LOCK (smpte);
485 position = smpte->position;
486 border = smpte->border;
488 /* run the type specific filter code */
489 smpte->process (smpte, in_frame, out_frame,
490 smpte->mask, border, ((1 << smpte->depth) + border) * position);
491 GST_OBJECT_UNLOCK (smpte);
498 GST_ELEMENT_ERROR (smpte, CORE, NEGOTIATION, (NULL),
499 ("No input format negotiated"));
500 return GST_FLOW_NOT_NEGOTIATED;
505 gst_smpte_alpha_transform_caps (GstBaseTransform * trans,
506 GstPadDirection direction, GstCaps * from, GstCaps * filter)
508 GstCaps *result, *tmp_caps, *tmpl_caps = NULL;
511 tmp_caps = gst_caps_new_empty ();
513 for (i = 0; i < gst_caps_get_size (from); i++) {
514 GstStructure *structure;
515 const GValue *val, *lval;
516 GValue list = { 0, };
517 GValue aval = { 0, };
520 structure = gst_structure_copy (gst_caps_get_structure (from, i));
521 /* we can transform I420 to AYUV,
522 * so need to locate and substitute AYUV for the both of them */
523 val = gst_structure_get_value (structure, "format");
524 if (val && GST_VALUE_HOLDS_LIST (val)) {
525 gboolean seen_ayuv = FALSE, seen_i420 = FALSE;
527 g_value_init (&list, GST_TYPE_LIST);
528 for (j = 0; j < gst_value_list_get_size (val); j++) {
529 lval = gst_value_list_get_value (val, j);
530 if ((str = g_value_get_string (lval))) {
531 if (strcmp (str, "AYUV") == 0) {
533 } else if (strcmp (str, "I420") == 0) {
538 if (seen_ayuv && !seen_i420) {
540 } else if (seen_i420 && !seen_ayuv) {
545 g_value_copy (val, &list);
546 g_value_init (&aval, G_TYPE_STRING);
547 g_value_set_string (&aval, str);
548 gst_value_list_append_value (&list, &aval);
549 g_value_reset (&aval);
550 gst_structure_set_value (structure, "format", &list);
551 g_value_unset (&list);
553 } else if (val && G_VALUE_HOLDS_STRING (val)) {
554 if ((str = g_value_get_string (val)) &&
555 ((strcmp (str, "AYUV") == 0) || (strcmp (str, "I420") == 0))) {
556 g_value_init (&list, GST_TYPE_LIST);
557 g_value_init (&aval, G_TYPE_STRING);
558 g_value_set_string (&aval, "AYUV");
559 gst_value_list_append_value (&list, &aval);
560 g_value_reset (&aval);
561 g_value_set_string (&aval, "I420");
562 gst_value_list_append_value (&list, &aval);
563 g_value_reset (&aval);
564 gst_structure_set_value (structure, "format", &list);
565 g_value_unset (&list);
568 gst_structure_remove_field (structure, "format");
571 gst_structure_remove_field (structure, "colorimetry");
572 gst_structure_remove_field (structure, "chroma-site");
574 gst_caps_append_structure (tmp_caps, structure);
577 /* Get the appropriate template */
578 if (direction == GST_PAD_SINK) {
580 gst_static_pad_template_get_caps (&gst_smpte_alpha_src_template);
581 } else if (direction == GST_PAD_SRC) {
583 gst_static_pad_template_get_caps (&gst_smpte_alpha_sink_template);
585 g_assert_not_reached ();
588 /* Intersect with our template caps */
589 result = gst_caps_intersect (tmp_caps, tmpl_caps);
590 gst_caps_unref (tmpl_caps);
591 gst_caps_unref (tmp_caps);
593 result = gst_caps_simplify (result);
595 GST_LOG_OBJECT (trans, "transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT,
599 GstCaps *intersection;
601 GST_DEBUG_OBJECT (trans, "Using filter caps %" GST_PTR_FORMAT, filter);
603 gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
604 gst_caps_unref (result);
605 result = intersection;
606 GST_DEBUG_OBJECT (trans, "Intersection %" GST_PTR_FORMAT, result);
613 gst_smpte_alpha_set_info (GstVideoFilter * vfilter, GstCaps * incaps,
614 GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
616 GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (vfilter);
619 smpte->process = NULL;
620 smpte->in_format = GST_VIDEO_INFO_FORMAT (in_info);
621 smpte->out_format = GST_VIDEO_INFO_FORMAT (out_info);
623 /* try to update the mask now, this will also adjust the width/height on
625 GST_OBJECT_LOCK (smpte);
627 gst_smpte_alpha_update_mask (smpte, smpte->type, smpte->invert,
628 smpte->depth, GST_VIDEO_INFO_WIDTH (out_info),
629 GST_VIDEO_INFO_HEIGHT (out_info));
630 GST_OBJECT_UNLOCK (smpte);
635 switch (smpte->out_format) {
636 case GST_VIDEO_FORMAT_AYUV:
637 switch (smpte->in_format) {
638 case GST_VIDEO_FORMAT_AYUV:
639 smpte->process = gst_smpte_alpha_process_ayuv_ayuv;
641 case GST_VIDEO_FORMAT_I420:
642 smpte->process = gst_smpte_alpha_process_i420_ayuv;
648 case GST_VIDEO_FORMAT_ARGB:
649 switch (smpte->in_format) {
650 case GST_VIDEO_FORMAT_ARGB:
651 smpte->process = gst_smpte_alpha_process_argb_argb;
657 case GST_VIDEO_FORMAT_RGBA:
658 switch (smpte->in_format) {
659 case GST_VIDEO_FORMAT_RGBA:
660 smpte->process = gst_smpte_alpha_process_rgba_rgba;
666 case GST_VIDEO_FORMAT_ABGR:
667 switch (smpte->in_format) {
668 case GST_VIDEO_FORMAT_ABGR:
669 smpte->process = gst_smpte_alpha_process_abgr_abgr;
675 case GST_VIDEO_FORMAT_BGRA:
676 switch (smpte->in_format) {
677 case GST_VIDEO_FORMAT_BGRA:
678 smpte->process = gst_smpte_alpha_process_bgra_bgra;
693 GST_ERROR_OBJECT (smpte, "failed creating the mask");
699 gst_smpte_alpha_finalize (GstSMPTEAlpha * smpte)
702 gst_mask_destroy (smpte->mask);
705 G_OBJECT_CLASS (parent_class)->finalize ((GObject *) smpte);
709 gst_smpte_alpha_set_property (GObject * object, guint prop_id,
710 const GValue * value, GParamSpec * pspec)
712 GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (object);
718 type = g_value_get_enum (value);
720 GST_OBJECT_LOCK (smpte);
721 gst_smpte_alpha_update_mask (smpte, type, smpte->invert,
722 smpte->depth, smpte->width, smpte->height);
723 GST_OBJECT_UNLOCK (smpte);
727 GST_OBJECT_LOCK (smpte);
728 smpte->border = g_value_get_int (value);
729 GST_OBJECT_UNLOCK (smpte);
734 depth = g_value_get_int (value);
736 GST_OBJECT_LOCK (smpte);
737 gst_smpte_alpha_update_mask (smpte, smpte->type, smpte->invert,
738 depth, smpte->width, smpte->height);
739 GST_OBJECT_UNLOCK (smpte);
743 GST_OBJECT_LOCK (smpte);
744 smpte->position = g_value_get_double (value);
745 GST_OBJECT_UNLOCK (smpte);
750 invert = g_value_get_boolean (value);
751 GST_OBJECT_LOCK (smpte);
752 gst_smpte_alpha_update_mask (smpte, smpte->type, invert,
753 smpte->depth, smpte->width, smpte->height);
754 GST_OBJECT_UNLOCK (smpte);
758 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
764 gst_smpte_alpha_get_property (GObject * object, guint prop_id,
765 GValue * value, GParamSpec * pspec)
767 GstSMPTEAlpha *smpte;
769 smpte = GST_SMPTE_ALPHA (object);
773 GST_OBJECT_LOCK (smpte);
774 g_value_set_enum (value, smpte->type);
775 GST_OBJECT_UNLOCK (smpte);
778 GST_OBJECT_LOCK (smpte);
779 g_value_set_int (value, smpte->border);
780 GST_OBJECT_UNLOCK (smpte);
783 GST_OBJECT_LOCK (smpte);
784 g_value_set_int (value, smpte->depth);
785 GST_OBJECT_UNLOCK (smpte);
788 GST_OBJECT_LOCK (smpte);
789 g_value_set_double (value, smpte->position);
790 GST_OBJECT_UNLOCK (smpte);
793 GST_OBJECT_LOCK (smpte);
794 g_value_set_boolean (value, smpte->invert);
795 GST_OBJECT_UNLOCK (smpte);
798 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
804 gst_smpte_alpha_plugin_init (GstPlugin * plugin)
806 GST_DEBUG_CATEGORY_INIT (gst_smpte_alpha_debug, "smptealpha", 0,
807 "SMPTE alpha effect");
809 return gst_element_register (plugin, "smptealpha", GST_RANK_NONE,
810 GST_TYPE_SMPTE_ALPHA);