---
 doc/indevs.texi    |    3 +-
 libavdevice/v4l2.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index 4405a5b..cdffeaa 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -267,7 +267,8 @@ the device.
 Video4Linux and Video4Linux2 devices only support a limited set of
 @var{width}x@var{height} sizes and framerates. You can check which are
 supported for example with the command @file{dov4l} for Video4Linux
-devices and the command @file{v4l-info} for Video4Linux2 devices.
+devices and passing @option{list} to @command{-pixel_format} for
+Video4Linux2 devices.
 
 If the size for the device is set to 0x0, the input device will
 try to autodetect the size to use.
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 9e8c5e4..6b73005 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -101,6 +101,40 @@ static struct fmt_map fmt_conversion_table[] = {
     { PIX_FMT_NONE,    CODEC_ID_MJPEG,    V4L2_PIX_FMT_JPEG    },
 };
 
+static void list_formats(AVFormatContext *ctx, int level, int fd)
+{
+    struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
+    struct v4l2_frmsizeenum vfse = { 0 };
+
+    while(!ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
+        av_log(ctx, level,
+               "%c%c%c%c/%04x %s flags %s%s :",
+               vfd.pixelformat & 0xFF,
+               (vfd.pixelformat >> 8) & 0xFF,
+               (vfd.pixelformat >> 16) & 0xFF,
+               (vfd.pixelformat >> 24) & 0xFF,
+               vfd.pixelformat,
+               vfd.description,
+               vfd.flags & V4L2_FMT_FLAG_EMULATED ? "e" : " ",
+               vfd.flags & V4L2_FMT_FLAG_COMPRESSED ? "c": " ");
+
+        vfse.pixel_format = vfd.pixelformat;
+
+        while(!ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
+            av_log(ctx, level,
+                   " %ux%u",
+                   vfse.discrete.width, vfse.discrete.height);
+            vfse.index++;
+        }
+
+        vfse.index = 0;
+        vfd.index++;
+
+        av_log(ctx, level, "\n");
+    }
+
+};
+
 static int device_open(AVFormatContext *ctx)
 {
     struct v4l2_capability cap;
@@ -626,12 +660,24 @@ static int v4l2_read_header(AVFormatContext *s1, 
AVFormatParameters *ap)
                s->video_size);
         goto out;
     }
-    if (s->pixel_format &&
-        (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) {
-        av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n",
-               s->pixel_format);
-        res = AVERROR(EINVAL);
-        goto out;
+
+    if (s->pixel_format) {
+
+        if (!strcmp(s->pixel_format, "list")) {
+            list_formats(s1, AV_LOG_INFO, s->fd);
+            res = AVERROR_EXIT;
+            goto out;
+        }
+
+        pix_fmt = av_get_pix_fmt(s->pixel_format);
+
+        if (pix_fmt == PIX_FMT_NONE) {
+            av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n",
+                   s->pixel_format);
+
+            res = AVERROR(EINVAL);
+            goto out;
+        }
     }
 
     if (!s->width && !s->height) {
-- 
1.7.8.rc1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to