diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-04-16 17:27:02 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-04-29 19:28:18 +0200 |
commit | 055c90359a6932bf548f73a9eba6ef8f9807d2e5 (patch) | |
tree | 40726bf6262cb0b007b1d0620155f9084a4c29b7 /gst/smpte | |
parent | 56d4230b22a761db62dfc5c964205c47cd573a31 (diff) |
smptealpha: Make color format support more generic
This allows easier addition of new formats later.
Diffstat (limited to 'gst/smpte')
-rw-r--r-- | gst/smpte/gstsmptealpha.c | 74 | ||||
-rw-r--r-- | 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 e25650fcd..cd91e842b 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 18e2cdea2..efa599aad 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 { |