diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index f620de147d..491034979a 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -229,6 +229,7 @@ EXTRA_HFILES = \ $(top_srcdir)/sys/osxvideo/osxvideosink.h \ $(top_srcdir)/sys/v4l2/gstv4l2src.h \ $(top_srcdir)/sys/v4l2/gstv4l2sink.h \ + $(top_srcdir)/sys/v4l2/gstv4l2radio.h \ $(top_srcdir)/sys/waveform/gstwaveformsink.h \ $(top_srcdir)/sys/ximage/gstximagesrc.h diff --git a/docs/plugins/gst-plugins-good-plugins-docs.sgml b/docs/plugins/gst-plugins-good-plugins-docs.sgml index 459a064c83..988bba3417 100644 --- a/docs/plugins/gst-plugins-good-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-good-plugins-docs.sgml @@ -154,6 +154,7 @@ + diff --git a/docs/plugins/gst-plugins-good-plugins-sections.txt b/docs/plugins/gst-plugins-good-plugins-sections.txt index 6081c67633..b2e6de68cf 100644 --- a/docs/plugins/gst-plugins-good-plugins-sections.txt +++ b/docs/plugins/gst-plugins-good-plugins-sections.txt @@ -2048,6 +2048,20 @@ GST_IS_V4L2SINK_CLASS gst_v4l2sink_get_type +
+element-v4l2radio +v4l2radio +GstV4l2Radio + +GstV4l2RadioClass +GST_V4L2RADIO +GST_IS_V4L2RADIO +GST_TYPE_V4L2RADIO +GST_V4L2RADIO_CLASS +GST_IS_V4L2RADIO_CLASS +gst_v4l2radio_get_type +
+
element-waveformsink waveformsink diff --git a/docs/plugins/inspect/plugin-video4linux2.xml b/docs/plugins/inspect/plugin-video4linux2.xml index 5204cc02fa..8349f913d3 100644 --- a/docs/plugins/inspect/plugin-video4linux2.xml +++ b/docs/plugins/inspect/plugin-video4linux2.xml @@ -24,5 +24,12 @@ + + v4l2radio + Radio (video4linux2) Tuner + Tuner + Controls a Video4Linux2 radio device + Alexey Chernov <4ernov@gmail.com> + - \ No newline at end of file + diff --git a/sys/v4l2/Makefile.am b/sys/v4l2/Makefile.am index ab996a15a8..a7a99dea31 100644 --- a/sys/v4l2/Makefile.am +++ b/sys/v4l2/Makefile.am @@ -13,6 +13,7 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.c \ gstv4l2object.c \ gstv4l2bufferpool.c \ gstv4l2src.c \ + gstv4l2radio.c \ gstv4l2tuner.c \ gstv4l2vidorient.c \ v4l2_calls.c \ @@ -51,6 +52,7 @@ noinst_HEADERS = \ gstv4l2object.h \ gstv4l2sink.h \ gstv4l2src.h \ + gstv4l2radio.h \ gstv4l2tuner.h \ gstv4l2vidorient.h \ gstv4l2xoverlay.h \ diff --git a/sys/v4l2/gstv4l2.c b/sys/v4l2/gstv4l2.c index 4a7056fd52..95f64db785 100644 --- a/sys/v4l2/gstv4l2.c +++ b/sys/v4l2/gstv4l2.c @@ -35,6 +35,7 @@ #ifdef HAVE_EXPERIMENTAL #include "gstv4l2sink.h" #endif +#include "gstv4l2radio.h" /* #include "gstv4l2jpegsrc.h" */ /* #include "gstv4l2mjpegsrc.h" */ /* #include "gstv4l2mjpegsink.h" */ @@ -58,6 +59,8 @@ plugin_init (GstPlugin * plugin) !gst_element_register (plugin, "v4l2sink", GST_RANK_NONE, GST_TYPE_V4L2SINK) || #endif + !gst_element_register (plugin, "v4l2radio", GST_RANK_NONE, + GST_TYPE_V4L2RADIO) || /* !gst_element_register (plugin, "v4l2jpegsrc", */ /* GST_RANK_NONE, GST_TYPE_V4L2JPEGSRC) || */ /* !gst_element_register (plugin, "v4l2mjpegsrc", */ diff --git a/sys/v4l2/gstv4l2radio.c b/sys/v4l2/gstv4l2radio.c new file mode 100644 index 0000000000..b1699d3814 --- /dev/null +++ b/sys/v4l2/gstv4l2radio.c @@ -0,0 +1,633 @@ +/* GStreamer v4l2 radio tuner element + * Copyright (C) 2010, 2011 Alexey Chernov <4ernov@gmail.com> + * + * gstv4l2radio.c - V4L2 radio tuner element + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:element-v4l2radio + * + * v4l2radio can be used to control radio device + * and to tune it to different radiostations. + * + * + * Example launch lines + * |[ + * gst-launch v4l2radio device=/dev/radio0 frequency=101200000 + * gst-launch alsasrc device=hw:1 ! audioconvert ! audioresample ! alsasink + * ]| + * First pipeline tunes the radio device /dev/radio0 to station 101.2 MHz, + * second pipeline connects digital audio out (hw:1) to default sound card. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "gst/gst-i18n-plugin.h" + +#include "gstv4l2tuner.h" +#include "gstv4l2radio.h" +#include "v4l2_calls.h" + +GST_DEBUG_CATEGORY_STATIC (v4l2radio_debug); +#define GST_CAT_DEFAULT v4l2radio_debug + +#define DEFAULT_PROP_DEVICE "/dev/radio0" +#define MIN_FREQUENCY 87500000 +#define DEFAULT_FREQUENCY 100000000 +#define MAX_FREQUENCY 108000000 + +enum +{ + ARG_0, + ARG_DEVICE, + ARG_FREQUENCY +}; + +static gboolean +gst_v4l2radio_fill_channel_list (GstV4l2Radio * radio) +{ + int res; + struct v4l2_tuner vtun; + struct v4l2_capability vc; + GstV4l2TunerChannel *v4l2channel; + GstTunerChannel *channel; + + GstElement *e; + + GstV4l2Object *v4l2object; + + e = GST_ELEMENT (radio); + v4l2object = radio->v4l2object; + + GST_DEBUG_OBJECT (e, "getting audio enumeration"); + GST_V4L2_CHECK_OPEN (v4l2object); + + GST_DEBUG_OBJECT (e, " audio input"); + + memset (&vc, 0, sizeof (vc)); + + res = v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP, &vc); + if (res < 0) + goto caps_failed; + + if (!(vc.capabilities & V4L2_CAP_TUNER)) + goto not_a_tuner; + + /* getting audio input */ + memset (&vtun, 0, sizeof (vtun)); + vtun.index = 0; + + res = v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_TUNER, &vtun); + if (res < 0) + goto tuner_failed; + + GST_LOG_OBJECT (e, " index: %d", vtun.index); + GST_LOG_OBJECT (e, " name: '%s'", vtun.name); + GST_LOG_OBJECT (e, " type: %016x", (guint) vtun.type); + GST_LOG_OBJECT (e, " caps: %016x", (guint) vtun.capability); + GST_LOG_OBJECT (e, " rlow: %016x", (guint) vtun.rangelow); + GST_LOG_OBJECT (e, " rhigh: %016x", (guint) vtun.rangehigh); + GST_LOG_OBJECT (e, " audmode: %016x", (guint) vtun.audmode); + + v4l2channel = g_object_new (GST_TYPE_V4L2_TUNER_CHANNEL, NULL); + channel = GST_TUNER_CHANNEL (v4l2channel); + channel->label = g_strdup ((const gchar *) vtun.name); + channel->flags = GST_TUNER_CHANNEL_FREQUENCY | GST_TUNER_CHANNEL_AUDIO; + v4l2channel->index = 0; + v4l2channel->tuner = 0; + + channel->freq_multiplicator = + 62.5 * ((vtun.capability & V4L2_TUNER_CAP_LOW) ? 1 : 1000); + channel->min_frequency = vtun.rangelow * channel->freq_multiplicator; + channel->max_frequency = vtun.rangehigh * channel->freq_multiplicator; + channel->min_signal = 0; + channel->max_signal = 0xffff; + + v4l2object->channels = + g_list_prepend (v4l2object->channels, (gpointer) channel); + + v4l2object->channels = g_list_reverse (v4l2object->channels); + + GST_DEBUG_OBJECT (e, "done"); + return TRUE; + + /* ERRORS */ +tuner_failed: + { + GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS, + (_("Failed to get settings of tuner %d on device '%s'."), + vtun.index, v4l2object->videodev), GST_ERROR_SYSTEM); + return FALSE; + } +caps_failed: + { + GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS, + (_("Error getting capabilities for device '%s'."), + v4l2object->videodev), GST_ERROR_SYSTEM); + return FALSE; + } +not_a_tuner: + { + GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS, + (_("Device '%s' is not a tuner."), + v4l2object->videodev), GST_ERROR_SYSTEM); + return FALSE; + } +} + +static gboolean +gst_v4l2radio_get_input (GstV4l2Object * v4l2object, gint * input) +{ + GST_DEBUG_OBJECT (v4l2object->element, "trying to get radio input"); + + if (!GST_V4L2_IS_OPEN (v4l2object)) + return FALSE; + + if (!v4l2object->channels) + goto input_failed; + + *input = 0; + + GST_DEBUG_OBJECT (v4l2object->element, "input: %d", 0); + + return TRUE; + + /* ERRORS */ +input_failed: + { + GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, + (_("Failed to get radio input on device '%s'. "), + v4l2object->videodev), GST_ERROR_SYSTEM); + return FALSE; + } +} + +static gboolean +gst_v4l2radio_set_input (GstV4l2Object * v4l2object, gint input) +{ + GST_DEBUG_OBJECT (v4l2object->element, "trying to set input to %d", input); + + if (!GST_V4L2_IS_OPEN (v4l2object)) + return FALSE; + + if (!v4l2object->channels) + goto input_failed; + + return TRUE; + + /* ERRORS */ +input_failed: + { + GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS, + (_("Failed to set input %d on device %s."), + input, v4l2object->videodev), GST_ERROR_SYSTEM); + return FALSE; + } +} + +static gboolean +gst_v4l2radio_set_mute_on (GstV4l2Radio * radio, gboolean on) +{ + gint res; + struct v4l2_control vctrl; + + GST_DEBUG_OBJECT (radio, "setting current tuner mute state: %d", on); + + if (!GST_V4L2_IS_OPEN (radio->v4l2object)) + return FALSE; + + memset (&vctrl, 0, sizeof (vctrl)); + vctrl.id = V4L2_CID_AUDIO_MUTE; + vctrl.value = on; + + GST_DEBUG_OBJECT (radio, "radio fd: %d", radio->v4l2object->video_fd); + + res = ioctl (radio->v4l2object->video_fd, VIDIOC_S_CTRL, &vctrl); + GST_DEBUG_OBJECT (radio, "mute state change result: %d", res); + if (res < 0) + goto freq_failed; + + return TRUE; + + /* ERRORS */ +freq_failed: + { + GST_ELEMENT_WARNING (radio, RESOURCE, SETTINGS, + (_("Failed to change mute state for device '%s'."), + radio->v4l2object->videodev), GST_ERROR_SYSTEM); + return FALSE; + } +} + +static gboolean +gst_v4l2radio_set_mute (GstV4l2Radio * radio) +{ + return gst_v4l2radio_set_mute_on (radio, TRUE); +} + +static gboolean +gst_v4l2radio_set_unmute (GstV4l2Radio * radio) +{ + return gst_v4l2radio_set_mute_on (radio, FALSE); +} + +GST_IMPLEMENT_V4L2_PROBE_METHODS (GstV4l2RadioClass, gst_v4l2radio); +GST_IMPLEMENT_V4L2_TUNER_METHODS (GstV4l2Radio, gst_v4l2radio); + +static void gst_v4l2radio_uri_handler_init (gpointer g_iface, + gpointer iface_data); + +static gboolean +gst_v4l2radio_interface_supported (GstImplementsInterface * iface, + GType iface_type) +{ + if (iface_type == GST_TYPE_TUNER) + return TRUE; + else + return FALSE; +} + +static void +gst_v4l2radio_implements_interface_init (GstImplementsInterfaceClass * iface) +{ + iface->supported = gst_v4l2radio_interface_supported; +} + +static void +gst_v4l2radio_tuner_interface_reinit (GstTunerClass * iface) +{ + gst_v4l2radio_tuner_interface_init (iface); +} + +static void +gst_v4l2radio_interfaces (GType type) +{ + static const GInterfaceInfo urihandler_info = { + (GInterfaceInitFunc) gst_v4l2radio_uri_handler_init, + NULL, + NULL + }; + + static const GInterfaceInfo implements_interface_info = { + (GInterfaceInitFunc) gst_v4l2radio_implements_interface_init, + NULL, + NULL, + }; + + static const GInterfaceInfo propertyprobe_info = { + (GInterfaceInitFunc) gst_v4l2radio_property_probe_interface_init, + NULL, + NULL, + }; + + static const GInterfaceInfo tuner_interface_info = { + (GInterfaceInitFunc) gst_v4l2radio_tuner_interface_reinit, + NULL, + NULL, + }; + + g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info); + g_type_add_interface_static (type, + GST_TYPE_IMPLEMENTS_INTERFACE, &implements_interface_info); + + g_type_add_interface_static (type, GST_TYPE_TUNER, &tuner_interface_info); + + g_type_add_interface_static (type, + GST_TYPE_PROPERTY_PROBE, &propertyprobe_info); +} + +GST_BOILERPLATE_FULL (GstV4l2Radio, gst_v4l2radio, GstElement, GST_TYPE_ELEMENT, + gst_v4l2radio_interfaces); + +static void gst_v4l2radio_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_v4l2radio_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); +static void gst_v4l2radio_finalize (GstV4l2Radio * radio); +static void gst_v4l2radio_dispose (GObject * object); +static GstStateChangeReturn gst_v4l2radio_change_state (GstElement * element, + GstStateChange transition); + +static void +gst_v4l2radio_base_init (gpointer gclass) +{ + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (gclass); + GstV4l2RadioClass *gstv4l2radio_class = GST_V4L2RADIO_CLASS (gclass); + + GST_DEBUG_CATEGORY_INIT (v4l2radio_debug, "v4l2radio", 0, + "V4l2 radio element"); + + gstv4l2radio_class->v4l2_class_devices = NULL; + + gst_element_class_set_details_simple (gstelement_class, + "Radio (video4linux2) Tuner", + "Tuner", + "Controls a Video4Linux2 radio device", + "Alexey Chernov <4ernov@gmail.com>"); +} + +static void +gst_v4l2radio_class_init (GstV4l2RadioClass * klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + + gobject_class->set_property = gst_v4l2radio_set_property; + gobject_class->get_property = gst_v4l2radio_get_property; + + g_object_class_install_property (gobject_class, ARG_DEVICE, + g_param_spec_string ("device", "Radio device location", + "Video4Linux2 radio device location", + DEFAULT_PROP_DEVICE, G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, ARG_FREQUENCY, + g_param_spec_int ("frequency", "Station frequency", + "Station frequency in Hz", + MIN_FREQUENCY, MAX_FREQUENCY, DEFAULT_FREQUENCY, G_PARAM_READWRITE)); + + gobject_class->dispose = gst_v4l2radio_dispose; + gobject_class->finalize = (GObjectFinalizeFunc) gst_v4l2radio_finalize; + + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_v4l2radio_change_state); + +} + +static void +gst_v4l2radio_init (GstV4l2Radio * filter, GstV4l2RadioClass * gclass) +{ + filter->v4l2object = gst_v4l2_object_new (GST_ELEMENT (filter), + V4L2_BUF_TYPE_VIDEO_CAPTURE, DEFAULT_PROP_DEVICE, + gst_v4l2radio_get_input, gst_v4l2radio_set_input, NULL); + + filter->v4l2object->frequency = DEFAULT_FREQUENCY; + filter->v4l2object->videodev = g_strdup (DEFAULT_PROP_DEVICE); +} + +static void +gst_v4l2radio_dispose (GObject * object) +{ + GstV4l2Radio *radio = GST_V4L2RADIO (object); + gst_v4l2_close (radio->v4l2object); + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gst_v4l2radio_finalize (GstV4l2Radio * radio) +{ + gst_v4l2_object_destroy (radio->v4l2object); + G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (radio)); +} + +static gboolean +gst_v4l2radio_open (GstV4l2Radio * radio) +{ + GstV4l2Object *v4l2object; + + v4l2object = radio->v4l2object; + if (gst_v4l2_open (v4l2object)) + return gst_v4l2radio_fill_channel_list (radio); + else + return FALSE; +} + +static void +gst_v4l2radio_set_defaults (GstV4l2Radio * radio) +{ + GstV4l2Object *v4l2object; + GstTunerChannel *channel = NULL; + GstTuner *tuner; + + v4l2object = radio->v4l2object; + + if (!GST_IS_TUNER (v4l2object->element)) + return; + + tuner = GST_TUNER (v4l2object->element); + + if (v4l2object->channel) + channel = gst_tuner_find_channel_by_name (tuner, v4l2object->channel); + if (channel) { + gst_tuner_set_channel (tuner, channel); + } else { + channel = + GST_TUNER_CHANNEL (gst_tuner_get_channel (GST_TUNER + (v4l2object->element))); + if (channel) { + g_free (v4l2object->channel); + v4l2object->channel = g_strdup (channel->label); + gst_tuner_channel_changed (tuner, channel); + } + } + + if (channel + && GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) { + if (v4l2object->frequency != 0) { + gst_tuner_set_frequency (tuner, channel, v4l2object->frequency); + } else { + v4l2object->frequency = gst_tuner_get_frequency (tuner, channel); + if (v4l2object->frequency == 0) { + /* guess */ + gst_tuner_set_frequency (tuner, channel, MIN_FREQUENCY); + } else { + } + } + } +} + +static gboolean +gst_v4l2radio_start (GstV4l2Radio * radio) +{ + if (!gst_v4l2radio_open (radio)) + return FALSE; + + gst_v4l2radio_set_defaults (radio); + + return TRUE; +} + +static gboolean +gst_v4l2radio_stop (GstV4l2Radio * radio) +{ + if (!gst_v4l2_object_stop (radio->v4l2object)) + return FALSE; + + return TRUE; +} + +static GstStateChangeReturn +gst_v4l2radio_change_state (GstElement * element, GstStateChange transition) +{ + GstV4l2Radio *radio; + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + + radio = GST_V4L2RADIO (element); + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + /*start radio */ + if (!gst_v4l2radio_start (radio)) + ret = GST_STATE_CHANGE_FAILURE; + break; + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: + /*unmute radio */ + if (!gst_v4l2radio_set_unmute (radio)) + ret = GST_STATE_CHANGE_FAILURE; + break; + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + /*mute radio */ + if (!gst_v4l2radio_set_mute (radio)) + ret = GST_STATE_CHANGE_FAILURE; + break; + case GST_STATE_CHANGE_READY_TO_NULL: + /*stop radio */ + if (!gst_v4l2radio_stop (radio)) + ret = GST_STATE_CHANGE_FAILURE; + break; + default: + break; + } + + return ret; +} + +static void +gst_v4l2radio_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstV4l2Radio *radio = GST_V4L2RADIO (object); + gint frequency; + switch (prop_id) { + case ARG_DEVICE: + radio->v4l2object->videodev = + g_strdup ((gchar *) g_value_get_string (value)); + break; + case ARG_FREQUENCY: + frequency = g_value_get_int (value); + if (frequency >= MIN_FREQUENCY && frequency <= MAX_FREQUENCY) { + radio->v4l2object->frequency = frequency; + gst_v4l2_set_frequency (radio->v4l2object, 0, + radio->v4l2object->frequency); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_v4l2radio_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstV4l2Radio *radio = GST_V4L2RADIO (object); + + switch (prop_id) { + case ARG_DEVICE: + g_value_set_string (value, radio->v4l2object->videodev); + break; + case ARG_FREQUENCY: + if (gst_v4l2_get_frequency (radio->v4l2object, + 0, &(radio->v4l2object->frequency))) + g_value_set_int (value, radio->v4l2object->frequency); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* GstURIHandler interface */ +static GstURIType +gst_v4l2radio_uri_get_type (void) +{ + return GST_URI_SRC; +} + +static gchar ** +gst_v4l2radio_uri_get_protocols (void) +{ + static gchar *protocols[] = { (char *) "radio", NULL }; + return protocols; +} + +static const gchar * +gst_v4l2radio_uri_get_uri (GstURIHandler * handler) +{ + GstV4l2Radio *radio = GST_V4L2RADIO (handler); + + if (radio->v4l2object->videodev != NULL) { + if (gst_v4l2_get_frequency (radio->v4l2object, + 0, &(radio->v4l2object->frequency))) { + gchar uri[20]; + gchar freq[6]; + g_ascii_formatd (freq, 6, "%4.1f", radio->v4l2object->frequency / 1e6); + g_snprintf (uri, sizeof (uri), "radio://%s", freq); + return g_intern_string (uri); + } + } + + return "radio://"; +} + +static gboolean +gst_v4l2radio_uri_set_uri (GstURIHandler * handler, const gchar * uri) +{ + GstV4l2Radio *radio = GST_V4L2RADIO (handler); + gdouble dfreq; + gint ifreq; + const gchar *freq; + gchar *end; + + if (strcmp (uri, "radio://") != 0) { + freq = uri + 8; + + dfreq = g_ascii_strtod (freq, &end); + + if (errno || strlen (end)) + goto uri_failed; + + ifreq = dfreq * 1e6; + g_object_set (radio, "frequency", ifreq, NULL); + + } else + goto uri_failed; + + return TRUE; + +uri_failed: + return FALSE; +} + +static void +gst_v4l2radio_uri_handler_init (gpointer g_iface, gpointer iface_data) +{ + GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; + + iface->get_type = gst_v4l2radio_uri_get_type; + iface->get_protocols = gst_v4l2radio_uri_get_protocols; + iface->get_uri = gst_v4l2radio_uri_get_uri; + iface->set_uri = gst_v4l2radio_uri_set_uri; +} diff --git a/sys/v4l2/gstv4l2radio.h b/sys/v4l2/gstv4l2radio.h new file mode 100644 index 0000000000..f1c99a277f --- /dev/null +++ b/sys/v4l2/gstv4l2radio.h @@ -0,0 +1,68 @@ +/* GStreamer v4l2 radio tuner element + * Copyright (C) 2010, 2011 Alexey Chernov <4ernov@gmail.com> + * + * gstv4l2radio.h - V4L2 radio tuner element + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_V4L2RADIO_H__ +#define __GST_V4L2RADIO_H__ + +#include "gstv4l2object.h" + +G_BEGIN_DECLS + +#define GST_TYPE_V4L2RADIO \ + (gst_v4l2radio_get_type()) +#define GST_V4L2RADIO(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_V4L2RADIO,GstV4l2Radio)) +#define GST_V4L2RADIO_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_V4L2RADIO,GstV4l2RadioClass)) +#define GST_IS_V4L2RADIO(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4L2RADIO)) +#define GST_IS_V4L2RADIO_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2RADIO)) + +typedef struct _GstV4l2Radio GstV4l2Radio; +typedef struct _GstV4l2RadioClass GstV4l2RadioClass; + +/** + * GstV4l2Radio: + * @v4l2object: private #GstV4l2Object + * + * Opaque video4linux2 radio tuner element + */ +struct _GstV4l2Radio +{ + GstElement element; + + /*< private >*/ + GstV4l2Object * v4l2object; +}; + +struct _GstV4l2RadioClass +{ + GstElementClass parent_class; + + GList *v4l2_class_devices; +}; + +GType gst_v4l2radio_get_type (void); + +G_END_DECLS + +#endif /* __GST_V4L2RADIO_H__ */