v4l2: make possible to disable libv4l2 at runtime.

Also disable it by default since it looks currently buggy. The
usefulness of such library is mostly limited to backward compatibility
with very old devices.
This commit is contained in:
Clément Bœsch 2013-05-20 15:43:31 +02:00
parent 12f51c1f9e
commit 165bc9caa2
3 changed files with 49 additions and 15 deletions

View File

@ -590,8 +590,8 @@ Video4Linux2 input video device.
"v4l2" can be used as alias for "video4linux2".
If FFmpeg is built with v4l-utils support (by using the
@code{--enable-libv4l2} configure option), the device will always rely
on libv4l2.
@code{--enable-libv4l2} configure option), it is possible to use it with the
@code{-use_libv4l2} input device option.
The name of the device to grab is a file device node, usually Linux
systems tend to automatically create such nodes when the device

View File

@ -34,14 +34,6 @@
#if CONFIG_LIBV4L2
#include <libv4l2.h>
#else
#define v4l2_open open
#define v4l2_close close
#define v4l2_dup dup
#define v4l2_ioctl ioctl
#define v4l2_read read
#define v4l2_mmap mmap
#define v4l2_munmap munmap
#endif
static const int desired_video_buffers = 256;
@ -95,6 +87,15 @@ struct video_data {
int list_format; /**< Set by a private option. */
int list_standard; /**< Set by a private option. */
char *framerate; /**< Set by a private option. */
int use_libv4l2;
int (*open_f)(const char *file, int oflag, ...);
int (*close_f)(int fd);
int (*dup_f)(int fd);
int (*ioctl_f)(int fd, unsigned long int request, ...);
ssize_t (*read_f)(int fd, void *buffer, size_t n);
void *(*mmap_f)(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
int (*munmap_f)(void *_start, size_t length);
};
struct buff_data {
@ -104,11 +105,41 @@ struct buff_data {
static int device_open(AVFormatContext *ctx)
{
struct video_data *s = ctx->priv_data;
struct v4l2_capability cap;
int fd;
int ret;
int flags = O_RDWR;
#define SET_WRAPPERS(prefix) do { \
s->open_f = prefix ## open; \
s->close_f = prefix ## close; \
s->dup_f = prefix ## dup; \
s->ioctl_f = prefix ## ioctl; \
s->read_f = prefix ## read; \
s->mmap_f = prefix ## mmap; \
s->munmap_f = prefix ## munmap; \
} while (0)
if (s->use_libv4l2) {
#if CONFIG_LIBV4L2
SET_WRAPPERS(v4l2_);
#else
av_log(ctx, AV_LOG_ERROR, "libavdevice is not build with libv4l2 support.\n");
return AVERROR(EINVAL);
#endif
} else {
SET_WRAPPERS();
}
#define v4l2_open s->open_f
#define v4l2_close s->close_f
#define v4l2_dup s->dup_f
#define v4l2_ioctl s->ioctl_f
#define v4l2_read s->read_f
#define v4l2_mmap s->mmap_f
#define v4l2_munmap s->munmap_f
if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
flags |= O_NONBLOCK;
}
@ -194,7 +225,7 @@ static int device_init(AVFormatContext *ctx, int *width, int *height,
return res;
}
static int first_field(int fd)
static int first_field(const struct video_data *s, int fd)
{
int res;
v4l2_std_id std;
@ -213,6 +244,7 @@ static int first_field(int fd)
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat)
{
const struct video_data *s = ctx->priv_data;
struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
while(!v4l2_ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
@ -238,6 +270,7 @@ static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat)
static void list_formats(AVFormatContext *ctx, int fd, int type)
{
const struct video_data *s = ctx->priv_data;
struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
while(!v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
@ -777,7 +810,8 @@ static int v4l2_read_header(AVFormatContext *s1)
#if CONFIG_LIBV4L2
/* silence libv4l2 logging. if fopen() fails v4l2_log_file will be NULL
and errors will get sent to stderr */
v4l2_log_file = fopen("/dev/null", "w");
if (s->use_libv4l2)
v4l2_log_file = fopen("/dev/null", "w");
#endif
s->fd = device_open(s1);
@ -888,7 +922,7 @@ static int v4l2_read_header(AVFormatContext *s1)
return res;
}
s->top_field_first = first_field(s->fd);
s->top_field_first = first_field(s, s->fd);
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
st->codec->codec_id = codec_id;
@ -963,7 +997,7 @@ static const AVOption options[] = {
{ "default", "use timestamps from the kernel", OFFSET(ts_mode), AV_OPT_TYPE_CONST, {.i64 = V4L_TS_DEFAULT }, 0, 2, DEC, "timestamps" },
{ "abs", "use absolute timestamps (wall clock)", OFFSET(ts_mode), AV_OPT_TYPE_CONST, {.i64 = V4L_TS_ABS }, 0, 2, DEC, "timestamps" },
{ "mono2abs", "force conversion from monotonic to absolute timestamps", OFFSET(ts_mode), AV_OPT_TYPE_CONST, {.i64 = V4L_TS_MONO2ABS }, 0, 2, DEC, "timestamps" },
{ "use_libv4l2", "use libv4l2 (v4l-utils) convertion functions", OFFSET(use_libv4l2), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC },
{ NULL },
};

View File

@ -29,7 +29,7 @@
#define LIBAVDEVICE_VERSION_MAJOR 55
#define LIBAVDEVICE_VERSION_MINOR 1
#define LIBAVDEVICE_VERSION_MICRO 100
#define LIBAVDEVICE_VERSION_MICRO 101
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \