From 055c90359a6932bf548f73a9eba6ef8f9807d2e5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 16 Apr 2010 17:27:02 +0200 Subject: [PATCH] smptealpha: Make color format support more generic This allows easier addition of new formats later. --- gst/smpte/gstsmptealpha.c | 74 ++++++++++++++++++++++++++++++----------------- gst/smpte/gstsmptealpha.h | 6 +++- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/gst/smpte/gstsmptealpha.c b/gst/smpte/gstsmptealpha.c index e25650f..cd91e84 100644 --- a/gst/smpte/gstsmptealpha.c +++ b/gst/smpte/gstsmptealpha.c @@ -148,6 +148,14 @@ static gboolean gst_smpte_alpha_get_unit_size (GstBaseTransform * btrans, static GstFlowReturn gst_smpte_alpha_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out); +static void +gst_smpte_alpha_process_i420_ayuv (GstSMPTEAlpha * smpte, const guint8 * in, + guint8 * out, GstMask * mask, gint width, gint height, gint border, + gint pos); +static void gst_smpte_alpha_process_ayuv_ayuv (GstSMPTEAlpha * smpte, + const guint8 * in, guint8 * out, GstMask * mask, gint width, gint height, + gint border, gint pos); + GST_BOILERPLATE (GstSMPTEAlpha, gst_smpte_alpha, GstVideoFilter, GST_TYPE_VIDEO_FILTER); @@ -260,7 +268,12 @@ gst_smpte_alpha_setcaps (GstBaseTransform * btrans, GstCaps * incaps, gboolean ret; gint width, height; - if (!gst_video_format_parse_caps (incaps, &smpte->format, &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 @@ -273,6 +286,23 @@ gst_smpte_alpha_setcaps (GstBaseTransform * btrans, GstCaps * incaps, 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; + default: + break; + } + return ret; /* ERRORS */ @@ -324,11 +354,12 @@ gst_smpte_alpha_finalize (GstSMPTEAlpha * smpte) } static void -gst_smpte_alpha_do_ayuv (GstSMPTEAlpha * smpte, guint8 * in, guint8 * out, - GstMask * mask, gint width, gint height, gint border, gint pos) +gst_smpte_alpha_process_ayuv_ayuv (GstSMPTEAlpha * smpte, const guint8 * in, + guint8 * out, GstMask * mask, gint width, gint height, gint border, + gint pos) { gint i, j; - guint32 *maskp; + const guint32 *maskp; gint value; gint min, max; @@ -356,17 +387,18 @@ gst_smpte_alpha_do_ayuv (GstSMPTEAlpha * smpte, guint8 * in, guint8 * out, } static void -gst_smpte_alpha_do_i420 (GstSMPTEAlpha * smpte, guint8 * in, guint8 * out, - GstMask * mask, gint width, gint height, gint border, gint pos) +gst_smpte_alpha_process_i420_ayuv (GstSMPTEAlpha * smpte, const guint8 * in, + guint8 * out, GstMask * mask, gint width, gint height, gint border, + gint pos) { - guint8 *srcY; - guint8 *srcU; - guint8 *srcV; + const guint8 *srcY; + const guint8 *srcU; + const guint8 *srcV; gint i, j; gint src_wrap, src_uv_wrap; gint y_stride, uv_stride; gboolean odd_width; - guint32 *maskp; + const guint32 *maskp; gint value; gint min, max; @@ -435,6 +467,9 @@ gst_smpte_alpha_transform (GstBaseTransform * trans, GstBuffer * in, gdouble position; gint border; + if (G_UNLIKELY (!smpte->process)) + goto not_negotiated; + /* first sync the controller to the current stream_time of the buffer */ timestamp = GST_BUFFER_TIMESTAMP (in); stream_time = @@ -454,22 +489,9 @@ gst_smpte_alpha_transform (GstBaseTransform * trans, GstBuffer * in, GST_OBJECT_UNLOCK (smpte); /* run the type specific filter code */ - switch (smpte->format) { - case GST_VIDEO_FORMAT_I420: - gst_smpte_alpha_do_i420 (smpte, GST_BUFFER_DATA (in), - GST_BUFFER_DATA (out), - smpte->mask, smpte->width, smpte->height, - border, ((1 << smpte->depth) + border) * position); - break; - case GST_VIDEO_FORMAT_AYUV: - gst_smpte_alpha_do_ayuv (smpte, GST_BUFFER_DATA (in), - GST_BUFFER_DATA (out), - smpte->mask, smpte->width, smpte->height, - border, ((1 << smpte->depth) + border) * position); - break; - default: - goto not_negotiated; - } + 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; diff --git a/gst/smpte/gstsmptealpha.h b/gst/smpte/gstsmptealpha.h index 18e2cde..efa599a 100644 --- a/gst/smpte/gstsmptealpha.h +++ b/gst/smpte/gstsmptealpha.h @@ -55,12 +55,16 @@ struct _GstSMPTEAlpha { gboolean invert; /* negotiated format */ - GstVideoFormat format; + GstVideoFormat in_format, out_format; gint width; gint height; /* state of the effect */ GstMask *mask; + + /* processing function */ + void (*process) (GstSMPTEAlpha * smpte, const guint8 * in, guint8 * out, + GstMask * mask, gint width, gint height, gint border, gint pos); }; struct _GstSMPTEAlphaClass { -- 2.7.4