Commit 264ad6ea authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

v4l2: factor device open

This will be used by the radio tuner.
parent 2ced1b14
...@@ -29,12 +29,10 @@ ...@@ -29,12 +29,10 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <poll.h> #include <poll.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_access.h> #include <vlc_access.h>
#include <vlc_fs.h>
#include "v4l2.h" #include "v4l2.h"
...@@ -54,7 +52,7 @@ struct access_sys_t ...@@ -54,7 +52,7 @@ struct access_sys_t
static block_t *AccessRead( access_t * ); static block_t *AccessRead( access_t * );
static ssize_t AccessReadStream( access_t *, uint8_t *, size_t ); static ssize_t AccessReadStream( access_t *, uint8_t *, size_t );
static int AccessControl( access_t *, int, va_list ); static int AccessControl( access_t *, int, va_list );
static int InitVideo(access_t *, int); static int InitVideo(access_t *, int, uint32_t);
int AccessOpen( vlc_object_t *obj ) int AccessOpen( vlc_object_t *obj )
{ {
...@@ -72,27 +70,15 @@ int AccessOpen( vlc_object_t *obj ) ...@@ -72,27 +70,15 @@ int AccessOpen( vlc_object_t *obj )
char *path = var_InheritString (obj, CFG_PREFIX"dev"); char *path = var_InheritString (obj, CFG_PREFIX"dev");
if (unlikely(path == NULL)) if (unlikely(path == NULL))
goto error; /* probably OOM */ goto error; /* probably OOM */
msg_Dbg (obj, "opening device '%s'", path);
int rawfd = vlc_open (path, O_RDWR); uint32_t caps;
if (rawfd == -1) int fd = OpenDevice (obj, path, &caps);
{
msg_Err (obj, "cannot open device '%s': %m", path);
free (path);
goto error;
}
free (path); free (path);
int fd = v4l2_fd_open (rawfd, 0);
if (fd == -1) if (fd == -1)
{ goto error;
msg_Warn (obj, "cannot initialize user-space library: %m");
/* fallback to direct kernel mode anyway */
fd = rawfd;
}
sys->fd = fd; sys->fd = fd;
if (InitVideo (access, fd)) if (InitVideo (access, fd, caps))
{ {
v4l2_close (fd); v4l2_close (fd);
goto error; goto error;
...@@ -106,34 +92,11 @@ error: ...@@ -106,34 +92,11 @@ error:
return VLC_EGENERIC; return VLC_EGENERIC;
} }
int InitVideo (access_t *access, int fd) int InitVideo (access_t *access, int fd, uint32_t caps)
{ {
access_sys_t *sys = access->p_sys; access_sys_t *sys = access->p_sys;
/* Get device capabilites */ if (!(caps & V4L2_CAP_VIDEO_CAPTURE))
struct v4l2_capability cap;
if (v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) < 0)
{
msg_Err (access, "cannot get device capabilities: %m");
return -1;
}
msg_Dbg (access, "device %s using driver %s (version %u.%u.%u) on %s",
cap.card, cap.driver, (cap.version >> 16) & 0xFF,
(cap.version >> 8) & 0xFF, cap.version & 0xFF, cap.bus_info);
msg_Dbg (access, "the device has the capabilities: 0x%08X",
cap.capabilities);
msg_Dbg (access, " (%c) Video Capture, (%c) Audio, (%c) Tuner, (%c) Radio",
(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE ? 'X':' '),
(cap.capabilities & V4L2_CAP_AUDIO ? 'X':' '),
(cap.capabilities & V4L2_CAP_TUNER ? 'X':' '),
(cap.capabilities & V4L2_CAP_RADIO ? 'X':' '));
msg_Dbg (access, " (%c) Read/Write, (%c) Streaming, (%c) Asynchronous",
(cap.capabilities & V4L2_CAP_READWRITE ? 'X':' '),
(cap.capabilities & V4L2_CAP_STREAMING ? 'X':' '),
(cap.capabilities & V4L2_CAP_ASYNCIO ? 'X':' '));
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
{ {
msg_Err (access, "not a video capture device"); msg_Err (access, "not a video capture device");
return -1; return -1;
...@@ -178,7 +141,7 @@ int InitVideo (access_t *access, int fd) ...@@ -178,7 +141,7 @@ int InitVideo (access_t *access, int fd)
} }
/* Init I/O method */ /* Init I/O method */
if (cap.capabilities & V4L2_CAP_STREAMING) if (caps & V4L2_CAP_STREAMING)
{ {
sys->bufc = 4; sys->bufc = 4;
sys->bufv = StartMmap (VLC_OBJECT(access), fd, &sys->bufc); sys->bufv = StartMmap (VLC_OBJECT(access), fd, &sys->bufc);
...@@ -186,7 +149,7 @@ int InitVideo (access_t *access, int fd) ...@@ -186,7 +149,7 @@ int InitVideo (access_t *access, int fd)
return -1; return -1;
access->pf_block = AccessRead; access->pf_block = AccessRead;
} }
else if (cap.capabilities & V4L2_CAP_READWRITE) else if (caps & V4L2_CAP_READWRITE)
{ {
sys->blocksize = fmt.fmt.pix.sizeimage; sys->blocksize = fmt.fmt.pix.sizeimage;
sys->bufv = NULL; sys->bufv = NULL;
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <math.h> #include <math.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#ifndef MAP_ANONYMOUS #ifndef MAP_ANONYMOUS
...@@ -40,7 +39,6 @@ ...@@ -40,7 +39,6 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_demux.h> #include <vlc_demux.h>
#include <vlc_fs.h>
#include "v4l2.h" #include "v4l2.h"
...@@ -65,7 +63,7 @@ static void *UserPtrThread (void *); ...@@ -65,7 +63,7 @@ static void *UserPtrThread (void *);
static void *MmapThread (void *); static void *MmapThread (void *);
static void *ReadThread (void *); static void *ReadThread (void *);
static int DemuxControl( demux_t *, int, va_list ); static int DemuxControl( demux_t *, int, va_list );
static int InitVideo (demux_t *, int); static int InitVideo (demux_t *, int fd, uint32_t caps);
int DemuxOpen( vlc_object_t *obj ) int DemuxOpen( vlc_object_t *obj )
{ {
...@@ -81,27 +79,15 @@ int DemuxOpen( vlc_object_t *obj ) ...@@ -81,27 +79,15 @@ int DemuxOpen( vlc_object_t *obj )
char *path = var_InheritString (obj, CFG_PREFIX"dev"); char *path = var_InheritString (obj, CFG_PREFIX"dev");
if (unlikely(path == NULL)) if (unlikely(path == NULL))
goto error; /* probably OOM */ goto error; /* probably OOM */
msg_Dbg (obj, "opening device '%s'", path);
int rawfd = vlc_open (path, O_RDWR); uint32_t caps;
if (rawfd == -1) int fd = OpenDevice (obj, path, &caps);
{
msg_Err (obj, "cannot open device '%s': %m", path);
free (path);
goto error;
}
free (path); free (path);
int fd = v4l2_fd_open (rawfd, 0);
if (fd == -1) if (fd == -1)
{ goto error;
msg_Warn (obj, "cannot initialize user-space library: %m");
/* fallback to direct kernel mode anyway */
fd = rawfd;
}
sys->fd = fd; sys->fd = fd;
if (InitVideo (demux, fd)) if (InitVideo (demux, fd, caps))
{ {
v4l2_close (fd); v4l2_close (fd);
goto error; goto error;
...@@ -275,37 +261,10 @@ static void GetAR (int fd, unsigned *restrict num, unsigned *restrict den) ...@@ -275,37 +261,10 @@ static void GetAR (int fd, unsigned *restrict num, unsigned *restrict den)
*den = cropcap.pixelaspect.denominator; *den = cropcap.pixelaspect.denominator;
} }
static int InitVideo (demux_t *demux, int fd) static int InitVideo (demux_t *demux, int fd, uint32_t caps)
{ {
demux_sys_t *sys = demux->p_sys; demux_sys_t *sys = demux->p_sys;
/* Get device capabilites */
struct v4l2_capability cap;
if (v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) < 0)
{
msg_Err (demux, "cannot get device capabilities: %m");
return -1;
}
msg_Dbg (demux, "device %s using driver %s (version %u.%u.%u) on %s",
cap.card, cap.driver, (cap.version >> 16) & 0xFF,
(cap.version >> 8) & 0xFF, cap.version & 0xFF, cap.bus_info);
uint32_t caps;
#ifdef V4L2_CAP_DEVICE_CAPS
if (cap.capabilities & V4L2_CAP_DEVICE_CAPS)
{
msg_Dbg (demux, " with capabilities 0x%08"PRIX32" "
"(overall 0x%08"PRIX32")", cap.device_caps, cap.capabilities);
caps = cap.device_caps;
}
else
#endif
{
msg_Dbg (demux, " with unknown capabilities "
"(overall 0x%08"PRIX32")", cap.capabilities);
caps = cap.capabilities;
}
if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) if (!(caps & V4L2_CAP_VIDEO_CAPTURE))
{ {
msg_Err (demux, "not a video capture device"); msg_Err (demux, "not a video capture device");
......
...@@ -32,8 +32,12 @@ ...@@ -32,8 +32,12 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <sys/types.h>
#include <fcntl.h>
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_fs.h>
#include "v4l2.h" #include "v4l2.h"
...@@ -440,6 +444,55 @@ void ParseMRL( vlc_object_t *obj, const char *mrl ) ...@@ -440,6 +444,55 @@ void ParseMRL( vlc_object_t *obj, const char *mrl )
} }
} }
int OpenDevice (vlc_object_t *obj, const char *path, uint32_t *restrict caps)
{
msg_Dbg (obj, "opening device '%s'", path);
int rawfd = vlc_open (path, O_RDWR);
if (rawfd == -1)
{
msg_Err (obj, "cannot open device '%s': %m", path);
return -1;
}
int fd = v4l2_fd_open (rawfd, 0);
if (fd == -1)
{
msg_Warn (obj, "cannot initialize user-space library: %m");
/* fallback to direct kernel mode anyway */
fd = rawfd;
}
/* Get device capabilites */
struct v4l2_capability cap;
if (v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) < 0)
{
msg_Err (obj, "cannot get device capabilities: %m");
v4l2_close (fd);
return -1;
}
msg_Dbg (obj, "device %s using driver %s (version %u.%u.%u) on %s",
cap.card, cap.driver, (cap.version >> 16) & 0xFF,
(cap.version >> 8) & 0xFF, cap.version & 0xFF, cap.bus_info);
#ifdef V4L2_CAP_DEVICE_CAPS
if (cap.capabilities & V4L2_CAP_DEVICE_CAPS)
{
msg_Dbg (obj, " with capabilities 0x%08"PRIX32" "
"(overall 0x%08"PRIX32")", cap.device_caps, cap.capabilities);
*caps = cap.device_caps;
}
else
#endif
{
msg_Dbg (obj, " with unknown capabilities "
"(overall 0x%08"PRIX32")", cap.capabilities);
*caps = cap.capabilities;
}
return fd;
}
v4l2_std_id var_InheritStandard (vlc_object_t *obj, const char *varname) v4l2_std_id var_InheritStandard (vlc_object_t *obj, const char *varname)
{ {
char *name = var_InheritString (obj, varname); char *name = var_InheritString (obj, varname);
......
...@@ -79,6 +79,7 @@ struct buffer_t ...@@ -79,6 +79,7 @@ struct buffer_t
/* v4l2.c */ /* v4l2.c */
void ParseMRL(vlc_object_t *, const char *); void ParseMRL(vlc_object_t *, const char *);
int OpenDevice (vlc_object_t *, const char *, uint32_t *);
v4l2_std_id var_InheritStandard (vlc_object_t *, const char *); v4l2_std_id var_InheritStandard (vlc_object_t *, const char *);
/* video.c */ /* video.c */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment