[vlc-commits] v4l2: add basic support for AM and FM tuners (fixes #6788)

Rémi Denis-Courmont git at videolan.org
Thu Aug 23 14:19:03 CEST 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Aug 23 15:18:30 2012 +0300| [2971d9bd2279b4069dea237ab6f0394cb40e2de7] | committer: Rémi Denis-Courmont

v4l2: add basic support for AM and FM tuners (fixes #6788)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2971d9bd2279b4069dea237ab6f0394cb40e2de7
---

 modules/access/Modules.am   |    1 +
 modules/access/v4l2/radio.c |  121 +++++++++++++++++++++++++++++++++++++++++++
 modules/access/v4l2/v4l2.c  |   37 ++++++++-----
 modules/access/v4l2/v4l2.h  |    5 ++
 modules/access/v4l2/video.c |    2 +-
 5 files changed, 152 insertions(+), 14 deletions(-)

diff --git a/modules/access/Modules.am b/modules/access/Modules.am
index fa9eb8b..1e97e4e 100644
--- a/modules/access/Modules.am
+++ b/modules/access/Modules.am
@@ -152,6 +152,7 @@ libv4l2_plugin_la_SOURCES = \
 	v4l2/video.c \
 	v4l2/demux.c \
 	v4l2/access.c \
+	v4l2/radio.c \
 	v4l2/controls.c \
 	v4l2/lib.c \
 	v4l2/v4l2.h
diff --git a/modules/access/v4l2/radio.c b/modules/access/v4l2/radio.c
new file mode 100644
index 0000000..17897e4
--- /dev/null
+++ b/modules/access/v4l2/radio.c
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * radio.c : V4L2 analog radio receiver
+ *****************************************************************************
+ * Copyright (C) 2012 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <fcntl.h>
+
+#include <vlc_common.h>
+#include <vlc_demux.h>
+#include <vlc_fs.h>
+
+#include "v4l2.h"
+
+struct demux_sys_t
+{
+    int fd;
+    vlc_v4l2_ctrl_t *controls;
+};
+
+static int RadioControl (demux_t *demux, int query, va_list args)
+{
+    switch (query)
+    {
+        case DEMUX_CAN_PAUSE:
+        case DEMUX_CAN_SEEK:
+        case DEMUX_CAN_CONTROL_PACE:
+            *va_arg (args, bool *) = false;
+            break;
+
+        case DEMUX_GET_PTS_DELAY:
+            *va_arg (args,int64_t *) = INT64_C(1000)
+                * var_InheritInteger (demux, "live-caching");
+            break;
+
+        case DEMUX_GET_TIME:
+            *va_arg (args, int64_t *) = mdate ();
+            break;
+
+        /* TODO implement others */
+        default:
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+int RadioOpen (vlc_object_t *obj)
+{
+    demux_t *demux = (demux_t *)obj;
+
+    /* Parse MRL */
+    size_t pathlen = strcspn (demux->psz_location, ":;");
+    char *path = (pathlen != 0) ? strndup (demux->psz_location, pathlen)
+                              : var_InheritString (obj, CFG_PREFIX"radio-dev");
+    if (unlikely(path == NULL))
+        return VLC_ENOMEM;
+    if (demux->psz_location[pathlen] != '\0')
+        var_LocationParse (obj, demux->psz_location + pathlen + 1, CFG_PREFIX);
+
+    /* Open device */
+    uint32_t caps;
+    int fd = OpenDevice (obj, path, &caps);
+    free (path);
+    if (fd == -1)
+        return VLC_EGENERIC;
+    if (!(caps & V4L2_CAP_TUNER))
+    {
+        msg_Err (obj, "not a radio tuner device");
+        goto error;
+    }
+
+    if (SetupTuner (obj, fd, 0))
+        goto error;
+
+    demux_sys_t *sys = malloc (sizeof (*sys));
+    if (unlikely(sys == NULL))
+        goto error;
+
+    sys->fd = fd;
+    sys->controls = ControlsInit (VLC_OBJECT(demux), fd);
+
+    demux->p_sys = sys;
+    demux->pf_demux = NULL;
+    demux->pf_control = RadioControl;
+    demux->info.i_update = 0;
+    demux->info.i_title = 0;
+    demux->info.i_seekpoint = 0;
+    return VLC_SUCCESS;
+
+error:
+    v4l2_close (fd);
+    return VLC_EGENERIC;
+}
+
+void RadioClose (vlc_object_t *obj)
+{
+    demux_t *demux = (demux_t *)obj;
+    demux_sys_t *sys = demux->p_sys;
+
+    ControlsDeinit (obj, sys->controls);
+    v4l2_close (sys->fd);
+    free (sys);
+}
diff --git a/modules/access/v4l2/v4l2.c b/modules/access/v4l2/v4l2.c
index ec0c7d2..9347d58 100644
--- a/modules/access/v4l2/v4l2.c
+++ b/modules/access/v4l2/v4l2.c
@@ -41,8 +41,8 @@
 
 #include "v4l2.h"
 
-#define DEVICE_TEXT N_( "Device" )
-#define DEVICE_LONGTEXT N_("Video device node." )
+#define VIDEO_DEVICE_TEXT N_( "Video capture device" )
+#define VIDEO_DEVICE_LONGTEXT N_("Video capture device node." )
 #define STANDARD_TEXT N_( "Standard" )
 #define STANDARD_LONGTEXT N_( \
     "Video standard (Default, SECAM, PAL, or NTSC)." )
@@ -66,6 +66,15 @@
 /*#define FPS_TEXT N_( "Frame rate" )
 #define FPS_LONGTEXT N_( "Maximum frame rate to use (0 = no limits)." )*/
 
+#define RADIO_DEVICE_TEXT N_( "Radio device" )
+#define RADIO_DEVICE_LONGTEXT N_("Radio tuner device node." )
+#define FREQUENCY_TEXT N_("Frequency")
+#define FREQUENCY_LONGTEXT N_( \
+    "Tuner frequency in Hz or kHz (see debug output)" )
+#define TUNER_AUDIO_MODE_TEXT N_("Audio mode")
+#define TUNER_AUDIO_MODE_LONGTEXT N_( \
+    "Tuner audio mono/stereo and track selection." )
+
 #define CTRL_RESET_TEXT N_( "Reset controls" )
 #define CTRL_RESET_LONGTEXT N_( "Reset controls to defaults." )
 #define BRIGHTNESS_TEXT N_( "Brightness" )
@@ -180,13 +189,6 @@ static const char *const colorfx_user[] = { N_("Unspecified"), N_("None"),
     "To list available controls, increase verbosity (-vvv) " \
     "or use the v4l2-ctl application." )
 
-#define FREQUENCY_TEXT N_("Frequency")
-#define FREQUENCY_LONGTEXT N_( \
-    "Tuner frequency in Hz or kHz (see debug output)" )
-#define TUNER_AUDIO_MODE_TEXT N_("Audio mode")
-#define TUNER_AUDIO_MODE_LONGTEXT N_( \
-    "Tuner audio mono/stereo and track selection." )
-
 #define ASPECT_TEXT N_("Picture aspect-ratio n:m")
 #define ASPECT_LONGTEXT N_("Define input picture aspect-ratio to use. Default is 4:3" )
 
@@ -266,14 +268,14 @@ static const char *const psz_tuner_audio_modes_list_text[] = {
 };
 
 vlc_module_begin ()
-    set_shortname( N_("Video4Linux2") )
-    set_description( N_("Video4Linux2 input") )
+    set_shortname( N_("V4L") )
+    set_description( N_("Video4Linux input") )
     set_category( CAT_INPUT )
     set_subcategory( SUBCAT_INPUT_ACCESS )
 
     set_section( N_( "Video input" ), NULL )
     add_loadfile( CFG_PREFIX "dev", "/dev/video0",
-                  DEVICE_TEXT, DEVICE_LONGTEXT, false )
+                  VIDEO_DEVICE_TEXT, VIDEO_DEVICE_LONGTEXT, false )
         change_safe()
     add_string( CFG_PREFIX "standard", "",
                 STANDARD_TEXT, STANDARD_LONGTEXT, false )
@@ -306,6 +308,9 @@ vlc_module_begin ()
     add_obsolete_bool( CFG_PREFIX "use-libv4l2" ) /* since 2.1.0 */
 
     set_section( N_( "Tuner" ), NULL )
+    add_loadfile( CFG_PREFIX "radio-dev", "/dev/radio0",
+                  RADIO_DEVICE_TEXT, RADIO_DEVICE_LONGTEXT, false )
+        change_safe()
     add_obsolete_integer( CFG_PREFIX "tuner" ) /* since 2.1.0 */
     add_integer( CFG_PREFIX "tuner-frequency", -1, FREQUENCY_TEXT,
                  FREQUENCY_LONGTEXT, true )
