2d7bf5de020d51913081124803a2ba7624031b16
[processor-sdk/gst-plugin-dsp66.git] / src / gstdsp66videokernel.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include <string.h>
24 #include "gstdsp66videokernel.h"
26 static GstStaticPadTemplate dsp66_video_kernel_src_factory =
27 GST_STATIC_PAD_TEMPLATE ("src",
28     GST_PAD_SRC,
29     GST_PAD_ALWAYS,
30     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12 }"))
31     );
33 static GstStaticPadTemplate dsp66_video_kernel_sink_factory =
34 GST_STATIC_PAD_TEMPLATE ("sink",
35     GST_PAD_SINK,
36     GST_PAD_ALWAYS,
37     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12 }"))
38     );
40 /* Kernel signals and args */
41 enum
42 {
43   /* FILL ME */
44   LAST_SIGNAL
45 };
47 #define DEFAULT_FILTERSIZE   5
48 #define DEFAULT_LUM_ONLY     TRUE
49 #define DEFAULT_KERNELTYPE   GST_DSP66_VIDEO_KERNELTYPE_MEDIAN
50 #define DEFAULT_ARBKERNEL    "Sobel3x3"
51 enum
52 {
53   PROP_0,
54   PROP_FILTERSIZE,
55   PROP_LUM_ONLY,
56   PROP_KERNELTYPE,
57   PROP_ARBKERNEL
58 };
60 #define GST_TYPE_VIDEO_KERNEL_FILTERSIZE (gst_dsp66_video_kernel_filtersize_get_type())
61 #define GST_TYPE_VIDEO_KERNELTYPE (gst_dsp66_video_kerneltype_get_type())
63 static const GEnumValue dsp66_video_kernel_filtersizes[] = {
64   {GST_DSP66_VIDEO_KERNEL_FILTERSIZE_5, "Kernel of 5 neighbour pixels", "5"},
65   {GST_DSP66_VIDEO_KERNEL_FILTERSIZE_9, "Kernel of 9 neighbour pixels", "9"},
66   {GST_DSP66_VIDEO_KERNEL_FILTERSIZE_25, "Kernel of 25 neighbour pixels", "25"},
67   {0, NULL, NULL},
68 };
69 static const GEnumValue dsp66_video_kerneltype[] = {
70   {GST_DSP66_VIDEO_KERNELTYPE_MEDIAN, "Kernel median", "0"},
71   {GST_DSP66_VIDEO_KERNELTYPE_SOBEL, "Kernel sobel", "1"},
72   {GST_DSP66_VIDEO_KERNELTYPE_CONV,  "Kernel conv",  "2"},
73   {GST_DSP66_VIDEO_KERNELTYPE_CANNY, "Kernel canny", "3"},
74   {GST_DSP66_VIDEO_KERNELTYPE_ARB, "Kernel arbitrary", "4"},
75   {0, NULL, NULL},
76 };
78 static GType
79 gst_dsp66_video_kernel_filtersize_get_type (void)
80 {
81   static GType dsp66_video_kernel_filtersize_type = 0;
83   if (!dsp66_video_kernel_filtersize_type) {
84     dsp66_video_kernel_filtersize_type = g_enum_register_static ("GstDsp66VideoKernelFilterSize",
85         dsp66_video_kernel_filtersizes);
86   }
87   return dsp66_video_kernel_filtersize_type;
88 }
90 static GType
91 gst_dsp66_video_kerneltype_get_type (void)
92 {
93   static GType dsp66_video_kerneltype_type = 0;
95   if (!dsp66_video_kerneltype_type) {
96     dsp66_video_kerneltype_type = g_enum_register_static ("GstDsp66VideoKernelType", dsp66_video_kerneltype);
97   }
98   return dsp66_video_kerneltype_type;
99 }
101 #define gst_dsp66_video_kernel_parent_class parent_class
102 G_DEFINE_TYPE (GstDsp66VideoKernel, gst_dsp66_video_kernel, GST_TYPE_VIDEO_FILTER);
104 static GstFlowReturn gst_dsp66_video_kernel_transform_frame (GstVideoFilter * filter,
105     GstVideoFrame * in_frame, GstVideoFrame * out_frame);
107 static void gst_dsp66_video_kernel_set_property (GObject * object, guint prop_id,
108     const GValue * value, GParamSpec * pspec);
109 static void gst_dsp66_video_kernel_get_property (GObject * object, guint prop_id,
110     GValue * value, GParamSpec * pspec);
112 static void
113 gst_dsp66_video_kernel_class_init (GstDsp66VideoKernelClass * klass)
115   GObjectClass *gobject_class;
116   GstElementClass *gstelement_class;
117   GstVideoFilterClass *vfilter_class;
119   gobject_class = (GObjectClass *) klass;
120   gstelement_class = (GstElementClass *) klass;
121   vfilter_class = (GstVideoFilterClass *) klass;
123   gobject_class->set_property = gst_dsp66_video_kernel_set_property;
124   gobject_class->get_property = gst_dsp66_video_kernel_get_property;
126   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FILTERSIZE,
127       g_param_spec_enum ("filtersize", "Filtersize", "The size of the filter (5,9,25)",
128           GST_TYPE_VIDEO_KERNEL_FILTERSIZE, DEFAULT_FILTERSIZE,
129           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
131   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_KERNELTYPE,
132       g_param_spec_enum ("kerneltype", "Kerneltype", "Type of kernel (0=median, 1=sobel 2=conv 3=arbitrary)",
133           GST_TYPE_VIDEO_KERNELTYPE, DEFAULT_KERNELTYPE,
134           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
136   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LUM_ONLY,
137       g_param_spec_boolean ("lum-only", "Lum Only", "Only apply filter on "
138           "luminance", DEFAULT_LUM_ONLY,
139           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
141   g_object_class_install_property (gobject_class, PROP_ARBKERNEL,
142       g_param_spec_string ("arbkernel", "User defined kernel",
143           "The name of the kernel invoked via OpenCL.",
144           NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
146   gst_element_class_add_pad_template (gstelement_class,
147       gst_static_pad_template_get (&dsp66_video_kernel_sink_factory));
148   gst_element_class_add_pad_template (gstelement_class,
149       gst_static_pad_template_get (&dsp66_video_kernel_src_factory));
150   gst_element_class_set_static_metadata (gstelement_class, "Video kernels (choose: kerneltype, filtersize, lum-only, kernelname (opt))",
151       "Video Kernel",
152       "Apply a kernel via DSP C66 offload to an image",
153       "based on work by: Wim Taymans <wim.taymans@gmail.com>");
155   vfilter_class->transform_frame =
156       GST_DEBUG_FUNCPTR (gst_dsp66_video_kernel_transform_frame);
159 void
160 gst_dsp66_video_kernel_init (GstDsp66VideoKernel * kernel)
162   kernel->filtersize = DEFAULT_FILTERSIZE;
163   kernel->kerneltype = DEFAULT_KERNELTYPE;
164   kernel->lum_only   = DEFAULT_LUM_ONLY;
165   kernel->arbkernel  = g_strdup (DEFAULT_ARBKERNEL);
168 extern int oclconv_kernel(int kernel_type, int kernel_size, char *arbkernel, 
169                           unsigned char *src, unsigned char *dest, int width, int height, int sstride, int dstride); 
171 static int 
172 imgproc (gint kerneltype, gint filtersize, gchar *arbkernel, 
173     guint8 * dest, gint dstride, 
174     const guint8 * src, gint sstride,
175     gint width, gint height)
177   return oclconv_kernel(kerneltype, filtersize, arbkernel, (unsigned char *)src, (unsigned char *)dest, width, height, sstride, dstride);
180 static GstFlowReturn
181 gst_dsp66_video_kernel_transform_frame (GstVideoFilter * filter,
182     GstVideoFrame * in_frame, GstVideoFrame * out_frame)
184   GstDsp66VideoKernel *kernel = GST_DSP66_VIDEO_KERNEL (filter);
186     if(imgproc (kernel->kerneltype, kernel->filtersize, kernel->arbkernel,
187         GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0),
188         GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 0),
189         GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0),
190         GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 0),
191         GST_VIDEO_FRAME_WIDTH (in_frame), GST_VIDEO_FRAME_HEIGHT (in_frame)) < 0)
192     {
193       gst_video_frame_copy_plane (out_frame, in_frame, 0);
194       gst_video_frame_copy_plane (out_frame, in_frame, 1);
195       gst_video_frame_copy_plane (out_frame, in_frame, 2);
196     }
197     if (kernel->lum_only) {
198       gst_video_frame_copy_plane (out_frame, in_frame, 1);
199       gst_video_frame_copy_plane (out_frame, in_frame, 2);
200     } else {
201       imgproc (kernel->kerneltype, kernel->filtersize, kernel->arbkernel,
202           GST_VIDEO_FRAME_PLANE_DATA (out_frame, 1),
203           GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 1),
204           GST_VIDEO_FRAME_PLANE_DATA (in_frame, 1),
205           GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 1),
206           GST_VIDEO_FRAME_WIDTH (in_frame) / 2,
207           GST_VIDEO_FRAME_HEIGHT (in_frame) / 2);
208       imgproc (kernel->kerneltype, kernel->filtersize, kernel->arbkernel,
209           GST_VIDEO_FRAME_PLANE_DATA (out_frame, 2),
210           GST_VIDEO_FRAME_PLANE_STRIDE (out_frame, 2),
211           GST_VIDEO_FRAME_PLANE_DATA (in_frame, 2),
212           GST_VIDEO_FRAME_PLANE_STRIDE (in_frame, 2),
213           GST_VIDEO_FRAME_WIDTH (in_frame) / 2,
214           GST_VIDEO_FRAME_HEIGHT (in_frame) / 2);
215     }
217   return GST_FLOW_OK;
220 static void
221 gst_dsp66_video_kernel_set_property (GObject * object, guint prop_id,
222     const GValue * value, GParamSpec * pspec)
224   GstDsp66VideoKernel *kernel;
226   kernel = GST_DSP66_VIDEO_KERNEL (object);
228   switch (prop_id) {
229     case PROP_FILTERSIZE:
230       kernel->filtersize = g_value_get_enum (value);
231       break;
232     case PROP_LUM_ONLY:
233       kernel->lum_only   = g_value_get_boolean (value);
234       break;
235     case PROP_KERNELTYPE:
236       kernel->kerneltype = g_value_get_enum (value);
237       break;
238     case PROP_ARBKERNEL:
239       if (!g_value_get_string (value)) {
240         GST_WARNING ("Arbitrary kernel string can not be NULL");
241         break;
242       }
243       g_free (kernel->arbkernel);
244       kernel->arbkernel = g_value_dup_string (value);
245       break;
246     default:
247       break;
248   }
251 static void
252 gst_dsp66_video_kernel_get_property (GObject * object, guint prop_id, GValue * value,
253     GParamSpec * pspec)
255   GstDsp66VideoKernel *kernel;
257   kernel = GST_DSP66_VIDEO_KERNEL (object);
259   switch (prop_id) {
260     case PROP_FILTERSIZE:
261       g_value_set_enum (value, kernel->filtersize);
262       break;
263     case PROP_LUM_ONLY:
264       g_value_set_boolean (value, kernel->lum_only);
265       break;
266     case PROP_KERNELTYPE:
267       g_value_set_enum (value, kernel->kerneltype);
268       break;
269     default:
270       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
271       break;
272   }
274 /** nothing past this point **/