[FFmpeg-devel] [PATCH] v4l2: make possible to disable libv4l2 at runtime.
Clément Bœsch
ubitux at gmail.com
Mon May 20 15:48:25 CEST 2013
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.
---
doc/indevs.texi | 4 ++--
libavdevice/v4l2.c | 52 +++++++++++++++++++++++++++++++++++++++------------
libavdevice/version.h | 2 +-
3 files changed, 43 insertions(+), 15 deletions(-)
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 5e8d215..5cc03f9 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -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
- at code{--enable-libv4l2} configure option), the device will always rely
-on libv4l2.
+ at code{--enable-libv4l2} configure option), it is possible to use it with the
+ at 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
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 90985e3..7c69132 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -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,35 @@ 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 (CONFIG_LIBV4L2 && s->use_libv4l2)
+ SET_WRAPPERS(v4l2_);
+ 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 +219,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 +238,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 +264,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 +804,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 +916,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 +991,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 = 1}, 0, 1, DEC },
{ NULL },
};
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 6fd8d35..2aab520 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -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, \
--
1.8.2.3
More information about the ffmpeg-devel
mailing list