@@ -409,11 +414,17 @@ vlc_module_begin ()
 
     add_submodule ()
     add_shortcut( "v4l", "v4l2", "v4l2c" )
-    set_description( N_("Video4Linux2 Compressed A/V") )
+    set_description( N_("Video4Linux compressed A/V input") )
     set_capability( "access", 0 )
     /* use these when open as access_demux fails; VLC will use another demux */
     set_callbacks( AccessOpen, AccessClose )
 
+    add_submodule ()
+    add_shortcut ("radio" /*, "fm", "am" */)
+    set_description (N_("Video4Linux radio tuner"))
+    set_capability ("access_demux", 0)
+    set_callbacks (RadioOpen, RadioClose)
+
 vlc_module_end ()
 
 /**
diff --git a/modules/access/v4l2/v4l2.h b/modules/access/v4l2/v4l2.h
index bdcacb6..8586494 100644
--- a/modules/access/v4l2/v4l2.h
+++ b/modules/access/v4l2/v4l2.h
@@ -88,6 +88,7 @@ int SetupFormat (vlc_object_t *, int, uint32_t,
                  struct v4l2_format *, struct v4l2_streamparm *);
 #define SetupFormat(o,fd,fcc,fmt,p) \
         SetupFormat(VLC_OBJECT(o),fd,fcc,fmt,p)
+int SetupTuner (vlc_object_t *, int fd, uint32_t);
 
 int StartUserPtr (vlc_object_t *, int);
 struct buffer_t *StartMmap (vlc_object_t *, int, uint32_t *);
@@ -106,6 +107,10 @@ void GetMaxDimensions(vlc_object_t *, int fd, uint32_t fmt, float fps_min,
 int AccessOpen(vlc_object_t *);
 void AccessClose(vlc_object_t *);
 
+/* radio.c */
+int RadioOpen(vlc_object_t *);
+void RadioClose(vlc_object_t *);
+
 /* controls.c */
 vlc_v4l2_ctrl_t *ControlsInit(vlc_object_t *, int fd);
 void ControlsDeinit(vlc_object_t *, vlc_v4l2_ctrl_t *);
diff --git a/modules/access/v4l2/video.c b/modules/access/v4l2/video.c
index d633a9c..56b8b1a 100644
--- a/modules/access/v4l2/video.c
+++ b/modules/access/v4l2/video.c
@@ -116,7 +116,7 @@ static int SetupAudio (vlc_object_t *obj, int fd,
     return 0;
 }
 
-static int SetupTuner (vlc_object_t *obj, int fd, uint32_t idx)
+int SetupTuner (vlc_object_t *obj, int fd, uint32_t idx)
 {
     struct v4l2_tuner tuner = { .index = idx };
 



More information about the vlc-commits mailing list