static GstFlowReturn gst_smpte_alpha_transform_frame (GstVideoFilter * vfilter, GstVideoFrame * in_frame, GstVideoFrame * out_frame) { GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (vfilter); gdouble position; gint border; if (G_UNLIKELY (!smpte->process)) goto not_negotiated; GST_OBJECT_LOCK (smpte); position = smpte->position; border = smpte->border; /* run the type specific filter code */ smpte->process (smpte, in_frame, out_frame, smpte->mask, border, ((1 << smpte->depth) + border) * position); GST_OBJECT_UNLOCK (smpte); return GST_FLOW_OK; /* ERRORS */ not_negotiated: { GST_ELEMENT_ERROR (smpte, CORE, NEGOTIATION, (NULL), ("No input format negotiated")); return GST_FLOW_NOT_NEGOTIATED; } }
static GstFlowReturn gst_smpte_alpha_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out) { GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (trans); gdouble position; gint border; if (G_UNLIKELY (!smpte->process)) goto not_negotiated; /* these are the propertis we update with only the object lock, others are * only updated with the TRANSFORM_LOCK. */ GST_OBJECT_LOCK (smpte); position = smpte->position; border = smpte->border; GST_OBJECT_UNLOCK (smpte); /* run the type specific filter code */ smpte->process (smpte, GST_BUFFER_DATA (in), GST_BUFFER_DATA (out), smpte->mask, smpte->width, smpte->height, border, ((1 << smpte->depth) + border) * position); return GST_FLOW_OK; /* ERRORS */ not_negotiated: { GST_ELEMENT_ERROR (smpte, CORE, NEGOTIATION, (NULL), ("No input format negotiated")); return GST_FLOW_NOT_NEGOTIATED; } }
static void gst_smpte_alpha_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (object); switch (prop_id) { case PROP_TYPE:{ gint type; type = g_value_get_enum (value); GST_OBJECT_LOCK (smpte); gst_smpte_alpha_update_mask (smpte, type, smpte->invert, smpte->depth, smpte->width, smpte->height); GST_OBJECT_UNLOCK (smpte); break; } case PROP_BORDER: GST_OBJECT_LOCK (smpte); smpte->border = g_value_get_int (value); GST_OBJECT_UNLOCK (smpte); break; case PROP_DEPTH:{ gint depth; depth = g_value_get_int (value); GST_OBJECT_LOCK (smpte); gst_smpte_alpha_update_mask (smpte, smpte->type, smpte->invert, depth, smpte->width, smpte->height); GST_OBJECT_UNLOCK (smpte); break; } case PROP_POSITION: GST_OBJECT_LOCK (smpte); smpte->position = g_value_get_double (value); GST_OBJECT_UNLOCK (smpte); break; case PROP_INVERT:{ gboolean invert; invert = g_value_get_boolean (value); GST_OBJECT_LOCK (smpte); gst_smpte_alpha_update_mask (smpte, smpte->type, invert, smpte->depth, smpte->width, smpte->height); GST_OBJECT_UNLOCK (smpte); break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gst_smpte_alpha_before_transform (GstBaseTransform * trans, GstBuffer * buf) { GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (trans); GstClockTime timestamp, stream_time; /* first sync the controller to the current stream_time of the buffer */ timestamp = GST_BUFFER_TIMESTAMP (buf); stream_time = gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp); GST_DEBUG_OBJECT (smpte, "sync to %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp)); if (GST_CLOCK_TIME_IS_VALID (stream_time)) gst_object_sync_values (GST_OBJECT (smpte), stream_time); }
static void gst_smpte_alpha_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstSMPTEAlpha *smpte; smpte = GST_SMPTE_ALPHA (object); switch (prop_id) { case PROP_TYPE: GST_OBJECT_LOCK (smpte); g_value_set_enum (value, smpte->type); GST_OBJECT_UNLOCK (smpte); break; case PROP_BORDER: GST_OBJECT_LOCK (smpte); g_value_set_int (value, smpte->border); GST_OBJECT_UNLOCK (smpte); break; case PROP_DEPTH: GST_OBJECT_LOCK (smpte); g_value_set_int (value, smpte->depth); GST_OBJECT_UNLOCK (smpte); break; case PROP_POSITION: GST_OBJECT_LOCK (smpte); 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; } }
static gboolean gst_smpte_alpha_set_info (GstVideoFilter * vfilter, GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info) { GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (vfilter); gboolean ret; gint width, height; smpte->process = NULL; smpte->in_format = GST_VIDEO_INFO_FORMAT (in_info); smpte->out_format = GST_VIDEO_INFO_FORMAT (out_info); smpte->width = width = GST_VIDEO_INFO_WIDTH (out_info); smpte->height = height = GST_VIDEO_INFO_HEIGHT (out_info); /* 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->invert, smpte->depth, width, height); GST_OBJECT_UNLOCK (smpte); if (!ret) goto mask_failed; switch (smpte->out_format) { case GST_VIDEO_FORMAT_AYUV: switch (smpte->in_format) { case GST_VIDEO_FORMAT_AYUV: smpte->process = gst_smpte_alpha_process_ayuv_ayuv; break; case GST_VIDEO_FORMAT_I420: smpte->process = gst_smpte_alpha_process_i420_ayuv; break; default: break; } break; case GST_VIDEO_FORMAT_ARGB: switch (smpte->in_format) { case GST_VIDEO_FORMAT_ARGB: smpte->process = gst_smpte_alpha_process_argb_argb; break; default: break; } break; case GST_VIDEO_FORMAT_RGBA: switch (smpte->in_format) { case GST_VIDEO_FORMAT_RGBA: smpte->process = gst_smpte_alpha_process_rgba_rgba; break; default: break; } break; case GST_VIDEO_FORMAT_ABGR: switch (smpte->in_format) { case GST_VIDEO_FORMAT_ABGR: smpte->process = gst_smpte_alpha_process_abgr_abgr; break; default: break; } break; case GST_VIDEO_FORMAT_BGRA: switch (smpte->in_format) { case GST_VIDEO_FORMAT_BGRA: smpte->process = gst_smpte_alpha_process_bgra_bgra; break; default: break; } break; default: break; } return ret; /* ERRORS */ mask_failed: { GST_ERROR_OBJECT (smpte, "failed creating the mask"); return FALSE; } }
static gboolean gst_smpte_alpha_setcaps (GstBaseTransform * btrans, GstCaps * incaps, GstCaps * outcaps) { GstSMPTEAlpha *smpte = GST_SMPTE_ALPHA (btrans); gboolean ret; gint width, height; smpte->process = NULL; if (!gst_video_format_parse_caps (incaps, &smpte->in_format, &width, &height)) goto invalid_caps; if (!gst_video_format_parse_caps (outcaps, &smpte->out_format, &width, &height)) goto invalid_caps; /* 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->invert, smpte->depth, width, height); GST_OBJECT_UNLOCK (smpte); if (!ret) goto mask_failed; switch (smpte->out_format) { case GST_VIDEO_FORMAT_AYUV: switch (smpte->in_format) { case GST_VIDEO_FORMAT_AYUV: smpte->process = gst_smpte_alpha_process_ayuv_ayuv; break; case GST_VIDEO_FORMAT_I420: smpte->process = gst_smpte_alpha_process_i420_ayuv; break; default: break; } break; case GST_VIDEO_FORMAT_ARGB: switch (smpte->in_format) { case GST_VIDEO_FORMAT_ARGB: smpte->process = gst_smpte_alpha_process_argb_argb; break; default: break; } break; case GST_VIDEO_FORMAT_RGBA: switch (smpte->in_format) { case GST_VIDEO_FORMAT_RGBA: smpte->process = gst_smpte_alpha_process_rgba_rgba; break; default: break; } break; case GST_VIDEO_FORMAT_ABGR: switch (smpte->in_format) { case GST_VIDEO_FORMAT_ABGR: smpte->process = gst_smpte_alpha_process_abgr_abgr; break; default: break; } break; case GST_VIDEO_FORMAT_BGRA: switch (smpte->in_format) { case GST_VIDEO_FORMAT_BGRA: smpte->process = gst_smpte_alpha_process_bgra_bgra; break; default: break; } break; default: break; } return ret; /* ERRORS */ invalid_caps: { GST_ERROR_OBJECT (smpte, "Invalid caps: %" GST_PTR_FORMAT, incaps); return FALSE; } mask_failed: { GST_ERROR_OBJECT (smpte, "failed creating the mask"); return FALSE; } }