Commit ea0ac11f authored by Lukasz Marek's avatar Lukasz Marek

lavd/v4l2: implement list device callback

Signed-off-by: 's avatarLukasz Marek <lukasz.m.luki2@gmail.com>
parent 44e6eeb3
......@@ -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,
};
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