| /* |
| * gstxcamsrc.cpp - gst xcamsrc plugin |
| * |
| * Copyright (c) 2015 Intel Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * Author: John Ye <john.ye@intel.com> |
| */ |
| |
| /** |
| * SECTION:element-xcamsrc |
| * |
| * FIXME:Describe xcamsrc here. |
| * |
| * <refsect2> |
| * <title>Example launch line</title> |
| * |[ |
| * gst-launch-1.0 xcamsrc sensor=0 capturemode=0x4000 memtype=4 buffercount=8 fpsn=25 fpsd=1 \ |
| * width=1920 height=1080 pixelformat=0 field=0 bytesperline=3840 ! video/x-raw, format=NV12, \ |
| * width=1920, height=1080, framerate=30/1 ! queue ! vaapiencode_h264 ! fakesink |
| * ]| |
| * </refsect2> |
| */ |
| |
| #include "gstxcamsrc.h" |
| #include "v4l2dev.h" |
| #include "stub.h" |
| #include "fmt.h" |
| |
| using namespace XCam; |
| |
| XCAM_BEGIN_DECLARE |
| |
| #ifdef HAVE_CONFIG_H |
| # include <config.h> |
| #endif |
| |
| #include <gst/gst.h> |
| #include <gst/video/video.h> |
| #include <gst/video/video-format.h> |
| #include <linux/videodev2.h> |
| |
| #include <stdio.h> |
| #include <signal.h> |
| |
| #include "gstxcamsrc.h" |
| #include "gstxcaminterface.h" |
| |
| |
| GST_DEBUG_CATEGORY_STATIC (gst_xcamsrc_debug); |
| #define GST_CAT_DEFAULT gst_xcamsrc_debug |
| |
| |
| enum |
| { |
| PROP_0, |
| PROP_DEVICE, |
| PROP_COLOREFFECT, |
| PROP_SENSOR, |
| PROP_CAPTURE_MODE, |
| PROP_ENABLE_3A, |
| PROP_IO_MODE, |
| PROP_BUFFERCOUNT, |
| PROP_FPSN, |
| PROP_FPSD, |
| PROP_WIDTH, |
| PROP_HEIGHT, |
| PROP_PIXELFORMAT, |
| PROP_FIELD, |
| PROP_BYTESPERLINE |
| }; |
| |
| static void gst_xcamsrc_xcam_3a_interface_init (GstXCam3AInterface *iface); |
| |
| #define gst_xcamsrc_parent_class parent_class |
| G_DEFINE_TYPE_WITH_CODE (Gstxcamsrc, gst_xcamsrc, GST_TYPE_PUSH_SRC, |
| G_IMPLEMENT_INTERFACE (GST_TYPE_XCAM_3A_IF, |
| gst_xcamsrc_xcam_3a_interface_init)); |
| |
| GstCaps *gst_xcamsrc_get_all_caps (void); |
| |
| static void gst_xcamsrc_finalize (GObject * object); |
| static void gst_xcamsrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); |
| static void gst_xcamsrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); |
| static GstCaps* gst_xcamsrc_get_caps (GstBaseSrc *src, GstCaps *filter); |
| static gboolean gst_xcamsrc_set_caps (GstBaseSrc *src, GstCaps *caps); |
| static gboolean gst_xcamsrc_start (GstBaseSrc *src); |
| static gboolean gst_xcamsrc_stop (GstBaseSrc * basesrc); |
| static GstFlowReturn gst_xcamsrc_alloc (GstBaseSrc *src, guint64 offset, guint size, GstBuffer **buffer); |
| static GstFlowReturn gst_xcamsrc_fill (GstPushSrc *src, GstBuffer *out); |
| |
| static gboolean xcamsrc_init (GstPlugin * xcamsrc); |
| |
| XCAM_END_DECLARE |
| |
| static void |
| gst_xcamsrc_class_init (GstxcamsrcClass * klass) |
| { |
| GObjectClass *gobject_class; |
| GstElementClass *element_class; |
| GstBaseSrcClass *basesrc_class; |
| GstPushSrcClass *pushsrc_class; |
| |
| gobject_class = (GObjectClass *) klass; |
| element_class = (GstElementClass *) klass; |
| basesrc_class = GST_BASE_SRC_CLASS (klass); |
| pushsrc_class = GST_PUSH_SRC_CLASS (klass); |
| |
| gobject_class->finalize = gst_xcamsrc_finalize; |
| gobject_class->set_property = gst_xcamsrc_set_property; |
| gobject_class->get_property = gst_xcamsrc_get_property; |
| |
| g_object_class_install_property (gobject_class, PROP_DEVICE, |
| g_param_spec_string ("device", "Device", "Device location", |
| DEFAULT_PROP_DEVICE_NAME, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); |
| |
| g_object_class_install_property (gobject_class, PROP_COLOREFFECT, |
| g_param_spec_int ("coloreffect", "color effect", "0, none\t 1,sky blue\t 2,skin whiten low\t 3,skin whiten\t 4,skin whiten hight\t 5,sepia", |
| G_MININT, G_MAXINT, 0, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE))); |
| |
| g_object_class_install_property (gobject_class, PROP_ENABLE_3A, |
| g_param_spec_boolean ("enable-3a", "Enable 3A", "Enable 3A", |
| true, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); |
| |
| g_object_class_install_property (gobject_class, PROP_SENSOR, |
| g_param_spec_int ("sensor-id", "Sensor id", "Sensor id to input", |
| 0, G_MAXINT, DEFAULT_PROP_SENSOR, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| |
| g_object_class_install_property (gobject_class, PROP_CAPTURE_MODE, |
| g_param_spec_int ("capture-mode", "capture mode", "capture mode", |
| 0, G_MAXINT, DEFAULT_PROP_CAPTURE_MODE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_IO_MODE, |
| g_param_spec_int ("io-mode", "IO mode", "I/O mode", |
| 0, G_MAXINT, DEFAULT_PROP_IO_MODE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_BUFFERCOUNT, |
| g_param_spec_int ("buffercount", "buffer count", "buffer count", |
| 0, G_MAXINT, DEFAULT_PROP_BUFFERCOUNT, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_FPSN, |
| g_param_spec_int ("fpsn", "fps n", "fps n", |
| 0 , G_MAXINT, DEFAULT_PROP_FPSN, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_FPSD, |
| g_param_spec_int ("fpsd", "fps d", "fps d", |
| 0, G_MAXINT, DEFAULT_PROP_FPSD, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_WIDTH, |
| g_param_spec_int ("width", "width", "width", |
| 0, G_MAXINT, DEFAULT_PROP_WIDTH, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_HEIGHT, |
| g_param_spec_int ("height", "height", "height", |
| 0, G_MAXINT, DEFAULT_PROP_HEIGHT, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_PIXELFORMAT, |
| g_param_spec_int ("pixelformat", "pixelformat", "pixelformat", |
| 0, G_MAXINT, DEFAULT_PROP_PIXELFORMAT, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_FIELD, |
| g_param_spec_int ("field", "field", "field", |
| 0, G_MAXINT, DEFAULT_PROP_FIELD, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| g_object_class_install_property (gobject_class, PROP_BYTESPERLINE, |
| g_param_spec_int ("bytesperline", "bytes perline", "bytes perline", |
| 0, G_MAXINT, DEFAULT_PROP_BYTESPERLINE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) )); |
| |
| gst_element_class_set_details_simple(element_class, |
| "Libxcam Source", |
| "Source/Base", |
| "Capture camera video using xcam library", |
| "John Ye <john.ye@intel.com>"); |
| |
| gst_element_class_add_pad_template (element_class, |
| gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, gst_xcamsrc_get_all_caps ())); |
| |
| basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_xcamsrc_get_caps); |
| basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_xcamsrc_set_caps); |
| basesrc_class->alloc = GST_DEBUG_FUNCPTR (gst_xcamsrc_alloc); |
| |
| basesrc_class->start = GST_DEBUG_FUNCPTR (gst_xcamsrc_start); |
| basesrc_class->stop = GST_DEBUG_FUNCPTR (gst_xcamsrc_stop); |
| pushsrc_class->fill = GST_DEBUG_FUNCPTR (gst_xcamsrc_fill); |
| } |
| |
| // FIXME remove this function? |
| static void |
| gst_xcamsrc_init (Gstxcamsrc *xcamsrc) |
| { |
| MainDeviceManager::set_capture_device_name (DEFAULT_CAPTURE_DEVICE); |
| MainDeviceManager::set_event_device_name (DEFAULT_EVENT_DEVICE); |
| MainDeviceManager::set_cpf_file_name (DEFAULT_CPF_FILE_NAME); |
| |
| gst_base_src_set_format (GST_BASE_SRC (xcamsrc), GST_FORMAT_TIME); |
| gst_base_src_set_live (GST_BASE_SRC (xcamsrc), TRUE); |
| |
| xcamsrc->buf_count = DEFAULT_PROP_BUFFERCOUNT; //8 |
| xcamsrc->_fps_n = DEFAULT_PROP_FPSN; //25 |
| xcamsrc->_fps_d = DEFAULT_PROP_FPSD; //1 |
| xcamsrc->width = DEFAULT_PROP_WIDTH; //1920 |
| xcamsrc->height = DEFAULT_PROP_HEIGHT; //1080 |
| xcamsrc->pixelformat = V4L2_PIX_FMT_NV12; //420 |
| xcamsrc->field = V4L2_FIELD_NONE; //0 |
| xcamsrc->bytes_perline = DEFAULT_PROP_BYTESPERLINE; // 3840 |
| |
| gst_base_src_set_blocksize (GST_BASE_SRC (xcamsrc), DEFAULT_BLOCKSIZE); |
| } |
| |
| static void |
| gst_xcamsrc_finalize (GObject * object) |
| { |
| G_OBJECT_CLASS (parent_class)->finalize (object); |
| } |
| |
| static gboolean |
| gst_xcamsrc_start (GstBaseSrc *src) |
| { |
| Gstxcamsrc *xcamsrc = GST_XCAMSRC (src); |
| |
| xcamsrc->offset = 0; |
| xcamsrc->ctrl_time = 0; |
| |
| gst_object_sync_values (GST_OBJECT (src), xcamsrc->ctrl_time); |
| |
| return TRUE; |
| } |
| |
| static gboolean |
| gst_xcamsrc_stop (GstBaseSrc * basesrc) |
| { |
| Gstxcamsrc *src = GST_XCAMSRC_CAST (basesrc); |
| SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance(); |
| |
| device_manager->stop(); |
| device_manager->get_device()->close (); |
| device_manager->get_sub_device()->close (); |
| return TRUE; |
| } |
| |
| static GstCaps* |
| gst_xcamsrc_get_caps (GstBaseSrc *src, GstCaps *filter) |
| { |
| Gstxcamsrc *xcamsrc = GST_XCAMSRC (src); |
| return gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (xcamsrc)); |
| } |
| |
| extern "C" GstBufferPool * |
| gst_xcambufferpool_new (Gstxcamsrc *xcamsrc, GstCaps *caps); |
| |
| static gboolean |
| gst_xcamsrc_set_caps (GstBaseSrc *src, GstCaps *caps) |
| { |
| Gstxcamsrc *xcamsrc = GST_XCAMSRC (src); |
| |
| guint32 block_size = DEFAULT_BLOCKSIZE; |
| SmartPtr<MainDeviceManager> device_manager = DeviceManagerInstance::device_manager_instance(); |
| SmartPtr<V4l2Device> device = device_manager->get_device(); |
| |
| /** |
| * set_sensor_id |
| * set_capture_mode |
| * set_mem_type |
| * set_buffer_count |
| * set_framerate |
| * open |
| * set_format |
| * |
| **/ |
| device->set_buffer_count (xcamsrc->buf_count); |
| device->set_framerate (xcamsrc->_fps_n, xcamsrc->_fps_d); |
| device->open (); |
| device->set_format (xcamsrc->width, xcamsrc->height, xcamsrc->pixelformat, xcamsrc->field, xcamsrc->bytes_perline); |
| |
| struct v4l2_format format; |
| device->get_format (format); |
| block_size = format.fmt.pix.sizeimage; |
| |
| gst_base_src_set_blocksize (GST_BASE_SRC (xcamsrc), block_size); |
| |
| xcamsrc->duration = gst_util_uint64_scale_int (GST_SECOND, xcamsrc->_fps_d, xcamsrc->_fps_n); |
| xcamsrc->pool = gst_xcambufferpool_new ((Gstxcamsrc*)src, caps); |
| |
| gst_buffer_pool_set_active (GST_BUFFER_POOL_CAST (xcamsrc->pool), TRUE); |
| return TRUE; |
| } |
| |
| |
| |
| static GstFlowReturn gst_xcamsrc_alloc (GstBaseSrc *src, guint64 offset, guint size, GstBuffer **buffer) |
| { |
| GstFlowReturn ret; |
| Gstxcamsrc *xcamsrc = GST_XCAMSRC (src); |
| |
| ret = gst_buffer_pool_acquire_buffer (xcamsrc->pool, buffer, NULL); |
| return ret; |
| } |
| |
| // FIXME: timestamp is already set in xcore, isn't it? |
| static GstFlowReturn |
| gst_xcamsrc_fill (GstPushSrc *basesrc, GstBuffer *buf) |
| { |
| Gstxcamsrc *src = GST_XCAMSRC_CAST (basesrc); |
| GstClockTime abs_time, base_time, timestamp, duration; |
| GstClock *clock; |
| GstClockTime delay; |
| |
| timestamp = GST_BUFFER_TIMESTAMP (buf); |
| duration = src->duration; |
| |
| GST_OBJECT_LOCK (src); |
| if ((clock = GST_ELEMENT_CLOCK (src))) { |
| base_time = GST_ELEMENT (src)->base_time; |
| gst_object_ref (clock); |
| } else { |
| base_time = GST_CLOCK_TIME_NONE; |
| } |
| GST_OBJECT_UNLOCK (src); |
| |
| if (clock) { |
| abs_time = gst_clock_get_time (clock); |
| gst_object_unref (clock); |
| } else { |
| abs_time = GST_CLOCK_TIME_NONE; |
| } |
| |
| if (timestamp != GST_CLOCK_TIME_NONE) { |
| struct timespec now; |
| GstClockTime gstnow; |
| |
| clock_gettime (CLOCK_MONOTONIC, &now); |
| gstnow = GST_TIMESPEC_TO_TIME (now); |
| |
| if (gstnow < timestamp && (timestamp - gstnow) > (10 * GST_SECOND)) { |
| GTimeVal now; |
| |
| g_get_current_time (&now); |
| gstnow = GST_TIMEVAL_TO_TIME (now); |
| } |
| if (gstnow > timestamp) { |
| delay = gstnow - timestamp; |
| } else { |
| delay = 0; |
| } |
| } else { |
| if (GST_CLOCK_TIME_IS_VALID (duration)) |
| delay = duration; |
| else |
| delay = 0; |
| } |
| |
| GST_BUFFER_OFFSET (buf) = src->offset++; |
| GST_BUFFER_OFFSET_END (buf) = src->offset; |
| |
| if (G_LIKELY (abs_time != GST_CLOCK_TIME_NONE)) { |
| timestamp = abs_time - base_time; |
| |
| if (timestamp > delay) |
| timestamp -= delay; |
| else |
| timestamp = 0; |
| } else { |
| timestamp = GST_CLOCK_TIME_NONE; |
| } |
| |
| if (GST_CLOCK_TIME_IS_VALID (duration)) { |
| src->ctrl_time += duration; |
| } else { |
| src->ctrl_time = timestamp; |
| } |
| |
| gst_object_sync_values (GST_OBJECT (src), src->ctrl_time); |
| |
| GST_BUFFER_TIMESTAMP (buf) = timestamp; |
| GST_BUFFER_DURATION (buf) = duration; |
| |
| return GST_FLOW_OK; |
| } |
| |
| static void gst_xcamsrc_get_property (GObject *object, |
| guint prop_id, GValue *value, GParamSpec *pspec) |
| { |
| //TODO |
| } |
| |
| // FIXME do we need to support all these properties? |
| static void gst_xcamsrc_set_property (GObject *object, |
| guint prop_id, const GValue *value, GParamSpec *pspec) |
| { |
| Gstxcamsrc *src = GST_XCAMSRC (object); |
| int val; |
| enum v4l2_memory set_val; |
| SmartPtr<V4l2Device> device = DeviceManagerInstance::device_manager_instance()->get_device(); |
| |
| switch (prop_id) { |
| case PROP_DEVICE: |
| case PROP_ENABLE_3A: |
| case PROP_COLOREFFECT: |
| break; |
| case PROP_SENSOR: |
| device->set_sensor_id (g_value_get_int (value)); |
| break; |
| case PROP_CAPTURE_MODE: |
| val = g_value_get_int (value); |
| device->set_capture_mode (1 << (13 + val)); |
| break; |
| case PROP_IO_MODE: |
| val = g_value_get_int (value); |
| if (val == 1) |
| set_val = V4L2_MEMORY_MMAP; |
| else if (val == 2) |
| set_val = V4L2_MEMORY_USERPTR; |
| else if (val == 3) |
| set_val = V4L2_MEMORY_OVERLAY; |
| else |
| set_val = V4L2_MEMORY_DMABUF; |
| device->set_mem_type (set_val); |
| break; |
| case PROP_BUFFERCOUNT: |
| src->buf_count = g_value_get_int (value); |
| break; |
| case PROP_FPSN: |
| src->_fps_n = g_value_get_int (value); |
| break; |
| case PROP_FPSD: |
| src->_fps_d = g_value_get_int (value); |
| break; |
| case PROP_WIDTH: |
| src->width = g_value_get_int (value); |
| break; |
| case PROP_HEIGHT: |
| src->height = g_value_get_int (value); |
| break; |
| case PROP_PIXELFORMAT: |
| // FIXME |
| src->pixelformat = V4L2_PIX_FMT_NV12; |
| break; |
| case PROP_FIELD: |
| // TODO |
| src->field = V4L2_FIELD_NONE; |
| break; |
| case PROP_BYTESPERLINE: |
| src->bytes_perline = g_value_get_int (value); |
| break; |
| default: |
| G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
| break; |
| } |
| } |
| |
| GstCaps * |
| gst_xcamsrc_get_all_caps (void) |
| { |
| static GstCaps *caps = NULL; |
| if (caps == NULL) { |
| caps = gst_caps_new_empty (); |
| caps_append(caps); |
| } |
| return gst_caps_ref (caps); |
| } |
| |
| static void |
| gst_xcamsrc_xcam_3a_interface_init (GstXCam3AInterface *iface) |
| { |
| iface->set_white_balance_mode = gst_xcamsrc_set_white_balance_mode; |
| iface->set_awb_speed = gst_xcamsrc_set_awb_speed; |
| |
| iface->set_wb_color_temperature_range = gst_xcamsrc_set_wb_color_temperature_range; |
| iface->set_manual_wb_gain = gst_xcamsrc_set_manual_wb_gain; |
| |
| iface->set_exposure_mode = gst_xcamsrc_set_exposure_mode; |
| iface->set_ae_metering_mode = gst_xcamsrc_set_ae_metering_mode; |
| iface->set_exposure_window = gst_xcamsrc_set_exposure_window; |
| iface->set_exposure_value_offset = gst_xcamsrc_set_exposure_value_offset; |
| iface->set_ae_speed = gst_xcamsrc_set_ae_speed; |
| |
| iface->set_exposure_flicker_mode = gst_xcamsrc_set_exposure_flicker_mode; |
| iface->get_exposure_flicker_mode = gst_xcamsrc_get_exposure_flicker_mode; |
| iface->get_current_exposure_time = gst_xcamsrc_get_current_exposure_time; |
| iface->get_current_analog_gain = gst_xcamsrc_get_current_analog_gain; |
| iface->set_manual_exposure_time = gst_xcamsrc_set_manual_exposure_time; |
| iface->set_manual_analog_gain = gst_xcamsrc_set_manual_analog_gain; |
| iface->set_aperture = gst_xcamsrc_set_aperture; |
| iface->set_max_analog_gain = gst_xcamsrc_set_max_analog_gain; |
| iface->get_max_analog_gain = gst_xcamsrc_get_max_analog_gain; |
| iface->set_exposure_time_range = gst_xcamsrc_set_exposure_time_range; |
| iface->get_exposure_time_range = gst_xcamsrc_get_exposure_time_range; |
| iface->set_dvs = gst_xcamsrc_set_dvs; |
| iface->set_noise_reduction_level = gst_xcamsrc_set_noise_reduction_level; |
| iface->set_temporal_noise_reduction_level = gst_xcamsrc_set_temporal_noise_reduction_level; |
| iface->set_gamma_table = gst_xcamsrc_set_gamma_table; |
| iface->set_gbce = gst_xcamsrc_set_gbce; |
| iface->set_manual_brightness = gst_xcamsrc_set_manual_brightness; |
| iface->set_manual_contrast = gst_xcamsrc_set_manual_contrast; |
| iface->set_manual_hue = gst_xcamsrc_set_manual_hue; |
| iface->set_manual_saturation = gst_xcamsrc_set_manual_saturation; |
| iface->set_manual_sharpness = gst_xcamsrc_set_manual_sharpness; |
| iface->set_night_mode = gst_xcamsrc_set_night_mode; |
| } |
| |
| static gboolean |
| xcamsrc_init (GstPlugin * xcamsrc) |
| { |
| GST_DEBUG_CATEGORY_INIT (gst_xcamsrc_debug, "xcamsrc", |
| 0, "xcamsrc"); |
| |
| return gst_element_register (xcamsrc, "xcamsrc", GST_RANK_NONE, |
| GST_TYPE_XCAMSRC); |
| } |
| |
| #ifndef PACKAGE |
| #define PACKAGE "libxam" |
| #endif |
| |
| GST_PLUGIN_DEFINE ( |
| GST_VERSION_MAJOR, |
| GST_VERSION_MINOR, |
| xcamsrc, |
| "xcamsrc", |
| xcamsrc_init, |
| VERSION, |
| GST_LICENSE_UNKNOWN, |
| "Xcamsrc", |
| "https://github.com/01org/libxcam" |
| ) |