[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