From b893197317709282e7668ce464c9dd3efcf6ecc1 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 16 Oct 2012 13:12:21 +0200 Subject: [PATCH] media: port to 1.0 --- configure.ac | 2 + gst/median/Makefile.am | 21 ++- gst/median/gstmedian.c | 329 +++++++++++++++-------------------------- gst/median/gstmedian.h | 17 +-- 4 files changed, 145 insertions(+), 224 deletions(-) diff --git a/configure.ac b/configure.ac index e557cf4d04..eee6766c0d 100644 --- a/configure.ac +++ b/configure.ac @@ -326,6 +326,7 @@ AG_GST_CHECK_PLUGIN(isomp4) AG_GST_CHECK_PLUGIN(law) AG_GST_CHECK_PLUGIN(level) AG_GST_CHECK_PLUGIN(matroska) +AG_GST_CHECK_PLUGIN(median) AG_GST_CHECK_PLUGIN(monoscope) AG_GST_CHECK_PLUGIN(multifile) AG_GST_CHECK_PLUGIN(multipart) @@ -1082,6 +1083,7 @@ gst/isomp4/Makefile gst/law/Makefile gst/level/Makefile gst/matroska/Makefile +gst/median/Makefile gst/monoscope/Makefile gst/multifile/Makefile gst/multipart/Makefile diff --git a/gst/median/Makefile.am b/gst/median/Makefile.am index 32f9d829a9..e0b55caf84 100644 --- a/gst/median/Makefile.am +++ b/gst/median/Makefile.am @@ -1,10 +1,25 @@ plugin_LTLIBRARIES = libgstmedian.la libgstmedian_la_SOURCES = gstmedian.c - -libgstmedian_la_CFLAGS = $(GST_CFLAGS) -libgstmedian_la_LIBADD = $(GST_LIBS) +libgstmedian_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_BASE_CFLAGS) $(GST_CFLAGS) +libgstmedian_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \ + $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) libgstmedian_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstmedian_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = gstmedian.h + +Android.mk: Makefile.am $(BUILT_SOURCES) + androgenizer \ + -:PROJECT libgstmedian -:SHARED libgstmedian \ + -:TAGS eng debug \ + -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ + -:SOURCES $(libgstmedian_la_SOURCES) \ + -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmedian_la_CFLAGS) \ + -:LDFLAGS $(libgstmedian_la_LDFLAGS) \ + $(libgstmedian_la_LIBADD) \ + -ldl \ + -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ + LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-1.0' \ + > $@ diff --git a/gst/median/gstmedian.c b/gst/median/gstmedian.c index 3f02cbd839..d2ba86b419 100644 --- a/gst/median/gstmedian.c +++ b/gst/median/gstmedian.c @@ -27,14 +27,14 @@ static GstStaticPadTemplate median_src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")) + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420")) ); static GstStaticPadTemplate median_sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")) + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420")) ); @@ -47,135 +47,71 @@ enum enum { - ARG_0, - ARG_ACTIVE, - ARG_FILTERSIZE, - ARG_LUM_ONLY + PROP_0, + PROP_ACTIVE, + PROP_FILTERSIZE, + PROP_LUM_ONLY }; -static GType gst_median_get_type (void); -static void gst_median_class_init (GstMedianClass * klass); -static void gst_median_base_init (GstMedianClass * klass); -static void gst_median_init (GstMedian * median); +#define gst_median_parent_class parent_class +G_DEFINE_TYPE (GstMedian, gst_median, GST_TYPE_VIDEO_FILTER); -static void median_5 (unsigned char *src, unsigned char *dest, int height, - int width); +static void median_5 (guint8 * src, gint sstride, const guint8 * dest, + gint dstride, gint width, gint height); +#if 0 static void median_9 (unsigned char *src, unsigned char *dest, int height, int width); -static void gst_median_chain (GstPad * pad, GstData * _data); +#endif + +static GstFlowReturn gst_median_transform_frame (GstVideoFilter * filter, + GstVideoFrame * in_frame, GstVideoFrame * out_frame); static void gst_median_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_median_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstElementClass *parent_class = NULL; - -/*static guint gst_median_signals[LAST_SIGNAL] = { 0 }; */ - -GType -gst_median_get_type (void) -{ - static GType median_type = 0; - - if (!median_type) { - static const GTypeInfo median_info = { - sizeof (GstMedianClass), - (GBaseInitFunc) gst_median_base_init, - NULL, - (GClassInitFunc) gst_median_class_init, - NULL, - NULL, - sizeof (GstMedian), - 0, - (GInstanceInitFunc) gst_median_init, - }; - - median_type = - g_type_register_static (GST_TYPE_ELEMENT, "GstMedian", &median_info, 0); - } - return median_type; -} - -static void -gst_median_base_init (GstMedianClass * klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&median_sink_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&median_src_factory)); - gst_element_class_set_static_metadata (element_class, "Median effect", - "Filter/Effect/Video", - "Apply a median filter to an image", - "Wim Taymans "); -} - static void gst_median_class_init (GstMedianClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; + GstVideoFilterClass *vfilter_class; gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - /* FIXME: add long property descriptions */ - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACTIVE, - g_param_spec_boolean ("active", "active", "active", TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILTERSIZE, - g_param_spec_int ("filtersize", "filtersize", "filtersize", G_MININT, - G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LUM_ONLY, - g_param_spec_boolean ("lum-only", "lum-only", "lum-only", TRUE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + vfilter_class = (GstVideoFilterClass *) klass; gobject_class->set_property = gst_median_set_property; gobject_class->get_property = gst_median_get_property; -} -static gboolean -gst_median_link (GstPad * pad, const GstCaps * caps) -{ - GstMedian *filter = GST_MEDIAN (gst_pad_get_parent (pad)); - GstPad *otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; - GstStructure *structure = gst_caps_get_structure (caps, 0); - gint w, h; - GstPadLinkReturn ret; + /* FIXME: add long property descriptions */ + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ACTIVE, + g_param_spec_boolean ("active", "active", "active", TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FILTERSIZE, + g_param_spec_int ("filtersize", "filtersize", "filtersize", G_MININT, + G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LUM_ONLY, + g_param_spec_boolean ("lum-only", "lum-only", "lum-only", TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - gst_structure_get_int (structure, "width", &w); - gst_structure_get_int (structure, "height", &h); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&median_sink_factory)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&median_src_factory)); + gst_element_class_set_static_metadata (gstelement_class, "Median effect", + "Filter/Effect/Video", + "Apply a median filter to an image", + "Wim Taymans "); - ret = gst_pad_try_set_caps (otherpad, caps); - if (GST_PAD_LINK_SUCCESSFUL (ret)) { - filter->width = w; - filter->height = h; - } - - gst_object_unref (filter); - - return ret; + vfilter_class->transform_frame = + GST_DEBUG_FUNCPTR (gst_median_transform_frame); } void gst_median_init (GstMedian * median) { - median->sinkpad = - gst_pad_new_from_static_template (&media_sink_factory, "sink"); - gst_pad_set_getcaps_function (median->sinkpad, gst_pad_proxy_getcaps); - gst_pad_set_link_function (median->sinkpad, gst_median_link); - gst_pad_set_chain_function (median->sinkpad, gst_median_chain); - gst_element_add_pad (GST_ELEMENT (median), median->sinkpad); - - median->srcpad = gst_pad_new_from_static_template (&media_src_factory, "src"); - gst_pad_set_getcaps_function (median->srcpad, gst_pad_proxy_getcaps); - gst_pad_set_link_function (median->sinkpad, gst_median_link); - gst_element_add_pad (GST_ELEMENT (median), median->srcpad); - median->filtersize = 5; median->lum_only = TRUE; median->active = TRUE; @@ -185,35 +121,30 @@ gst_median_init (GstMedian * median) #define PIX_SWAP(a,b) { unsigned char temp=(a);(a)=(b);(b)=temp; } static void -median_5 (unsigned char *src, unsigned char *dest, int width, int height) +median_5 (guint8 * dest, gint dstride, const guint8 * src, gint sstride, + gint width, gint height) { - int nLastRow; - int nLastCol; - unsigned char p[9]; + unsigned char p[5]; int i, j, k; - nLastCol = width - 1; - nLastRow = height - 1; - - /*copy the top and bottom rows into the result array */ + /* copy the top and bottom rows into the result array */ for (i = 0; i < width; i++) { dest[i] = src[i]; - dest[nLastRow * width + i] = src[nLastRow * width + i]; + dest[(height - 1) * dstride + i] = src[(height - 1) * sstride + i]; } - dest[i] = src[i]; - - nLastCol--; - nLastRow--; /* process the interior pixels */ - i = width + 1; - for (k = 0; k < nLastRow; k++) { - for (j = 0; j < nLastCol; j++, i++) { - p[0] = src[i - width]; + for (k = 2; k < height; k++) { + dest += dstride; + src += sstride; + + dest[0] = src[0]; + for (j = 2, i = 1; j < width; j++, i++) { + p[0] = src[i - sstride]; p[1] = src[i - 1]; p[2] = src[i]; p[3] = src[i + 1]; - p[4] = src[i + width]; + p[4] = src[i + sstride]; PIX_SORT (p[0], p[1]); PIX_SORT (p[3], p[4]); PIX_SORT (p[0], p[3]); @@ -224,48 +155,37 @@ median_5 (unsigned char *src, unsigned char *dest, int width, int height) dest[i] = p[2]; } dest[i] = src[i]; - i++; - dest[i] = src[i]; - i++; } - dest[i] = src[i]; - i++; } static void -median_9 (unsigned char *src, unsigned char *dest, int width, int height) +median_9 (guint8 * dest, gint dstride, const guint8 * src, gint sstride, + gint width, gint height) { - int nLastRow; - int nLastCol; unsigned char p[9]; int i, j, k; - nLastCol = width - 1; - nLastRow = height - 1; - /*copy the top and bottom rows into the result array */ for (i = 0; i < width; i++) { dest[i] = src[i]; - dest[nLastRow * width + i] = src[nLastRow * width + i]; + dest[(height - 1) * dstride + i] = src[(height - 1) * sstride + i]; } - dest[i] = src[i]; - - nLastCol--; - nLastRow--; - /* process the interior pixels */ - i = width + 1; - for (k = 0; k < nLastRow; k++) { - for (j = 0; j < nLastCol; j++, i++) { - p[0] = src[i - width - 1]; - p[1] = src[i - width]; - p[2] = src[i - width + 1]; + for (k = 2; k < height; k++) { + dest += dstride; + src += sstride; + + dest[0] = src[0]; + for (j = 2, i = 1; j < width; j++, i++) { + p[0] = src[i - sstride - 1]; + p[1] = src[i - sstride]; + p[2] = src[i - sstride + 1]; p[3] = src[i - 1]; p[4] = src[i]; p[5] = src[i + 1]; - p[6] = src[i + width - 1]; - p[7] = src[i + width]; - p[8] = src[i + width + 1]; + p[6] = src[i + sstride - 1]; + p[7] = src[i + sstride]; + p[8] = src[i + sstride + 1]; PIX_SORT (p[1], p[2]); PIX_SORT (p[4], p[5]); PIX_SORT (p[7], p[8]); @@ -288,79 +208,66 @@ median_9 (unsigned char *src, unsigned char *dest, int width, int height) dest[i] = p[4]; } dest[i] = src[i]; - i++; - dest[i] = src[i]; - i++; } - dest[i] = src[i]; - i++; } -static void -gst_median_chain (GstPad * pad, GstData * _data) +static GstFlowReturn +gst_median_transform_frame (GstVideoFilter * filter, GstVideoFrame * in_frame, + GstVideoFrame * out_frame) { - GstBuffer *buf = GST_BUFFER (_data); - GstMedian *median; - guchar *data; - gulong size; - GstBuffer *outbuf; - -/* GstMeta *meta; */ - int lumsize, chromsize; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - median = GST_MEDIAN (GST_OBJECT_PARENT (pad)); - - if (!median->active) { - gst_pad_push (median->srcpad, GST_DATA (buf)); - return; - } - - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); - - GST_DEBUG ("median: have buffer of %d", GST_BUFFER_SIZE (buf)); - - outbuf = gst_buffer_new (); - GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (buf)); - GST_BUFFER_SIZE (outbuf) = GST_BUFFER_SIZE (buf); - - lumsize = median->width * median->height; - chromsize = lumsize / 4; + GstMedian *median = GST_MEDIAN (filter); if (median->filtersize == 5) { - median_5 (data, GST_BUFFER_DATA (outbuf), median->width, median->height); - if (!median->lum_only) { - median_5 (data + lumsize, GST_BUFFER_DATA (outbuf) + lumsize, - median->width / 2, median->height / 2); - median_5 (data + lumsize + chromsize, - GST_BUFFER_DATA (outbuf) + lumsize + chromsize, median->width / 2, - median->height / 2); + median_5 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0), + GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0), + GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0), + GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0), + GST_VIDEO_FRAME_WIDTH (in_frame), GST_VIDEO_FRAME_HEIGHT (in_frame)); + + if (median->lum_only) { + gst_video_frame_copy_plane (out_frame, in_frame, 1); + gst_video_frame_copy_plane (out_frame, in_frame, 2); } else { - memcpy (GST_BUFFER_DATA (outbuf) + lumsize, data + lumsize, - chromsize * 2); + median_5 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 1), + GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 1), + GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1), + GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1), + GST_VIDEO_FRAME_WIDTH (in_frame) / 2, + GST_VIDEO_FRAME_HEIGHT (in_frame) / 2); + median_5 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 2), + GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 2), + GST_VIDEO_FRAME_PLANE_DATA (in_frame, 2), + GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 2), + GST_VIDEO_FRAME_WIDTH (in_frame) / 2, + GST_VIDEO_FRAME_HEIGHT (in_frame) / 2); } } else { - median_9 (data, GST_BUFFER_DATA (outbuf), median->width, median->height); - if (!median->lum_only) { - median_9 (data + lumsize, GST_BUFFER_DATA (outbuf) + lumsize, - median->width / 2, median->height / 2); - median_9 (data + lumsize + chromsize, - GST_BUFFER_DATA (outbuf) + lumsize + chromsize, median->width / 2, - median->height / 2); + median_9 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0), + GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0), + GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0), + GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0), + GST_VIDEO_FRAME_WIDTH (in_frame), GST_VIDEO_FRAME_HEIGHT (in_frame)); + + if (median->lum_only) { + gst_video_frame_copy_plane (out_frame, in_frame, 1); + gst_video_frame_copy_plane (out_frame, in_frame, 2); } else { - memcpy (GST_BUFFER_DATA (outbuf) + lumsize, data + lumsize, - chromsize * 2); + median_9 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 1), + GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 1), + GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1), + GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1), + GST_VIDEO_FRAME_WIDTH (in_frame) / 2, + GST_VIDEO_FRAME_HEIGHT (in_frame) / 2); + median_9 (GST_VIDEO_FRAME_PLANE_DATA (out_frame, 2), + GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 2), + GST_VIDEO_FRAME_PLANE_DATA (in_frame, 2), + GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 2), + GST_VIDEO_FRAME_WIDTH (in_frame) / 2, + GST_VIDEO_FRAME_HEIGHT (in_frame) / 2); } } - GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); - gst_buffer_unref (buf); - - gst_pad_push (median->srcpad, GST_DATA (outbuf)); + return GST_FLOW_OK; } static void @@ -374,7 +281,7 @@ gst_median_set_property (GObject * object, guint prop_id, const GValue * value, median = GST_MEDIAN (object); switch (prop_id) { - case ARG_FILTERSIZE: + case PROP_FILTERSIZE: argvalue = g_value_get_int (value); if (argvalue != 5 && argvalue != 9) { g_warning ("median: invalid filtersize (%d), must be 5 or 9\n", @@ -383,10 +290,10 @@ gst_median_set_property (GObject * object, guint prop_id, const GValue * value, median->filtersize = argvalue; } break; - case ARG_ACTIVE: + case PROP_ACTIVE: median->active = g_value_get_boolean (value); break; - case ARG_LUM_ONLY: + case PROP_LUM_ONLY: median->lum_only = g_value_get_boolean (value); break; default: @@ -404,13 +311,13 @@ gst_median_get_property (GObject * object, guint prop_id, GValue * value, median = GST_MEDIAN (object); switch (prop_id) { - case ARG_FILTERSIZE: + case PROP_FILTERSIZE: g_value_set_int (value, median->filtersize); break; - case ARG_ACTIVE: + case PROP_ACTIVE: g_value_set_boolean (value, median->active); break; - case ARG_LUM_ONLY: + case PROP_LUM_ONLY: g_value_set_boolean (value, median->lum_only); break; default: diff --git a/gst/median/gstmedian.h b/gst/median/gstmedian.h index bd9808086c..50b01ae14f 100644 --- a/gst/median/gstmedian.h +++ b/gst/median/gstmedian.h @@ -23,12 +23,10 @@ #include +#include +#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - +G_BEGIN_DECLS #define GST_TYPE_MEDIAN \ (gst_median_get_type()) @@ -45,7 +43,7 @@ typedef struct _GstMedian GstMedian; typedef struct _GstMedianClass GstMedianClass; struct _GstMedian { - GstElement element; + GstVideoFilter parent; int format; int width; @@ -60,12 +58,11 @@ struct _GstMedian { }; struct _GstMedianClass { - GstElementClass parent_class; + GstVideoFilterClass parent_class; }; -#ifdef __cplusplus -} -#endif /* __cplusplus */ +GType gst_median_get_type (void); +G_END_DECLS #endif /* __GST_MEDIAN_H__ */