segmentation: Port to GstOpencvVideoFilter base class
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Sun, 4 Dec 2016 19:42:47 +0000 (14:42 -0500)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Sun, 4 Dec 2016 19:49:05 +0000 (14:49 -0500)
ext/opencv/gstsegmentation.cpp
ext/opencv/gstsegmentation.h

index d67bb9a..d52476e 100644 (file)
@@ -81,7 +81,7 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch-1.0  v4l2src device=/dev/video0 ! videoconvert ! video/x-raw,width=320,height=240 ! videoconvert ! segmentation test-mode=true method=2 ! videoconvert ! ximagesink
+ * gst-launch-1.0  v4l2src device=/dev/video0 ! videoconvert ! segmentation test-mode=true method=2 ! videoconvert ! ximagesink
  * ]|
  * </refsect2>
  */
@@ -142,7 +142,8 @@ gst_segmentation_method_get_type (void)
   return etype;
 }
 
-G_DEFINE_TYPE (GstSegmentation, gst_segmentation, GST_TYPE_VIDEO_FILTER);
+G_DEFINE_TYPE (GstSegmentation, gst_segmentation, GST_TYPE_OPENCV_VIDEO_FILTER);
+
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
@@ -159,13 +160,13 @@ static void gst_segmentation_set_property (GObject * object, guint prop_id,
 static void gst_segmentation_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static GstFlowReturn gst_segmentation_transform_ip (GstVideoFilter * btrans,
-    GstVideoFrame * frame);
+static GstFlowReturn gst_segmentation_transform_ip (GstOpencvVideoFilter * filter,
+    GstBuffer * buffer, IplImage * img);
 
 static gboolean gst_segmentation_stop (GstBaseTransform * basesrc);
-static gboolean gst_segmentation_set_info (GstVideoFilter * filter,
-    GstCaps * incaps, GstVideoInfo * in_info,
-    GstCaps * outcaps, GstVideoInfo * out_info);
+static gboolean gst_segmentation_set_caps (GstOpencvVideoFilter * filter, gint in_width,
+    gint in_height, gint in_depth, gint in_channels,
+    gint out_width, gint out_height, gint out_depth, gint out_channels);
 static void gst_segmentation_release_all_pointers (GstSegmentation * filter);
 
 /* Codebook algorithm + connected components functions*/
@@ -190,7 +191,8 @@ gst_segmentation_class_init (GstSegmentationClass * klass)
   GObjectClass *gobject_class;
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstBaseTransformClass *basesrc_class = GST_BASE_TRANSFORM_CLASS (klass);
-  GstVideoFilterClass *video_class = (GstVideoFilterClass *) klass;
+  GstOpencvVideoFilterClass *cvfilter_class =
+      (GstOpencvVideoFilterClass *) klass;
 
   gobject_class = (GObjectClass *) klass;
 
@@ -199,8 +201,8 @@ gst_segmentation_class_init (GstSegmentationClass * klass)
 
   basesrc_class->stop = gst_segmentation_stop;
 
-  video_class->transform_frame_ip = gst_segmentation_transform_ip;
-  video_class->set_info = gst_segmentation_set_info;
+  cvfilter_class->cv_trans_ip_func = gst_segmentation_transform_ip;
+  cvfilter_class->cv_set_caps = gst_segmentation_set_caps;
 
   g_object_class_install_property (gobject_class, PROP_METHOD,
       g_param_spec_enum ("method",
@@ -243,10 +245,9 @@ gst_segmentation_init (GstSegmentation * filter)
   filter->test_mode = DEFAULT_TEST_MODE;
   filter->framecount = 0;
   filter->learning_rate = DEFAULT_LEARNING_RATE;
-  gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
+  gst_opencv_video_filter_set_in_place (GST_OPENCV_VIDEO_FILTER (filter), TRUE);
 }
 
-
 static void
 gst_segmentation_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
@@ -291,25 +292,20 @@ gst_segmentation_get_property (GObject * object, guint prop_id,
   }
 }
 
-/* GstElement vmethod implementations */
-/* this function handles the link with other elements */
 static gboolean
-gst_segmentation_set_info (GstVideoFilter * filter,
-    GstCaps * incaps, GstVideoInfo * in_info,
-    GstCaps * outcaps, GstVideoInfo * out_info)
+gst_segmentation_set_caps (GstOpencvVideoFilter * filter, gint in_width,
+    gint in_height, gint in_depth, gint in_channels,
+    gint out_width, gint out_height, gint out_depth, gint out_channels)
 {
   GstSegmentation *segmentation = GST_SEGMENTATION (filter);
   CvSize size;
 
-  size = cvSize (in_info->width, in_info->height);
-  segmentation->width = in_info->width;
-  segmentation->height = in_info->height;
-  /*  If cvRGB is already allocated, it means there's a cap modification, */
-  /*  so release first all the images. */
-  if (NULL != segmentation->cvRGBA)
-    gst_segmentation_release_all_pointers (segmentation);
+  size = cvSize (in_width, in_height);
+  segmentation->width = in_width;
+  segmentation->height = in_height;
 
-  segmentation->cvRGBA = cvCreateImageHeader (size, IPL_DEPTH_8U, 4);
+  if (NULL != segmentation->cvRGB)
+    gst_segmentation_release_all_pointers (segmentation);
 
   segmentation->cvRGB = cvCreateImage (size, IPL_DEPTH_8U, 3);
   segmentation->cvYUV = cvCreateImage (size, IPL_DEPTH_8U, 3);
@@ -343,7 +339,7 @@ gst_segmentation_stop (GstBaseTransform * basesrc)
 {
   GstSegmentation *filter = GST_SEGMENTATION (basesrc);
 
-  if (filter->cvRGBA != NULL)
+  if (filter->cvRGB != NULL)
     gst_segmentation_release_all_pointers (filter);
 
   return TRUE;
@@ -352,7 +348,6 @@ gst_segmentation_stop (GstBaseTransform * basesrc)
 static void
 gst_segmentation_release_all_pointers (GstSegmentation * filter)
 {
-  cvReleaseImage (&filter->cvRGBA);
   cvReleaseImage (&filter->cvRGB);
   cvReleaseImage (&filter->cvYUV);
   cvReleaseImage (&filter->cvFG);
@@ -367,18 +362,16 @@ gst_segmentation_release_all_pointers (GstSegmentation * filter)
 }
 
 static GstFlowReturn
-gst_segmentation_transform_ip (GstVideoFilter * btrans, GstVideoFrame * frame)
+gst_segmentation_transform_ip (GstOpencvVideoFilter * cvfilter, GstBuffer * buffer,
+        IplImage * img)
 {
-  GstSegmentation *filter = GST_SEGMENTATION (btrans);
+  GstSegmentation *filter = GST_SEGMENTATION (cvfilter);
   int j;
 
-  /*  get image data from the input, which is RGBA */
-  filter->cvRGBA->imageData = (char *) GST_VIDEO_FRAME_COMP_DATA (frame, 0);
-  filter->cvRGBA->widthStep = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
   filter->framecount++;
 
   /*  Image preprocessing: color space conversion etc */
-  cvCvtColor (filter->cvRGBA, filter->cvRGB, CV_RGBA2RGB);
+  cvCvtColor (img, filter->cvRGB, CV_RGBA2RGB);
   cvCvtColor (filter->cvRGB, filter->cvYUV, CV_RGB2YCrCb);
 
   /* Create and update a fg/bg model using a codebook approach following the
@@ -460,10 +453,10 @@ gst_segmentation_transform_ip (GstVideoFilter * btrans, GstVideoFrame * frame)
 
     cvSplit (filter->cvRGB, filter->ch1, filter->ch2, filter->ch3, NULL);
   } else
-    cvSplit (filter->cvRGBA, filter->ch1, filter->ch2, filter->ch3, NULL);
+    cvSplit (img, filter->ch1, filter->ch2, filter->ch3, NULL);
 
   /*  copy anyhow the fg/bg to the alpha channel in the output image */
-  cvMerge (filter->ch1, filter->ch2, filter->ch3, filter->cvFG, filter->cvRGBA);
+  cvMerge (filter->ch1, filter->ch2, filter->ch3, filter->cvFG, img);
 
 
   return GST_FLOW_OK;
index 982e2ba..20e42ca 100644 (file)
@@ -45,7 +45,7 @@
 #define __GST_SEGMENTATION_H__
 
 #include <gst/gst.h>
-#include <gst/video/gstvideofilter.h>
+#include <gst/opencv/gstopencvvideofilter.h>
 #include <opencv2/core/core_c.h>
 #include <opencv2/video/background_segm.hpp>
 #include <opencv2/core/version.hpp>
@@ -90,13 +90,12 @@ typedef struct code_book
 
 struct _GstSegmentation
 {
-  GstVideoFilter element;
+  GstOpencvVideoFilter element;
   gint method;
 
   gboolean test_mode;
   gint width, height;
 
-  IplImage *cvRGBA;
   IplImage *cvRGB;
   IplImage *cvYUV;
 
@@ -125,7 +124,7 @@ struct _GstSegmentation
 
 struct _GstSegmentationClass
 {
-  GstVideoFilterClass parent_class;
+  GstOpencvVideoFilterClass parent_class;
 };
 
 GType gst_segmentation_get_type (void);