Copyright cleanup - fix so we have BSD licensing banners
[processor-sdk/gst-plugin-dsp66.git] / src / gstdsp66videokernel.c
1 /*
2  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
3  *
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *    Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *    Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the  
15  *    distribution.
16  *
17  *    Neither the name of Texas Instruments Incorporated nor the names of
18  *    its contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38 #include <string.h>
39 #include "gstdsp66videokernel.h"
41 static GstStaticPadTemplate dsp66_video_kernel_src_factory =
42 GST_STATIC_PAD_TEMPLATE ("src",
43     GST_PAD_SRC,
44     GST_PAD_ALWAYS,
45     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12 }"))
46     );
48 static GstStaticPadTemplate dsp66_video_kernel_sink_factory =
49 GST_STATIC_PAD_TEMPLATE ("sink",
50     GST_PAD_SINK,
51     GST_PAD_ALWAYS,
52     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12 }"))
53     );
55 /* Kernel signals and args */
56 enum
57 {
58   /* FILL ME */
59   LAST_SIGNAL
60 };
62 #define DEFAULT_FILTERSIZE   5
63 #define DEFAULT_LUM_ONLY     TRUE
64 #define DEFAULT_KERNELTYPE   GST_DSP66_VIDEO_KERNELTYPE_MEDIAN
65 #define DEFAULT_ARBKERNEL    "Sobel3x3"
66 enum
67 {
68   PROP_0,
69   PROP_FILTERSIZE,
70   PROP_LUM_ONLY,
71   PROP_KERNELTYPE,
72   PROP_ARBKERNEL
73 };
75 #define GST_TYPE_VIDEO_KERNEL_FILTERSIZE (gst_dsp66_video_kernel_filtersize_get_type())
76 #define GST_TYPE_VIDEO_KERNELTYPE (gst_dsp66_video_kerneltype_get_type())
78 static const GEnumValue dsp66_video_kernel_filtersizes[] = {
79   {GST_DSP66_VIDEO_KERNEL_FILTERSIZE_5, "Kernel of 5 neighbour pixels", "5"},
80   {GST_DSP66_VIDEO_KERNEL_FILTERSIZE_9, "Kernel of 9 neighbour pixels", "9"},
81   {GST_DSP66_VIDEO_KERNEL_FILTERSIZE_25, "Kernel of 25 neighbour pixels", "25"},
82   {0, NULL, NULL},
83 };
84 static const GEnumValue dsp66_video_kerneltype[] = {
85   {GST_DSP66_VIDEO_KERNELTYPE_MEDIAN, "Kernel median", "0"},
86   {GST_DSP66_VIDEO_KERNELTYPE_SOBEL, "Kernel sobel", "1"},
87   {GST_DSP66_VIDEO_KERNELTYPE_CONV,  "Kernel conv",  "2"},
88   {GST_DSP66_VIDEO_KERNELTYPE_CANNY, "Kernel canny", "3"},
89   {GST_DSP66_VIDEO_KERNELTYPE_ARB, "Kernel arbitrary", "4"},
90   {0, NULL, NULL},
91 };
93 static GType
94 gst_dsp66_video_kernel_filtersize_get_type (void)
95 {
96   static GType dsp66_video_kernel_filtersize_type = 0;
98   if (!dsp66_video_kernel_filtersize_type) {
99     dsp66_video_kernel_filtersize_type = g_enum_register_static ("GstDsp66VideoKernelFilterSize",
100         dsp66_video_kernel_filtersizes);
101   }
102   return dsp66_video_kernel_filtersize_type;
105 static GType
106 gst_dsp66_video_kerneltype_get_type (void)
108   static GType dsp66_video_kerneltype_type = 0;
110   if (!dsp66_video_kerneltype_type) {
111     dsp66_video_kerneltype_type = g_enum_register_static ("GstDsp66VideoKernelType", dsp66_video_kerneltype);
112   }
113   return dsp66_video_kerneltype_type;
116 #define gst_dsp66_video_kernel_parent_class parent_class
117 G_DEFINE_TYPE (GstDsp66VideoKernel, gst_dsp66_video_kernel, GST_TYPE_VIDEO_FILTER);
119 static GstFlowReturn gst_dsp66_video_kernel_transform_frame (GstVideoFilter * filter,
120     GstVideoFrame * in_frame, GstVideoFrame * out_frame);
122 static void gst_dsp66_video_kernel_set_property (GObject * object, guint prop_id,
123     const GValue * value, GParamSpec * pspec);
124 static void gst_dsp66_video_kernel_get_property (GObject * object, guint prop_id,
125     GValue * value, GParamSpec * pspec);
127 static void
128 gst_dsp66_video_kernel_class_init (GstDsp66VideoKernelClass * klass)
130   GObjectClass *gobject_class;
131   GstElementClass *gstelement_class;
132   GstVideoFilterClass *vfilter_class;
134   gobject_class = (GObjectClass *) klass;
135   gstelement_class = (GstElementClass *) klass;
136   vfilter_class = (GstVideoFilterClass *) klass;
138   gobject_class->set_property = gst_dsp66_video_kernel_set_property;
139   gobject_class->get_property = gst_dsp66_video_kernel_get_property;
141   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FILTERSIZE,
142       g_param_spec_enum ("filtersize", "Filtersize", "The size of the filter (5,9,25)",
143           GST_TYPE_VIDEO_KERNEL_FILTERSIZE, DEFAULT_FILTERSIZE,
144           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_KERNELTYPE,
147       g_param_spec_enum ("kerneltype", "Kerneltype", "Type of kernel (0=median, 1=sobel 2=conv 3=arbitrary)",
148           GST_TYPE_VIDEO_KERNELTYPE, DEFAULT_KERNELTYPE,
149           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
151   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LUM_ONLY,
152       g_param_spec_boolean ("lum-only", "Lum Only", "Only apply filter on "
153           "luminance", DEFAULT_LUM_ONLY,
154           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156   g_object_class_install_property (gobject_class, PROP_ARBKERNEL,
157       g_param_spec_string ("arbkernel", "User defined kernel",
158           "The name of the kernel invoked via OpenCL.",
159           NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
161   gst_element_class_add_pad_template (gstelement_class,
162       gst_static_pad_template_get (&dsp66_video_kernel_sink_factory));
163   gst_element_class_add_pad_template (gstelement_class,
164       gst_static_pad_template_get (&dsp66_video_kernel_src_factory));
165   gst_element_class_set_static_metadata (gstelement_class, "Video kernels (choose: kerneltype, filtersize, lum-only, kernelname (opt))",
166       "Video Kernel",
167       "Apply a kernel via DSP C66 offload to an image",
168       "based on work by: Wim Taymans <wim.taymans@gmail.com>");
170   vfilter_class->transform_frame =
171       GST_DEBUG_FUNCPTR (gst_dsp66_video_kernel_transform_frame);
174 void
175 gst_dsp66_video_kernel_init (GstDsp66VideoKernel * kernel)
177   kernel->filtersize = DEFAULT_FILTERSIZE;
178   kernel->kerneltype = DEFAULT_KERNELTYPE;
179   kernel->lum_only   = DEFAULT_LUM_ONLY;
180   kernel->arbkernel  = g_strdup (DEFAULT_ARBKERNEL);
183 extern int oclconv_kernel(int kernel_type, int kernel_size, char *arbkernel, 
184                           unsigned char *src, unsigned char *dest, int width, int height, int sstride, int dstride); 
186 static int 
187 imgproc (gint kerneltype, gint filtersize, gchar *arbkernel, 
188     guint8 * dest, gint dstride, 
189     const guint8 * src, gint sstride,
190     gint width, gint height)
192   return oclconv_kernel(kerneltype, filtersize, arbkernel, (unsigned char *)src, (unsigned char *)dest, width, height, sstride, dstride);
195 static GstFlowReturn
196 gst_dsp66_video_kernel_transform_frame (GstVideoFilter * filter,
197     GstVideoFrame * in_frame, GstVideoFrame * out_frame)
199   GstDsp66VideoKernel *kernel = GST_DSP66_VIDEO_KERNEL (filter);
201     if(imgproc (kernel->kerneltype, kernel->filtersize, kernel->arbkernel,
202         GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0),
203         GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0),
204         GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0),
205         GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0),
206         GST_VIDEO_FRAME_WIDTH (in_frame), GST_VIDEO_FRAME_HEIGHT (in_frame)) < 0)
207     {
208       gst_video_frame_copy_plane (out_frame, in_frame, 0);
209       gst_video_frame_copy_plane (out_frame, in_frame, 1);
210       gst_video_frame_copy_plane (out_frame, in_frame, 2);
211     }
212     if (kernel->lum_only) {
213       gst_video_frame_copy_plane (out_frame, in_frame, 1);
214       gst_video_frame_copy_plane (out_frame, in_frame, 2);
215     } else {
216       imgproc (kernel->kerneltype, kernel->filtersize, kernel->arbkernel,
217           GST_VIDEO_FRAME_PLANE_DATA (out_frame, 1),
218           GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 1),
219           GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1),
220           GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1),
221           GST_VIDEO_FRAME_WIDTH (in_frame) / 2,
222           GST_VIDEO_FRAME_HEIGHT (in_frame) / 2);
223       imgproc (kernel->kerneltype, kernel->filtersize, kernel->arbkernel,
224           GST_VIDEO_FRAME_PLANE_DATA (out_frame, 2),
225           GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 2),
226           GST_VIDEO_FRAME_PLANE_DATA (in_frame, 2),
227           GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 2),
228           GST_VIDEO_FRAME_WIDTH (in_frame) / 2,
229           GST_VIDEO_FRAME_HEIGHT (in_frame) / 2);
230     }
232   return GST_FLOW_OK;
235 static void
236 gst_dsp66_video_kernel_set_property (GObject * object, guint prop_id,
237     const GValue * value, GParamSpec * pspec)
239   GstDsp66VideoKernel *kernel;
241   kernel = GST_DSP66_VIDEO_KERNEL (object);
243   switch (prop_id) {
244     case PROP_FILTERSIZE:
245       kernel->filtersize = g_value_get_enum (value);
246       break;
247     case PROP_LUM_ONLY:
248       kernel->lum_only   = g_value_get_boolean (value);
249       break;
250     case PROP_KERNELTYPE:
251       kernel->kerneltype = g_value_get_enum (value);
252       break;
253     case PROP_ARBKERNEL:
254       if (!g_value_get_string (value)) {
255         GST_WARNING ("Arbitrary kernel string can not be NULL");
256         break;
257       }
258       g_free (kernel->arbkernel);
259       kernel->arbkernel = g_value_dup_string (value);
260       break;
261     default:
262       break;
263   }
266 static void
267 gst_dsp66_video_kernel_get_property (GObject * object, guint prop_id, GValue * value,
268     GParamSpec * pspec)
270   GstDsp66VideoKernel *kernel;
272   kernel = GST_DSP66_VIDEO_KERNEL (object);
274   switch (prop_id) {
275     case PROP_FILTERSIZE:
276       g_value_set_enum (value, kernel->filtersize);
277       break;
278     case PROP_LUM_ONLY:
279       g_value_set_boolean (value, kernel->lum_only);
280       break;
281     case PROP_KERNELTYPE:
282       g_value_set_enum (value, kernel->kerneltype);
283       break;
284     default:
285       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
286       break;
287   }
289 /** nothing past this point **/