From 685b2025416d94ddd112bcb9c55b0d4bc48811e4 Mon Sep 17 00:00:00 2001 From: "Joshua M. Doe" Date: Thu, 10 Oct 2019 07:49:56 -0400 Subject: [PATCH] select: new filter to drop frames based on offset and skip Motivation was to select only odd or even frames. --- gst/CMakeLists.txt | 1 + gst/select/CMakeLists.txt | 28 ++++ gst/select/gstselect.c | 265 ++++++++++++++++++++++++++++++++++++++ gst/select/gstselect.h | 71 ++++++++++ 4 files changed, 365 insertions(+) create mode 100644 gst/select/CMakeLists.txt create mode 100644 gst/select/gstselect.c create mode 100644 gst/select/gstselect.h diff --git a/gst/CMakeLists.txt b/gst/CMakeLists.txt index accf79e..ba625a1 100644 --- a/gst/CMakeLists.txt +++ b/gst/CMakeLists.txt @@ -4,4 +4,5 @@ endif (OPENCV_FOUND) add_subdirectory (extractcolor) add_subdirectory (misb) +add_subdirectory (select) add_subdirectory (videoadjust) diff --git a/gst/select/CMakeLists.txt b/gst/select/CMakeLists.txt new file mode 100644 index 0000000..f35996e --- /dev/null +++ b/gst/select/CMakeLists.txt @@ -0,0 +1,28 @@ +set (SOURCES + gstselect.c + ) + +set (HEADERS + gstselect.h) + +include_directories (AFTER + ${ORC_INCLUDE_DIR}) + +set (libname libgstselect) + +add_library (${libname} MODULE + ${SOURCES} + ${HEADERS}) + +target_link_libraries (${libname} + ${ORC_LIBRARIES} + ${GLIB2_LIBRARIES} + ${GOBJECT_LIBRARIES} + ${GSTREAMER_LIBRARY} + ${GSTREAMER_BASE_LIBRARY} + ${GSTREAMER_VIDEO_LIBRARY}) + +set (pdbfile "${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/${libname}.pdb") +install (FILES ${pdbfile} DESTINATION lib/gstreamer-1.0 COMPONENT pdb) +install(TARGETS ${libname} + LIBRARY DESTINATION lib/gstreamer-1.0) diff --git a/gst/select/gstselect.c b/gst/select/gstselect.c new file mode 100644 index 0000000..1847c37 --- /dev/null +++ b/gst/select/gstselect.c @@ -0,0 +1,265 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) <2003> David Schleef + * Copyright (C) 2003 Arwed v. Merkatz + * Copyright (C) 2006 Mark Nauwelaerts + * Copyright (C) 2015 United States Government, Joshua M. Doe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** +* SECTION:element-select +* +* Selects buffers from offset and skip. +* +* +* Example launch line +* |[ +* gst-launch videotestsrc ! select ! autovideosink +* ]| +* +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstselect.h" + +enum +{ + PROP_0, + PROP_OFFSET, + PROP_SKIP, + PROP_LAST +}; + +#define DEFAULT_PROP_OFFSET 0 +#define DEFAULT_PROP_SKIP 0 + +/* the capabilities of the inputs and outputs */ +static GstStaticPadTemplate gst_select_sink_template = +GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("ANY") + ); + +static GstStaticPadTemplate gst_select_src_template = +GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("ANY") + ); + + +/* GObject vmethod declarations */ +static void gst_select_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_select_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static void gst_select_dispose (GObject * object); + +/* GstBaseTransform vmethod declarations */ +static GstFlowReturn gst_select_transform_ip (GstBaseTransform * trans, + GstBuffer * buf); + +/* GstSelect method declarations */ +static void gst_select_reset (GstSelect * filter); + +/* setup debug */ +GST_DEBUG_CATEGORY_STATIC (select_debug); +#define GST_CAT_DEFAULT select_debug + +G_DEFINE_TYPE (GstSelect, gst_select, GST_TYPE_BASE_TRANSFORM); + +/************************************************************************/ +/* GObject vmethod implementations */ +/************************************************************************/ + +/** + * gst_select_dispose: + * @object: #GObject. + * + */ +static void +gst_select_dispose (GObject * object) +{ + GstSelect *select = GST_SELECT (object); + + GST_DEBUG ("dispose"); + + gst_select_reset (select); + + /* chain up to the parent class */ + G_OBJECT_CLASS (gst_select_parent_class)->dispose (object); +} + +/** + * gst_select_class_init: + * @object: #GstSelectClass. + * + */ +static void +gst_select_class_init (GstSelectClass * klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); + GstBaseTransformClass *gstbasetransform_class = + GST_BASE_TRANSFORM_CLASS (klass); + + GST_DEBUG_CATEGORY_INIT (select_debug, "select", 0, "Video Levels Filter"); + + GST_DEBUG ("class init"); + + /* Register GObject vmethods */ + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_select_dispose); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_select_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_select_get_property); + + /* Install GObject properties */ + g_object_class_install_property (gobject_class, PROP_OFFSET, + g_param_spec_int ("offset", "Buffer offset", + "First buffer offset to pass", 0, G_MAXINT, DEFAULT_PROP_OFFSET, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | + GST_PARAM_MUTABLE_PLAYING)); + g_object_class_install_property (gobject_class, PROP_SKIP, + g_param_spec_int ("skip", "Buffers to skip", "Number of buffers to skip", + 0, G_MAXINT, DEFAULT_PROP_OFFSET, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | + GST_PARAM_MUTABLE_PLAYING)); + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_select_sink_template)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&gst_select_src_template)); + + gst_element_class_set_static_metadata (gstelement_class, + "Select buffer filter", "Filter/Effect", + "Selects buffers based on buffer offset", + "Joshua M. Doe "); + + /* Register GstBaseTransform vmethods */ + gstbasetransform_class->transform_ip = + GST_DEBUG_FUNCPTR (gst_select_transform_ip); +} + +static void +gst_select_init (GstSelect * trans) +{ + GST_DEBUG_OBJECT (trans, "init class instance"); + + trans->offset = DEFAULT_PROP_OFFSET; + trans->skip = DEFAULT_PROP_SKIP; + + gst_base_transform_set_in_place (GST_BASE_TRANSFORM (trans), TRUE); + + gst_select_reset (trans); +} + +static void +gst_select_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstSelect *filt = GST_SELECT (object); + + GST_DEBUG_OBJECT (filt, "setting property %s", pspec->name); + + switch (prop_id) { + case PROP_OFFSET: + filt->offset = g_value_get_int (value); + break; + case PROP_SKIP: + filt->skip = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_select_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstSelect *filt = GST_SELECT (object); + + GST_DEBUG_OBJECT (filt, "getting property %s", pspec->name); + + switch (prop_id) { + case PROP_OFFSET: + g_value_set_int (value, filt->offset); + break; + case PROP_SKIP: + g_value_set_int (value, filt->skip); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstFlowReturn +gst_select_transform_ip (GstBaseTransform * trans, GstBuffer * buf) +{ + GstSelect *filt = GST_SELECT (trans); + guint64 buf_offset = GST_BUFFER_OFFSET (buf); + + if (buf_offset < filt->offset) { + GST_LOG_OBJECT (filt, + "Dropping buffer %d since it's before the chosen offset %d", + buf_offset, filt->offset); + return GST_BASE_TRANSFORM_FLOW_DROPPED; + } + + if ((filt->offset - buf_offset) % (filt->skip + 1)) { + GST_LOG_OBJECT (filt, + "Dropping buffer %d since it's been chosen to be skipped", buf_offset); + return GST_BASE_TRANSFORM_FLOW_DROPPED; + } + + return GST_FLOW_OK; +} + + +static void +gst_select_reset (GstSelect * filt) +{ +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "select", 0, "select"); + + GST_DEBUG ("plugin_init"); + + GST_CAT_INFO (GST_CAT_DEFAULT, "registering select element"); + + if (!gst_element_register (plugin, "select", GST_RANK_NONE, GST_TYPE_SELECT)) { + return FALSE; + } + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + select, + "Filter that selects which buffers to pass", + plugin_init, GST_PACKAGE_VERSION, GST_PACKAGE_LICENSE, GST_PACKAGE_NAME, + GST_PACKAGE_ORIGIN); diff --git a/gst/select/gstselect.h b/gst/select/gstselect.h new file mode 100644 index 0000000..6805a0c --- /dev/null +++ b/gst/select/gstselect.h @@ -0,0 +1,71 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) <2003> David Schleef + * Copyright (C) 2003 Arwed v. Merkatz + * Copyright (C) 2006 Mark Nauwelaerts + * Copyright (C) 2015 United States Government, Joshua M. Doe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __GST_SELECT_H__ +#define __GST_SELECT_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_SELECT \ + (gst_select_get_type()) +#define GST_SELECT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SELECT,GstSelect)) +#define GST_SELECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SELECT,GstSelectClass)) +#define GST_IS_SELECT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SELECT)) +#define GST_IS_SELECT_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SELECT)) + +typedef struct _GstSelect GstSelect; +typedef struct _GstSelectClass GstSelectClass; + +/** +* GstSelect: +* @element: the parent element. +* +* +* The opaque GstSelect data structure. +*/ +struct _GstSelect +{ + GstBaseTransform element; + + /* properties */ + gint offset; + gint skip; +}; + +struct _GstSelectClass +{ + GstBaseTransformClass parent_class; +}; + +GType gst_select_get_type(void); + +G_END_DECLS + +#endif /* __GST_SELECT_H__ */