summaryrefslogtreecommitdiff
path: root/gst/smpte
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2010-04-16 17:27:02 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2010-04-29 19:28:18 +0200
commit055c90359a6932bf548f73a9eba6ef8f9807d2e5 (patch)
tree40726bf6262cb0b007b1d0620155f9084a4c29b7 /gst/smpte
parent56d4230b22a761db62dfc5c964205c47cd573a31 (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.c74
-rw-r--r--gst/smpte/gstsmptealpha.h6
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 {