smptealpha: Make color format support more generic

This allows easier addition of new formats later.
This commit is contained in:
Sebastian Dröge 2010-04-16 17:27:02 +02:00
parent 56d4230b22
commit 055c90359a
2 changed files with 53 additions and 27 deletions

View file

@ -148,6 +148,14 @@ static gboolean gst_smpte_alpha_get_unit_size (GstBaseTransform * btrans,
static GstFlowReturn gst_smpte_alpha_transform (GstBaseTransform * trans, static GstFlowReturn gst_smpte_alpha_transform (GstBaseTransform * trans,
GstBuffer * in, GstBuffer * out); 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_BOILERPLATE (GstSMPTEAlpha, gst_smpte_alpha, GstVideoFilter,
GST_TYPE_VIDEO_FILTER); GST_TYPE_VIDEO_FILTER);
@ -260,7 +268,12 @@ gst_smpte_alpha_setcaps (GstBaseTransform * btrans, GstCaps * incaps,
gboolean ret; gboolean ret;
gint width, height; 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; goto invalid_caps;
/* try to update the mask now, this will also adjust the width/height on /* 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) if (!ret)
goto mask_failed; 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; return ret;
/* ERRORS */ /* ERRORS */
@ -324,11 +354,12 @@ gst_smpte_alpha_finalize (GstSMPTEAlpha * smpte)
} }
static void static void
gst_smpte_alpha_do_ayuv (GstSMPTEAlpha * smpte, guint8 * in, guint8 * out, gst_smpte_alpha_process_ayuv_ayuv (GstSMPTEAlpha * smpte, const guint8 * in,
GstMask * mask, gint width, gint height, gint border, gint pos) guint8 * out, GstMask * mask, gint width, gint height, gint border,
gint pos)
{ {
gint i, j; gint i, j;
guint32 *maskp; const guint32 *maskp;
gint value; gint value;
gint min, max; gint min, max;
@ -356,17 +387,18 @@ gst_smpte_alpha_do_ayuv (GstSMPTEAlpha * smpte, guint8 * in, guint8 * out,
} }
static void static void
gst_smpte_alpha_do_i420 (GstSMPTEAlpha * smpte, guint8 * in, guint8 * out, gst_smpte_alpha_process_i420_ayuv (GstSMPTEAlpha * smpte, const guint8 * in,
GstMask * mask, gint width, gint height, gint border, gint pos) guint8 * out, GstMask * mask, gint width, gint height, gint border,
gint pos)
{ {
guint8 *srcY; const guint8 *srcY;
guint8 *srcU; const guint8 *srcU;
guint8 *srcV; const guint8 *srcV;
gint i, j; gint i, j;
gint src_wrap, src_uv_wrap; gint src_wrap, src_uv_wrap;
gint y_stride, uv_stride; gint y_stride, uv_stride;
gboolean odd_width; gboolean odd_width;
guint32 *maskp; const guint32 *maskp;
gint value; gint value;
gint min, max; gint min, max;
@ -435,6 +467,9 @@ gst_smpte_alpha_transform (GstBaseTransform * trans, GstBuffer * in,
gdouble position; gdouble position;
gint border; gint border;
if (G_UNLIKELY (!smpte->process))
goto not_negotiated;
/* first sync the controller to the current stream_time of the buffer */ /* first sync the controller to the current stream_time of the buffer */
timestamp = GST_BUFFER_TIMESTAMP (in); timestamp = GST_BUFFER_TIMESTAMP (in);
stream_time = stream_time =
@ -454,22 +489,9 @@ gst_smpte_alpha_transform (GstBaseTransform * trans, GstBuffer * in,
GST_OBJECT_UNLOCK (smpte); GST_OBJECT_UNLOCK (smpte);
/* run the type specific filter code */ /* run the type specific filter code */
switch (smpte->format) { smpte->process (smpte, GST_BUFFER_DATA (in), GST_BUFFER_DATA (out),
case GST_VIDEO_FORMAT_I420: smpte->mask, smpte->width, smpte->height, border,
gst_smpte_alpha_do_i420 (smpte, GST_BUFFER_DATA (in), ((1 << smpte->depth) + border) * position);
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;
}
return GST_FLOW_OK; return GST_FLOW_OK;

View file

@ -55,12 +55,16 @@ struct _GstSMPTEAlpha {
gboolean invert; gboolean invert;
/* negotiated format */ /* negotiated format */
GstVideoFormat format; GstVideoFormat in_format, out_format;
gint width; gint width;
gint height; gint height;
/* state of the effect */ /* state of the effect */
GstMask *mask; 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 { struct _GstSMPTEAlphaClass {