1 /*
2 * gstxcamfilter.cpp -gst xcamfilter plugin
3 *
4 * Copyright (c) 2016 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Yinhang Liu <yinhangx.liu@intel.com>
19 */
20
21 #include "gstxcamfilter.h"
22 #include "gstxcambuffermeta.h"
23
24 #include <gst/gstmeta.h>
25 #include <gst/allocators/gstdmabuf.h>
26
27 using namespace XCam;
28 using namespace GstXCam;
29
30 #define DEFAULT_SMART_ANALYSIS_LIB_DIR "/usr/lib/xcam/plugins/smart"
31 #define DEFAULT_DELAY_BUFFER_NUM 2
32
33 #define DEFAULT_PROP_BUFFERCOUNT 8
34 #define DEFAULT_PROP_COPY_MODE COPY_MODE_CPU
35 #define DEFAULT_PROP_DEFOG_MODE DEFOG_NONE
36 #define DEFAULT_PROP_WAVELET_MODE NONE_WAVELET
37 #define DEFAULT_PROP_3D_DENOISE_MODE DENOISE_3D_NONE
38 #define DEFAULT_PROP_ENABLE_WIREFRAME FALSE
39 #define DEFAULT_PROP_ENABLE_IMAGE_WARP FALSE
40 #define DEFAULT_PROP_ENABLE_IMAGE_STITCH FALSE
41 #define DEFAULT_PROP_STITCH_ENABLE_SEAM FALSE
42 #define DEFAULT_PROP_STITCH_SCALE_MODE CLBlenderScaleLocal
43 #define DEFAULT_PROP_STITCH_FISHEYE_MAP FALSE
44 #define DEFAULT_PROP_STITCH_LSC FALSE
45 #define DEFAULT_PROP_STITCH_FM_OCL FALSE
46 #define DEFAULT_PROP_STITCH_RES_MODE StitchRes1080P
47
48 XCAM_BEGIN_DECLARE
49
50 enum {
51 PROP_0,
52 PROP_BUFFERCOUNT,
53 PROP_COPY_MODE,
54 PROP_DEFOG_MODE,
55 PROP_WAVELET_MODE,
56 PROP_DENOISE_3D_MODE,
57 PROP_ENABLE_WIREFRAME,
58 PROP_ENABLE_IMAGE_WARP,
59 PROP_ENABLE_IMAGE_STITCH,
60 PROP_STITCH_ENABLE_SEAM,
61 PROP_STITCH_SCALE_MODE,
62 PROP_STITCH_FISHEYE_MAP,
63 PROP_STITCH_LSC,
64 PROP_STITCH_FM_OCL,
65 PROP_STITCH_RES_MODE
66 };
67
68 #define GST_TYPE_XCAM_FILTER_COPY_MODE (gst_xcam_filter_copy_mode_get_type ())
69 static GType
gst_xcam_filter_copy_mode_get_type(void)70 gst_xcam_filter_copy_mode_get_type (void)
71 {
72 static GType g_type = 0;
73 static const GEnumValue copy_mode_types[] = {
74 {COPY_MODE_CPU, "Copy buffer with CPU", "cpu"},
75 {COPY_MODE_DMA, "Copy buffer with DMA", "dma"},
76 {0, NULL, NULL}
77 };
78
79 if (g_once_init_enter (&g_type)) {
80 const GType type =
81 g_enum_register_static ("GstXCamFilterCopyModeType", copy_mode_types);
82 g_once_init_leave (&g_type, type);
83 }
84
85 return g_type;
86 }
87
88 #define GST_TYPE_XCAM_FILTER_DEFOG_MODE (gst_xcam_filter_defog_mode_get_type ())
89 static GType
gst_xcam_filter_defog_mode_get_type(void)90 gst_xcam_filter_defog_mode_get_type (void)
91 {
92 static GType g_type = 0;
93 static const GEnumValue defog_mode_types [] = {
94 {DEFOG_NONE, "Defog disabled", "none"},
95 {DEFOG_RETINEX, "Defog retinex", "retinex"},
96 {DEFOG_DCP, "Defog dark channel prior", "dcp"},
97 {0, NULL, NULL}
98 };
99
100 if (g_once_init_enter (&g_type)) {
101 const GType type =
102 g_enum_register_static ("GstXCamFilterDefogModeType", defog_mode_types);
103 g_once_init_leave (&g_type, type);
104 }
105
106 return g_type;
107 }
108
109 #define GST_TYPE_XCAM_FILTER_WAVELET_MODE (gst_xcam_filter_wavelet_mode_get_type ())
110 static GType
gst_xcam_filter_wavelet_mode_get_type(void)111 gst_xcam_filter_wavelet_mode_get_type (void)
112 {
113 static GType g_type = 0;
114 static const GEnumValue wavelet_mode_types[] = {
115 {NONE_WAVELET, "Wavelet disabled", "none"},
116 {HAT_WAVELET_Y, "Hat wavelet Y", "hat Y"},
117 {HAT_WAVELET_UV, "Hat wavelet UV", "hat UV"},
118 {HARR_WAVELET_Y, "Haar wavelet Y", "haar Y"},
119 {HARR_WAVELET_UV, "Haar wavelet UV", "haar UV"},
120 {HARR_WAVELET_YUV, "Haar wavelet YUV", "haar YUV"},
121 {HARR_WAVELET_BAYES, "Haar wavelet bayes shrink", "haar Bayes"},
122 {0, NULL, NULL},
123 };
124
125 if (g_once_init_enter (&g_type)) {
126 const GType type =
127 g_enum_register_static ("GstXCamFilterWaveletModeType", wavelet_mode_types);
128 g_once_init_leave (&g_type, type);
129 }
130
131 return g_type;
132 }
133
134 #define GST_TYPE_XCAM_FILTER_3D_DENOISE_MODE (gst_xcam_filter_3d_denoise_mode_get_type ())
135 static GType
gst_xcam_filter_3d_denoise_mode_get_type(void)136 gst_xcam_filter_3d_denoise_mode_get_type (void)
137 {
138 static GType g_type = 0;
139 static const GEnumValue denoise_3d_mode_types [] = {
140 {DENOISE_3D_NONE, "3D Denoise disabled", "none"},
141 {DENOISE_3D_YUV, "3D Denoise yuv", "yuv"},
142 {DENOISE_3D_UV, "3D Denoise uv", "uv"},
143 {0, NULL, NULL}
144 };
145
146 if (g_once_init_enter (&g_type)) {
147 const GType type =
148 g_enum_register_static ("GstXCamFilter3DDenoiseModeType", denoise_3d_mode_types);
149 g_once_init_leave (&g_type, type);
150 }
151
152 return g_type;
153 }
154
155 #define GST_TYPE_XCAM_FILTER_STITCH_SCALE_MODE (gst_xcam_filter_stitch_scale_mode_get_type ())
156 static GType
gst_xcam_filter_stitch_scale_mode_get_type(void)157 gst_xcam_filter_stitch_scale_mode_get_type (void)
158 {
159 static GType g_type = 0;
160 static const GEnumValue stitch_scale_mode_types [] = {
161 {CLBlenderScaleLocal, "Image stitch local scale", "local"},
162 {CLBlenderScaleGlobal, "Image stitch glocal scale", "global"},
163 {0, NULL, NULL}
164 };
165
166 if (g_once_init_enter (&g_type)) {
167 const GType type =
168 g_enum_register_static ("GstXCamFilterStitchScaleModeType", stitch_scale_mode_types);
169 g_once_init_leave (&g_type, type);
170 }
171
172 return g_type;
173 }
174
175 #define GST_TYPE_XCAM_FILTER_STITCH_RES_MODE (gst_xcam_filter_stitch_res_mode_get_type ())
176 static GType
gst_xcam_filter_stitch_res_mode_get_type(void)177 gst_xcam_filter_stitch_res_mode_get_type (void)
178 {
179 static GType g_type = 0;
180 static const GEnumValue stitch_res_mode_types [] = {
181 {StitchRes1080P, "Image stitch 1080P mode", "1080p"},
182 {StitchRes4K, "Image stitch 4K mode", "4k"},
183 {0, NULL, NULL}
184 };
185
186 if (g_once_init_enter (&g_type)) {
187 const GType type =
188 g_enum_register_static ("GstXCamFilterStitchResModeType", stitch_res_mode_types);
189 g_once_init_leave (&g_type, type);
190 }
191
192 return g_type;
193 }
194
195 static GstStaticPadTemplate gst_xcam_sink_factory =
196 GST_STATIC_PAD_TEMPLATE ("sink",
197 GST_PAD_SINK,
198 GST_PAD_ALWAYS,
199 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ NV12 }")));
200
201 static GstStaticPadTemplate gst_xcam_src_factory =
202 GST_STATIC_PAD_TEMPLATE ("src",
203 GST_PAD_SRC,
204 GST_PAD_ALWAYS,
205 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ NV12 }")));
206
207 GST_DEBUG_CATEGORY (gst_xcam_filter_debug);
208 #define GST_CAT_DEFAULT gst_xcam_filter_debug
209
210 #define gst_xcam_filter_parent_class parent_class
211 G_DEFINE_TYPE (GstXCamFilter, gst_xcam_filter, GST_TYPE_BASE_TRANSFORM);
212
213 static void gst_xcam_filter_finalize (GObject * object);
214 static void gst_xcam_filter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
215 static void gst_xcam_filter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
216 static gboolean gst_xcam_filter_start (GstBaseTransform *trans);
217 static GstCaps *gst_xcam_filter_transform_caps (
218 GstBaseTransform *trans, GstPadDirection direction, GstCaps *caps, GstCaps *filter);
219 static gboolean gst_xcam_filter_set_caps (GstBaseTransform *trans, GstCaps *incaps, GstCaps *outcaps);
220 static gboolean gst_xcam_filter_stop (GstBaseTransform *trans);
221 static void gst_xcam_filter_before_transform (GstBaseTransform *trans, GstBuffer *buffer);
222 static GstFlowReturn gst_xcam_filter_prepare_output_buffer (GstBaseTransform * trans, GstBuffer *input, GstBuffer **outbuf);
223 static GstFlowReturn gst_xcam_filter_transform (GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf);
224
225 XCAM_END_DECLARE
226
227 static void
gst_xcam_filter_class_init(GstXCamFilterClass * class_self)228 gst_xcam_filter_class_init (GstXCamFilterClass *class_self)
229 {
230 GObjectClass *gobject_class;
231 GstElementClass *element_class;
232 GstBaseTransformClass *basetrans_class;
233
234 gobject_class = (GObjectClass *) class_self;
235 element_class = (GstElementClass *) class_self;
236 basetrans_class = (GstBaseTransformClass *) class_self;
237
238 GST_DEBUG_CATEGORY_INIT (gst_xcam_filter_debug, "xcamfilter", 0, "LibXCam filter plugin");
239
240 gobject_class->finalize = gst_xcam_filter_finalize;
241 gobject_class->set_property = gst_xcam_filter_set_property;
242 gobject_class->get_property = gst_xcam_filter_get_property;
243
244 g_object_class_install_property (
245 gobject_class, PROP_BUFFERCOUNT,
246 g_param_spec_int ("buffercount", "buffer count", "Buffer count",
247 0, G_MAXINT, DEFAULT_PROP_BUFFERCOUNT,
248 (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
249
250 g_object_class_install_property (
251 gobject_class, PROP_COPY_MODE,
252 g_param_spec_enum ("copy-mode", "copy mode", "Copy Mode",
253 GST_TYPE_XCAM_FILTER_COPY_MODE, DEFAULT_PROP_COPY_MODE,
254 (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
255
256 g_object_class_install_property (
257 gobject_class, PROP_DEFOG_MODE,
258 g_param_spec_enum ("defog-mode", "defog mode", "Defog mode",
259 GST_TYPE_XCAM_FILTER_DEFOG_MODE, DEFAULT_PROP_DEFOG_MODE,
260 (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
261
262 g_object_class_install_property (
263 gobject_class, PROP_WAVELET_MODE,
264 g_param_spec_enum ("wavelet-mode", "wavelet mode", "Wavelet Mode",
265 GST_TYPE_XCAM_FILTER_WAVELET_MODE, DEFAULT_PROP_WAVELET_MODE,
266 (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
267
268 g_object_class_install_property (
269 gobject_class, PROP_DENOISE_3D_MODE,
270 g_param_spec_enum ("denoise-3d", "3D Denoise mode", "3D Denoise mode",
271 GST_TYPE_XCAM_FILTER_3D_DENOISE_MODE, DEFAULT_PROP_3D_DENOISE_MODE,
272 (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
273
274 g_object_class_install_property (
275 gobject_class, PROP_ENABLE_WIREFRAME,
276 g_param_spec_boolean ("enable-wireframe", "enable wire frame", "Enable wire frame",
277 DEFAULT_PROP_ENABLE_WIREFRAME, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
278
279 g_object_class_install_property (
280 gobject_class, PROP_ENABLE_IMAGE_WARP,
281 g_param_spec_boolean ("enable-warp", "enable image warp", "Enable Image Warp",
282 DEFAULT_PROP_ENABLE_IMAGE_WARP, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
283
284 g_object_class_install_property (
285 gobject_class, PROP_ENABLE_IMAGE_STITCH,
286 g_param_spec_boolean ("enable-stitch", "enable image stitch", "Enable Image Stitch",
287 DEFAULT_PROP_ENABLE_IMAGE_STITCH, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
288
289 g_object_class_install_property (
290 gobject_class, PROP_STITCH_ENABLE_SEAM,
291 g_param_spec_boolean ("stitch-seam", "enable seam just for stitch", "Enable Seam Just For Stitch",
292 DEFAULT_PROP_STITCH_ENABLE_SEAM, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
293
294 g_object_class_install_property (
295 gobject_class, PROP_STITCH_SCALE_MODE,
296 g_param_spec_enum ("stitch-scale", "stitch scale mode", "Stitch Scale Mode",
297 GST_TYPE_XCAM_FILTER_STITCH_SCALE_MODE, DEFAULT_PROP_STITCH_SCALE_MODE,
298 (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
299
300 g_object_class_install_property (
301 gobject_class, PROP_STITCH_FISHEYE_MAP,
302 g_param_spec_boolean ("stitch-fisheye-map", "stitch fisheye map", "Enable fisheye map for stitch",
303 DEFAULT_PROP_STITCH_FISHEYE_MAP, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
304
305 g_object_class_install_property (
306 gobject_class, PROP_STITCH_LSC,
307 g_param_spec_boolean ("stitch-lsc", "stitch enable lens shading correction", "Enable Lens Shading Correction",
308 DEFAULT_PROP_STITCH_LSC, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
309
310 #if HAVE_OPENCV
311 g_object_class_install_property (
312 gobject_class, PROP_STITCH_FM_OCL,
313 g_param_spec_boolean ("stitch-fm-ocl", "stitch enable ocl for feature match", "Enable ocl for feature match",
314 DEFAULT_PROP_STITCH_FM_OCL, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
315 #endif
316
317 g_object_class_install_property (
318 gobject_class, PROP_STITCH_RES_MODE,
319 g_param_spec_enum ("stitch-res-mode", "stitch resolution mode", "Stitch Resolution Mode",
320 GST_TYPE_XCAM_FILTER_STITCH_RES_MODE, DEFAULT_PROP_STITCH_RES_MODE,
321 (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
322
323 gst_element_class_set_details_simple (element_class,
324 "Libxcam Filter",
325 "Filter/Effect/Video",
326 "Process NV12 stream using xcam library",
327 "Wind Yuan <feng.yuan@intel.com> & Yinhang Liu <yinhangx.liu@intel.com>");
328
329 gst_element_class_add_pad_template (element_class,
330 gst_static_pad_template_get (&gst_xcam_src_factory));
331 gst_element_class_add_pad_template (element_class,
332 gst_static_pad_template_get (&gst_xcam_sink_factory));
333
334 basetrans_class->start = GST_DEBUG_FUNCPTR (gst_xcam_filter_start);
335 basetrans_class->stop = GST_DEBUG_FUNCPTR (gst_xcam_filter_stop);
336 basetrans_class->transform_caps = GST_DEBUG_FUNCPTR (gst_xcam_filter_transform_caps);
337 basetrans_class->set_caps = GST_DEBUG_FUNCPTR (gst_xcam_filter_set_caps);
338 basetrans_class->before_transform = GST_DEBUG_FUNCPTR (gst_xcam_filter_before_transform);
339 basetrans_class->prepare_output_buffer = GST_DEBUG_FUNCPTR (gst_xcam_filter_prepare_output_buffer);
340 basetrans_class->transform = GST_DEBUG_FUNCPTR (gst_xcam_filter_transform);
341 }
342
343 static void
gst_xcam_filter_init(GstXCamFilter * xcamfilter)344 gst_xcam_filter_init (GstXCamFilter *xcamfilter)
345 {
346 xcamfilter->buf_count = DEFAULT_PROP_BUFFERCOUNT;
347 xcamfilter->copy_mode = DEFAULT_PROP_COPY_MODE;
348 xcamfilter->defog_mode = DEFAULT_PROP_DEFOG_MODE;
349 xcamfilter->wavelet_mode = DEFAULT_PROP_WAVELET_MODE;
350 xcamfilter->denoise_3d_mode = DEFAULT_PROP_3D_DENOISE_MODE;
351 xcamfilter->denoise_3d_ref_count = 2;
352 xcamfilter->enable_wireframe = DEFAULT_PROP_ENABLE_WIREFRAME;
353 xcamfilter->enable_image_warp = DEFAULT_PROP_ENABLE_IMAGE_WARP;
354 xcamfilter->enable_stitch = DEFAULT_PROP_ENABLE_IMAGE_STITCH;
355 xcamfilter->stitch_enable_seam = DEFAULT_PROP_STITCH_ENABLE_SEAM;
356 xcamfilter->stitch_fisheye_map = DEFAULT_PROP_STITCH_FISHEYE_MAP;
357 xcamfilter->stitch_lsc = DEFAULT_PROP_STITCH_LSC;
358 xcamfilter->stitch_fm_ocl = DEFAULT_PROP_STITCH_FM_OCL;
359 xcamfilter->stitch_scale_mode = DEFAULT_PROP_STITCH_SCALE_MODE;
360 xcamfilter->stitch_res_mode = DEFAULT_PROP_STITCH_RES_MODE;
361
362 xcamfilter->delay_buf_num = DEFAULT_DELAY_BUFFER_NUM;
363 xcamfilter->cached_buf_num = 0;
364
365 XCAM_CONSTRUCTOR (xcamfilter->pipe_manager, SmartPtr<MainPipeManager>);
366 xcamfilter->pipe_manager = new MainPipeManager;
367 XCAM_ASSERT (xcamfilter->pipe_manager.ptr ());
368 }
369
370 static void
gst_xcam_filter_finalize(GObject * object)371 gst_xcam_filter_finalize (GObject *object)
372 {
373 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (object);
374
375 if (xcamfilter->allocator)
376 gst_object_unref (xcamfilter->allocator);
377
378 xcamfilter->pipe_manager.release ();
379 XCAM_DESTRUCTOR (xcamfilter->pipe_manager, SmartPtr<MainPipeManager>);
380
381 G_OBJECT_CLASS (parent_class)->finalize (object);
382 }
383
384 static void
gst_xcam_filter_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)385 gst_xcam_filter_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
386 {
387 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (object);
388
389 switch (prop_id) {
390 case PROP_BUFFERCOUNT:
391 xcamfilter->buf_count = g_value_get_int (value);
392 break;
393 case PROP_COPY_MODE:
394 xcamfilter->copy_mode = (CopyMode) g_value_get_enum (value);
395 break;
396 case PROP_DEFOG_MODE:
397 xcamfilter->defog_mode = (DefogModeType) g_value_get_enum (value);
398 break;
399 case PROP_WAVELET_MODE:
400 xcamfilter->wavelet_mode = (WaveletModeType) g_value_get_enum (value);
401 break;
402 case PROP_DENOISE_3D_MODE:
403 xcamfilter->denoise_3d_mode = (Denoise3DModeType) g_value_get_enum (value);
404 break;
405 case PROP_ENABLE_WIREFRAME:
406 xcamfilter->enable_wireframe = g_value_get_boolean (value);
407 break;
408 case PROP_ENABLE_IMAGE_WARP:
409 xcamfilter->enable_image_warp = g_value_get_boolean (value);
410 break;
411 case PROP_ENABLE_IMAGE_STITCH:
412 xcamfilter->enable_stitch = g_value_get_boolean (value);
413 break;
414 case PROP_STITCH_ENABLE_SEAM:
415 xcamfilter->stitch_enable_seam = g_value_get_boolean (value);
416 break;
417 case PROP_STITCH_SCALE_MODE:
418 xcamfilter->stitch_scale_mode = (CLBlenderScaleMode) g_value_get_enum (value);
419 break;
420 case PROP_STITCH_FISHEYE_MAP:
421 xcamfilter->stitch_fisheye_map = g_value_get_boolean (value);
422 break;
423 case PROP_STITCH_LSC:
424 xcamfilter->stitch_lsc = g_value_get_boolean (value);
425 break;
426 #if HAVE_OPENCV
427 case PROP_STITCH_FM_OCL:
428 xcamfilter->stitch_fm_ocl = g_value_get_boolean (value);
429 break;
430 #endif
431 case PROP_STITCH_RES_MODE:
432 xcamfilter->stitch_res_mode = (StitchResMode) g_value_get_enum (value);
433 break;
434 default:
435 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
436 break;
437 }
438 }
439
440 static void
gst_xcam_filter_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)441 gst_xcam_filter_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
442 {
443 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (object);
444
445 switch (prop_id) {
446 case PROP_BUFFERCOUNT:
447 g_value_set_int (value, xcamfilter->buf_count);
448 break;
449 case PROP_COPY_MODE:
450 g_value_set_enum (value, xcamfilter->copy_mode);
451 break;
452 case PROP_DEFOG_MODE:
453 g_value_set_enum (value, xcamfilter->defog_mode);
454 break;
455 case PROP_WAVELET_MODE:
456 g_value_set_enum (value, xcamfilter->wavelet_mode);
457 break;
458 case PROP_DENOISE_3D_MODE:
459 g_value_set_enum (value, xcamfilter->denoise_3d_mode);
460 break;
461 case PROP_ENABLE_WIREFRAME:
462 g_value_set_boolean (value, xcamfilter->enable_wireframe);
463 break;
464 case PROP_ENABLE_IMAGE_WARP:
465 g_value_set_boolean (value, xcamfilter->enable_image_warp);
466 break;
467 case PROP_ENABLE_IMAGE_STITCH:
468 g_value_set_boolean (value, xcamfilter->enable_stitch);
469 break;
470 case PROP_STITCH_ENABLE_SEAM:
471 g_value_set_boolean (value, xcamfilter->stitch_enable_seam);
472 break;
473 case PROP_STITCH_SCALE_MODE:
474 g_value_set_enum (value, xcamfilter->stitch_scale_mode);
475 break;
476 case PROP_STITCH_FISHEYE_MAP:
477 g_value_set_boolean (value, xcamfilter->stitch_fisheye_map);
478 break;
479 case PROP_STITCH_LSC:
480 g_value_set_boolean (value, xcamfilter->stitch_lsc);
481 break;
482 #if HAVE_OPENCV
483 case PROP_STITCH_FM_OCL:
484 g_value_set_boolean (value, xcamfilter->stitch_fm_ocl);
485 break;
486 #endif
487 case PROP_STITCH_RES_MODE:
488 g_value_set_enum (value, xcamfilter->stitch_res_mode);
489 break;
490 default:
491 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
492 break;
493 }
494 }
495
496 static gboolean
gst_xcam_filter_start(GstBaseTransform * trans)497 gst_xcam_filter_start (GstBaseTransform *trans)
498 {
499 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (trans);
500
501 if (xcamfilter->buf_count <= xcamfilter->delay_buf_num) {
502 XCAM_LOG_ERROR (
503 "buffer count (%d) should be greater than delayed buffer number (%d)",
504 xcamfilter->buf_count,
505 xcamfilter->delay_buf_num);
506 return false;
507 }
508
509 SmartPtr<MainPipeManager> pipe_manager = xcamfilter->pipe_manager;
510 SmartPtr<SmartAnalyzer> smart_analyzer;
511 SmartPtr<CLPostImageProcessor> image_processor;
512
513 SmartHandlerList smart_handlers = SmartAnalyzerLoader::load_smart_handlers (DEFAULT_SMART_ANALYSIS_LIB_DIR);
514 if (!smart_handlers.empty ()) {
515 smart_analyzer = new SmartAnalyzer ();
516 if (smart_analyzer.ptr ()) {
517 SmartHandlerList::iterator i_handler = smart_handlers.begin ();
518 for (; i_handler != smart_handlers.end (); ++i_handler)
519 {
520 XCAM_ASSERT ((*i_handler).ptr ());
521 smart_analyzer->add_handler (*i_handler);
522 }
523 if (smart_analyzer->prepare_handlers () != XCAM_RETURN_NO_ERROR) {
524 XCAM_LOG_WARNING ("analyzer(%s) prepare handlers failed", smart_analyzer->get_name ());
525 return false;
526 }
527 pipe_manager->set_smart_analyzer (smart_analyzer);
528 } else {
529 XCAM_LOG_WARNING ("load smart analyzer(%s) failed, please check.", DEFAULT_SMART_ANALYSIS_LIB_DIR);
530 }
531 }
532
533 image_processor = new CLPostImageProcessor ();
534 XCAM_ASSERT (image_processor.ptr ());
535 image_processor->set_stats_callback (pipe_manager);
536 image_processor->set_defog_mode ((CLPostImageProcessor::CLDefogMode) xcamfilter->defog_mode);
537
538 if (NONE_WAVELET != xcamfilter->wavelet_mode) {
539 if (HAT_WAVELET_Y == xcamfilter->wavelet_mode) {
540 image_processor->set_wavelet (CL_WAVELET_HAT, CL_IMAGE_CHANNEL_Y, false);
541 } else if (HAT_WAVELET_UV == xcamfilter->wavelet_mode) {
542 image_processor->set_wavelet (CL_WAVELET_HAT, CL_IMAGE_CHANNEL_UV, false);
543 } else if (HARR_WAVELET_Y == xcamfilter->wavelet_mode) {
544 image_processor->set_wavelet (CL_WAVELET_HAAR, CL_IMAGE_CHANNEL_Y, false);
545 } else if (HARR_WAVELET_UV == xcamfilter->wavelet_mode) {
546 image_processor->set_wavelet (CL_WAVELET_HAAR, CL_IMAGE_CHANNEL_UV, false);
547 } else if (HARR_WAVELET_YUV == xcamfilter->wavelet_mode) {
548 image_processor->set_wavelet (CL_WAVELET_HAAR, CL_IMAGE_CHANNEL_UV | CL_IMAGE_CHANNEL_Y, false);
549 } else if (HARR_WAVELET_BAYES == xcamfilter->wavelet_mode) {
550 image_processor->set_wavelet (CL_WAVELET_HAAR, CL_IMAGE_CHANNEL_UV | CL_IMAGE_CHANNEL_Y, true);
551 } else {
552 image_processor->set_wavelet (CL_WAVELET_DISABLED, CL_IMAGE_CHANNEL_UV, false);
553 }
554 }
555
556 image_processor->set_3ddenoise_mode (
557 (CLPostImageProcessor::CL3DDenoiseMode) xcamfilter->denoise_3d_mode, xcamfilter->denoise_3d_ref_count);
558
559 image_processor->set_wireframe (xcamfilter->enable_wireframe);
560 image_processor->set_image_warp (xcamfilter->enable_image_warp);
561 if (smart_analyzer.ptr ()) {
562 if (xcamfilter->enable_wireframe)
563 image_processor->set_scaler (true);
564
565 if (xcamfilter->enable_image_warp) {
566 image_processor->set_scaler (true);
567 xcamfilter->delay_buf_num = DEFAULT_DELAY_BUFFER_NUM + 16;
568 }
569 }
570
571 pipe_manager->add_image_processor (image_processor);
572 pipe_manager->set_image_processor (image_processor);
573
574 xcamfilter->buf_pool = new CLVideoBufferPool ();
575 XCAM_ASSERT (xcamfilter->buf_pool.ptr ());
576 if (xcamfilter->copy_mode == COPY_MODE_DMA) {
577 XCAM_LOG_WARNING ("CLVideoBuffer doesn't support DMA copy mode, switch to CPU copy mode");
578 xcamfilter->copy_mode = COPY_MODE_CPU;
579 }
580
581 if (xcamfilter->copy_mode == COPY_MODE_DMA) {
582 xcamfilter->allocator = gst_dmabuf_allocator_new ();
583 if (!xcamfilter->allocator) {
584 GST_WARNING ("xcamfilter get allocator failed");
585 return false;
586 }
587 }
588
589 return true;
590 }
591
592 static gboolean
gst_xcam_filter_stop(GstBaseTransform * trans)593 gst_xcam_filter_stop (GstBaseTransform *trans)
594 {
595 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (trans);
596
597 SmartPtr<BufferPool> buf_pool = xcamfilter->buf_pool;
598 if (buf_pool.ptr ())
599 buf_pool->stop ();
600
601 SmartPtr<MainPipeManager> pipe_manager = xcamfilter->pipe_manager;
602 if (pipe_manager.ptr ())
603 pipe_manager->stop ();
604
605 return true;
606 }
607
608 static GstCaps *
gst_xcam_filter_transform_caps(GstBaseTransform * trans,GstPadDirection direction,GstCaps * caps,GstCaps * filter)609 gst_xcam_filter_transform_caps (
610 GstBaseTransform *trans, GstPadDirection direction, GstCaps *caps, GstCaps *filter)
611 {
612 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (trans);
613
614 GstCaps *src_caps, *peer_caps, *intersect_caps;
615 GstStructure *sink_struct, *src_struct;
616 GstPad *peer_pad;
617 gint sink_width, sink_height, src_width, src_height;
618
619 gboolean is_sink_width = false;
620 gboolean is_sink_height = false;
621
622 src_caps = gst_pad_get_pad_template_caps (trans->srcpad);
623
624 if (direction == GST_PAD_SRC || !gst_caps_is_fixed (caps))
625 goto filtering;
626
627 sink_struct = gst_caps_get_structure (caps, 0);
628 if (!gst_structure_get_int (sink_struct, "width", &sink_width) ||
629 !gst_structure_get_int (sink_struct, "height", &sink_height))
630 goto filtering;
631
632 peer_pad = gst_pad_get_peer (trans->srcpad);
633 peer_caps = gst_pad_query_caps (peer_pad, src_caps);
634 if (!peer_pad || gst_caps_is_empty (peer_caps)) {
635 if (xcamfilter->enable_stitch) {
636 src_height = XCAM_ALIGN_UP (sink_width / 2, 16);
637 if (src_height * 2 != sink_width) {
638 gst_caps_unref (src_caps);
639 gst_caps_unref (peer_caps);
640 XCAM_LOG_ERROR ("xcamfilter stitch incorrect size, sink-width(%d) / 2 should be aligned with 16",
641 sink_width);
642 return NULL;
643 }
644 src_width = sink_width;
645
646 gst_caps_unref (src_caps);
647 src_caps = gst_caps_copy (caps);
648 src_struct = gst_caps_get_structure (src_caps, 0);
649
650 gst_structure_set (src_struct, "width", G_TYPE_INT, src_width,
651 "height", G_TYPE_INT, src_height, NULL);
652 }
653
654 gst_caps_unref (peer_caps);
655 goto filtering;
656 }
657
658 intersect_caps = gst_caps_intersect_full (peer_caps, src_caps, GST_CAPS_INTERSECT_FIRST);
659 gst_caps_unref (src_caps);
660 src_caps = intersect_caps;
661
662 src_struct = gst_caps_get_structure (src_caps, 0);
663 if (!gst_structure_get_int (src_struct, "width", &src_width)) {
664 is_sink_width = true;
665 src_width = sink_width;
666 }
667 if (!gst_structure_get_int (src_struct, "height", &src_height)) {
668 is_sink_height = true;
669 src_height = sink_height;
670 }
671
672 if (xcamfilter->enable_stitch) {
673 if (is_sink_width && is_sink_height)
674 src_height = XCAM_ALIGN_UP (src_width / 2, 16);
675
676 if (src_width != src_height * 2) {
677 XCAM_LOG_ERROR ("xcamfilter incorrect stitch size width:%d height:%d", src_width, src_height);
678 gst_caps_unref (src_caps);
679 return NULL;
680 }
681 }
682
683 gint fps_n, fps_d;
684 if (!gst_structure_get_fraction (src_struct, "framerate", &fps_n, &fps_d) &&
685 !gst_structure_get_fraction (sink_struct, "framerate", &fps_n, &fps_d)) {
686 fps_n = 25;
687 fps_d = 1;
688 }
689
690 gst_structure_set (src_struct, "width", G_TYPE_INT, src_width,
691 "height", G_TYPE_INT, src_height,
692 "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL);
693
694 filtering:
695 if (filter) {
696 intersect_caps = gst_caps_intersect_full (filter, src_caps, GST_CAPS_INTERSECT_FIRST);
697 gst_caps_unref (src_caps);
698 src_caps = intersect_caps;
699 }
700
701 return src_caps;
702 }
703
704 static gboolean
gst_xcam_filter_set_caps(GstBaseTransform * trans,GstCaps * incaps,GstCaps * outcaps)705 gst_xcam_filter_set_caps (GstBaseTransform *trans, GstCaps *incaps, GstCaps *outcaps)
706 {
707 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (trans);
708 GstVideoInfo in_info, out_info;
709
710 if (!gst_video_info_from_caps (&in_info, incaps) ||
711 !gst_video_info_from_caps (&out_info, outcaps)) {
712 XCAM_LOG_WARNING ("fail to parse incaps or outcaps");
713 return false;
714 }
715
716 XCAM_FAIL_RETURN (
717 ERROR,
718 GST_VIDEO_INFO_FORMAT (&in_info) == GST_VIDEO_FORMAT_NV12 ||
719 GST_VIDEO_INFO_FORMAT (&out_info) == GST_VIDEO_FORMAT_NV12,
720 false,
721 "xcamfilter only support NV12 stream");
722 xcamfilter->gst_sink_video_info = in_info;
723 xcamfilter->gst_src_video_info = out_info;
724
725 SmartPtr<MainPipeManager> pipe_manager = xcamfilter->pipe_manager;
726 SmartPtr<CLPostImageProcessor> processor = pipe_manager->get_image_processor();
727 XCAM_ASSERT (pipe_manager.ptr () && processor.ptr ());
728 if (!processor->set_output_format (V4L2_PIX_FMT_NV12))
729 return false;
730
731 if (processor->is_scaled ())
732 processor->set_scaler_factor (640.0 / GST_VIDEO_INFO_WIDTH (&in_info));
733 //processor->set_scaler_factor (0.5f);
734
735 if (xcamfilter->enable_stitch) {
736 processor->set_image_stitch (
737 xcamfilter->enable_stitch, xcamfilter->stitch_enable_seam, xcamfilter->stitch_scale_mode,
738 xcamfilter->stitch_fisheye_map, xcamfilter->stitch_lsc, xcamfilter->stitch_fm_ocl,
739 GST_VIDEO_INFO_WIDTH (&out_info), GST_VIDEO_INFO_HEIGHT (&out_info), (uint32_t) xcamfilter->stitch_res_mode);
740 XCAM_LOG_INFO ("xcamfilter stitch output size width:%d height:%d",
741 GST_VIDEO_INFO_WIDTH (&out_info), GST_VIDEO_INFO_HEIGHT (&out_info));
742 }
743
744 if (pipe_manager->start () != XCAM_RETURN_NO_ERROR) {
745 XCAM_LOG_ERROR ("pipe manager start failed");
746 return false;
747 }
748
749 VideoBufferInfo buf_info;
750 buf_info.init (
751 V4L2_PIX_FMT_NV12,
752 GST_VIDEO_INFO_WIDTH (&in_info),
753 GST_VIDEO_INFO_HEIGHT (&in_info),
754 XCAM_ALIGN_UP (GST_VIDEO_INFO_WIDTH (&in_info), 16),
755 XCAM_ALIGN_UP (GST_VIDEO_INFO_HEIGHT (&in_info), 16));
756
757 SmartPtr<BufferPool> buf_pool = xcamfilter->buf_pool;
758 XCAM_ASSERT (buf_pool.ptr ());
759 if (!buf_pool->set_video_info (buf_info) ||
760 !buf_pool->reserve (xcamfilter->buf_count)) {
761 XCAM_LOG_ERROR ("init buffer pool failed");
762 return false;
763 }
764
765 return true;
766 }
767
768 static GstFlowReturn
copy_gstbuf_to_xcambuf(GstVideoInfo gstinfo,GstBuffer * gstbuf,SmartPtr<VideoBuffer> xcambuf)769 copy_gstbuf_to_xcambuf (GstVideoInfo gstinfo, GstBuffer *gstbuf, SmartPtr<VideoBuffer> xcambuf)
770 {
771 GstMapInfo mapinfo;
772 VideoBufferPlanarInfo planar;
773 const VideoBufferInfo xcaminfo = xcambuf->get_video_info ();
774
775 uint8_t *memory = xcambuf->map ();
776 gboolean ret = gst_buffer_map (gstbuf, &mapinfo, GST_MAP_READ);
777 if (!memory || !ret) {
778 XCAM_LOG_WARNING ("xcamfilter map buffer failed");
779 return GST_FLOW_ERROR;
780 }
781
782 uint8_t *src = NULL;
783 uint8_t *dest = NULL;
784 for (uint32_t index = 0; index < xcaminfo.components; index++) {
785 xcaminfo.get_planar_info (planar, index);
786
787 src = mapinfo.data + GST_VIDEO_INFO_PLANE_OFFSET (&gstinfo, index);
788 dest = memory + xcaminfo.offsets [index];
789 for (uint32_t i = 0; i < planar.height; i++) {
790 memcpy (dest, src, GST_VIDEO_INFO_WIDTH (&gstinfo));
791 src += GST_VIDEO_INFO_PLANE_STRIDE (&gstinfo, index);
792 dest += xcaminfo.strides [index];
793 }
794 }
795
796 gst_buffer_unmap (gstbuf, &mapinfo);
797 xcambuf->unmap ();
798
799 return GST_FLOW_OK;
800 }
801
802 static GstFlowReturn
copy_xcambuf_to_gstbuf(GstVideoInfo gstinfo,SmartPtr<VideoBuffer> xcambuf,GstBuffer ** gstbuf)803 copy_xcambuf_to_gstbuf (GstVideoInfo gstinfo, SmartPtr<VideoBuffer> xcambuf, GstBuffer **gstbuf)
804 {
805 GstMapInfo mapinfo;
806 VideoBufferPlanarInfo planar;
807 const VideoBufferInfo xcaminfo = xcambuf->get_video_info ();
808
809 GstBuffer *tmpbuf = gst_buffer_new_allocate (NULL, GST_VIDEO_INFO_SIZE (&gstinfo), NULL);
810 if (!tmpbuf) {
811 XCAM_LOG_ERROR ("xcamfilter allocate buffer failed");
812 return GST_FLOW_ERROR;
813 }
814
815 uint8_t *memory = xcambuf->map ();
816 gboolean ret = gst_buffer_map (tmpbuf, &mapinfo, GST_MAP_WRITE);
817 if (!memory || !ret) {
818 XCAM_LOG_WARNING ("xcamfilter map buffer failed");
819 return GST_FLOW_ERROR;
820 }
821
822 uint8_t *src = NULL;
823 uint8_t *dest = NULL;
824 for (uint32_t index = 0; index < GST_VIDEO_INFO_N_PLANES (&gstinfo); index++) {
825 xcaminfo.get_planar_info (planar, index);
826
827 src = memory + xcaminfo.offsets [index];
828 dest = mapinfo.data + GST_VIDEO_INFO_PLANE_OFFSET (&gstinfo, index);
829 for (uint32_t i = 0; i < planar.height; i++) {
830 memcpy (dest, src, planar.width);
831 src += xcaminfo.strides [index];
832 dest += GST_VIDEO_INFO_PLANE_STRIDE (&gstinfo, index);
833 }
834 }
835
836 gst_buffer_unmap (tmpbuf, &mapinfo);
837 xcambuf->unmap ();
838
839 *gstbuf = tmpbuf;
840
841 return GST_FLOW_OK;
842 }
843
844 static GstFlowReturn
append_xcambuf_to_gstbuf(GstAllocator * allocator,SmartPtr<VideoBuffer> xcambuf,GstBuffer ** gstbuf)845 append_xcambuf_to_gstbuf (GstAllocator *allocator, SmartPtr<VideoBuffer> xcambuf, GstBuffer **gstbuf)
846 {
847 gsize offsets [XCAM_VIDEO_MAX_COMPONENTS];
848
849 VideoBufferInfo xcaminfo = xcambuf->get_video_info ();
850 for (int i = 0; i < XCAM_VIDEO_MAX_COMPONENTS; i++) {
851 offsets [i] = xcaminfo.offsets [i];
852 }
853
854 GstBuffer *tmpbuf = gst_buffer_new ();
855 GstMemory *mem = gst_dmabuf_allocator_alloc (allocator, dup (xcambuf->get_fd ()), xcambuf->get_size ());
856 XCAM_ASSERT (mem);
857
858 gst_buffer_append_memory (tmpbuf, mem);
859
860 gst_buffer_add_video_meta_full (
861 tmpbuf,
862 GST_VIDEO_FRAME_FLAG_NONE,
863 GST_VIDEO_FORMAT_NV12,
864 xcaminfo.width,
865 xcaminfo.height,
866 xcaminfo.components,
867 offsets,
868 (gint *) (xcaminfo.strides));
869
870 *gstbuf = tmpbuf;
871
872 return GST_FLOW_OK;
873 }
874
875 static gint
get_dmabuf_fd(GstBuffer * buffer)876 get_dmabuf_fd (GstBuffer *buffer)
877 {
878 GstMemory *mem = gst_buffer_peek_memory (buffer, 0);
879 if (!gst_is_dmabuf_memory (mem)) {
880 return -1;
881 }
882
883 return gst_dmabuf_memory_get_fd (mem);
884 }
885
886 static void
gst_xcam_filter_before_transform(GstBaseTransform * trans,GstBuffer * buffer)887 gst_xcam_filter_before_transform (GstBaseTransform *trans, GstBuffer *buffer)
888 {
889 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (trans);
890
891 SmartPtr<BufferPool> buf_pool = xcamfilter->buf_pool;
892 SmartPtr<MainPipeManager> pipe_manager = xcamfilter->pipe_manager;
893 XCAM_ASSERT (buf_pool.ptr () && pipe_manager.ptr ());
894
895 if (xcamfilter->cached_buf_num > xcamfilter->delay_buf_num)
896 return;
897
898 SmartPtr<VideoBuffer> video_buf;
899 gint dma_fd = get_dmabuf_fd (buffer);
900 if (dma_fd >= 0) {
901 #if HAVE_LIBDRM
902 SmartPtr<DrmBoBufferPool> bo_buf_pool = buf_pool.dynamic_cast_ptr<DrmBoBufferPool> ();
903 SmartPtr<DrmDisplay> display = bo_buf_pool->get_drm_display ();
904 VideoBufferInfo info = bo_buf_pool->get_video_info ();
905
906 SmartPtr<VideoBuffer> dma_buf = new DmaGstBuffer (info, dma_fd, buffer);
907 video_buf = display->convert_to_drm_bo_buf (display, dma_buf);
908 #endif
909 if (!video_buf.ptr ()) {
910 XCAM_LOG_ERROR ("xcamfilter convert to drm bo buffer failed");
911 return;
912 }
913 } else {
914 video_buf = buf_pool->get_buffer (buf_pool);
915 if (!buf_pool.ptr ()) {
916 XCAM_LOG_ERROR ("xcamfilter sink-pad get buffer failed");
917 return;
918 }
919
920 copy_gstbuf_to_xcambuf (xcamfilter->gst_sink_video_info, buffer, video_buf);
921 }
922
923 if (pipe_manager->push_buffer (video_buf) != XCAM_RETURN_NO_ERROR) {
924 XCAM_LOG_ERROR ("xcamfilter push buffer failed");
925 return;
926 }
927
928 xcamfilter->cached_buf_num++;
929 }
930
931 static GstFlowReturn
gst_xcam_filter_prepare_output_buffer(GstBaseTransform * trans,GstBuffer * input,GstBuffer ** outbuf)932 gst_xcam_filter_prepare_output_buffer (GstBaseTransform *trans, GstBuffer *input, GstBuffer **outbuf)
933 {
934 GstXCamFilter *xcamfilter = GST_XCAM_FILTER (trans);
935 GstFlowReturn ret = GST_FLOW_OK;
936
937 SmartPtr<MainPipeManager> pipe_manager = xcamfilter->pipe_manager;
938 SmartPtr<VideoBuffer> video_buf;
939
940 if (xcamfilter->cached_buf_num > xcamfilter->buf_count)
941 return GST_FLOW_ERROR;
942
943 int32_t timeout = -1;
944 if (xcamfilter->cached_buf_num <= xcamfilter->delay_buf_num)
945 timeout = 0;
946
947 video_buf = pipe_manager->dequeue_buffer (timeout);
948 if (!video_buf.ptr ()) {
949 XCAM_LOG_WARNING ("xcamfilter dequeue buffer failed");
950 *outbuf = NULL;
951 return GST_FLOW_OK;
952 }
953
954 if (xcamfilter->copy_mode == COPY_MODE_CPU) {
955 ret = copy_xcambuf_to_gstbuf (xcamfilter->gst_src_video_info, video_buf, outbuf);
956 } else if (xcamfilter->copy_mode == COPY_MODE_DMA) {
957 GstAllocator *allocator = xcamfilter->allocator;
958 ret = append_xcambuf_to_gstbuf (allocator, video_buf, outbuf);
959 }
960
961 if (ret == GST_FLOW_OK) {
962 xcamfilter->cached_buf_num--;
963 GST_BUFFER_TIMESTAMP (*outbuf) = GST_BUFFER_TIMESTAMP (input);
964 }
965
966 return ret;
967 }
968
969 static GstFlowReturn
gst_xcam_filter_transform(GstBaseTransform * trans,GstBuffer * inbuf,GstBuffer * outbuf)970 gst_xcam_filter_transform (GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf)
971 {
972 XCAM_UNUSED (trans);
973 XCAM_UNUSED (inbuf);
974
975 if (!outbuf) {
976 XCAM_LOG_ERROR ("transform failed with null outbufer");
977 return GST_FLOW_ERROR;
978 }
979
980 XCAM_STATIC_FPS_CALCULATION (gstxcamfilter, XCAM_OBJ_DUR_FRAME_NUM);
981 return GST_FLOW_OK;
982 }
983
984 static gboolean
gst_xcam_filter_plugin_init(GstPlugin * xcamfilter)985 gst_xcam_filter_plugin_init (GstPlugin *xcamfilter)
986 {
987 return gst_element_register (xcamfilter, "xcamfilter", GST_RANK_NONE,
988 GST_TYPE_XCAM_FILTER);
989 }
990
991 #ifndef PACKAGE
992 #define PACKAGE "libxam"
993 #endif
994
995 GST_PLUGIN_DEFINE (
996 GST_VERSION_MAJOR,
997 GST_VERSION_MINOR,
998 xcamfilter,
999 "Libxcam filter plugin",
1000 gst_xcam_filter_plugin_init,
1001 VERSION,
1002 GST_LICENSE_UNKNOWN,
1003 "libxcamfilter",
1004 "https://github.com/01org/libxcam"
1005 )
1006