On 21.12.2014 22:43, Lukasz Marek wrote:
Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
libavdevice/v4l2.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 2969980..9d4d7ae 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -1006,6 +1006,63 @@ static int v4l2_read_close(AVFormatContext *ctx)
return 0;
}
+static int v4l2_get_device_list(AVFormatContext *ctx, AVDeviceInfoList
*device_list)
+{
+ struct video_data *s = ctx->priv_data;
+ AVDeviceInfo *device = NULL;
+ struct v4l2_capability cap;
+ int i, ret = 0;
+
+ if (!device_list)
+ return AVERROR(EINVAL);
+
+ for (i = 0; i <= 31; i++) {
+ snprintf(ctx->filename, sizeof(ctx->filename), "/dev/video%d", i);
I wasn't sure this is correct. I changed this loop to opendir/readdir -
similar way v4l-utils does.
>From e2efb8e8b803b461d5c27b22435318e38639a2c8 Mon Sep 17 00:00:00 2001
From: Lukasz Marek <lukasz.m.lu...@gmail.com>
Date: Sun, 21 Dec 2014 22:37:18 +0100
Subject: [PATCH] lavd/v4l2: implement list device callback
Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
libavdevice/v4l2.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 2969980..8337cf5 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -31,6 +31,7 @@
*/
#include "v4l2-common.h"
+#include <dirent.h>
#if CONFIG_LIBV4L2
#include <libv4l2.h>
@@ -1006,6 +1007,81 @@ static int v4l2_read_close(AVFormatContext *ctx)
return 0;
}
+static int v4l2_is_v4l_dev(const char *name)
+{
+ return !strncmp(name, "video", 5) ||
+ !strncmp(name, "radio", 5) ||
+ !strncmp(name, "vbi", 3) ||
+ !strncmp(name, "v4l-subdev", 10);
+}
+
+static int v4l2_get_device_list(AVFormatContext *ctx, AVDeviceInfoList *device_list)
+{
+ struct video_data *s = ctx->priv_data;
+ DIR *dir;
+ struct dirent *entry;
+ AVDeviceInfo *device = NULL;
+ struct v4l2_capability cap;
+ int ret = 0;
+
+ if (!device_list)
+ return AVERROR(EINVAL);
+
+ dir = opendir("/dev");
+ if (!dir) {
+ ret = AVERROR(errno);
+ av_log(ctx, AV_LOG_ERROR, "Couldn't open the directory: %s\n", av_err2str(ret));
+ return ret;
+ }
+ while ((entry = readdir(dir))) {
+ if (!v4l2_is_v4l_dev(entry->d_name))
+ continue;
+
+ snprintf(ctx->filename, sizeof(ctx->filename), "/dev/%s", entry->d_name);
+ if ((s->fd = device_open(ctx)) < 0)
+ continue;
+
+ if (v4l2_ioctl(s->fd, VIDIOC_QUERYCAP, &cap) < 0) {
+ ret = AVERROR(errno);
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", av_err2str(ret));
+ goto fail;
+ }
+
+ device = av_mallocz(sizeof(AVDeviceInfo));
+ if (!device) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ device->device_name = av_strdup(ctx->filename);
+ device->device_description = av_strdup(cap.card);
+ if (!device->device_name || !device->device_description) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if ((ret = av_dynarray_add_nofree(&device_list->devices,
+ &device_list->nb_devices, device)) < 0)
+ goto fail;
+
+ v4l2_close(s->fd);
+ s->fd = -1;
+ continue;
+
+ fail:
+ if (device) {
+ av_freep(&device->device_name);
+ av_freep(&device->device_description);
+ av_freep(&device);
+ }
+ if (s->fd >= 0)
+ v4l2_close(s->fd);
+ s->fd = -1;
+ break;
+ }
+ closedir(dir);
+ return ret;
+}
+
#define OFFSET(x) offsetof(struct video_data, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
@@ -1050,6 +1126,7 @@ AVInputFormat ff_v4l2_demuxer = {
.read_header = v4l2_read_header,
.read_packet = v4l2_read_packet,
.read_close = v4l2_read_close,
+ .get_device_list = v4l2_get_device_list,
.flags = AVFMT_NOFILE,
.priv_class = &v4l2_class,
};
--
1.9.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel