On 2012-01-03 11:27:54 +0100, Luca Barbato wrote:
> Make use of the experimental framesize enumeration ioctl if available.
> ---
>  configure          |    3 ++
>  doc/indevs.texi    |    2 +-
>  libavdevice/v4l2.c |  101 
> ++++++++++++++++++++++++++++++++++++++++++++++++----
>  3 files changed, 98 insertions(+), 8 deletions(-)
> 
> diff --git a/configure b/configure
> index b7f0acd..c683dc4 100755
> --- a/configure
> +++ b/configure
> @@ -1135,6 +1135,7 @@ HAVE_LIST="
>      struct_sockaddr_in6
>      struct_sockaddr_sa_len
>      struct_sockaddr_storage
> +    struct_v4l2_frmivalenum_discrete
>      symver
>      symver_asm_label
>      symver_gnu_asm
> @@ -2993,6 +2994,8 @@ texi2html -version > /dev/null 2>&1 && enable texi2html 
> || disable texi2html
>  check_header linux/fb.h
>  check_header linux/videodev.h
>  check_header linux/videodev2.h
> +check_struct linux/videodev2.h "struct v4l2_frmivalenum" discrete
> +

does this check for a member in an anonymous union ever succeed with
gcc -std=c99 ? if not it is pointless and we should look how we can
make it available for gcc on linux.

>  check_header sys/videoio.h
>  
>  check_func_headers "windows.h vfw.h" capCreateCaptureWindow 
> "$vfwcap_indev_extralibs"
> diff --git a/doc/indevs.texi b/doc/indevs.texi
> index 4405a5b..e1b4ddd 100644
> --- a/doc/indevs.texi
> +++ b/doc/indevs.texi
> @@ -267,7 +267,7 @@ 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 using @command{-list_formats all} 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 cde2f9f..e0cd97f 100644
> --- a/libavdevice/v4l2.c
> +++ b/libavdevice/v4l2.c
> @@ -51,6 +51,10 @@
>  
>  static const int desired_video_buffers = 256;
>  
> +#define V4L_ALLFORMATS  3
> +#define V4L_RAWFORMATS  1
> +#define V4L_COMPFORMATS 2
> +
>  struct video_data {
>      AVClass *class;
>      int fd;
> @@ -65,8 +69,10 @@ struct video_data {
>      unsigned int *buf_len;
>      char *standard;
>      int channel;
> -    char *video_size; /**< String describing video size, set by a private 
> option. */
> +    char *video_size;   /**< String describing video size,
> +                             set by a private option. */
>      char *pixel_format; /**< Set by a private option. */
> +    int list_format;    /**< Set by a private option. */
>      char *framerate;    /**< Set by a private option. */
>  };
>  
> @@ -258,6 +264,71 @@ static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt)
>      return CODEC_ID_NONE;
>  }
>  
> +#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
> +static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t 
> pixelformat)
> +{
> +    struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
> +
> +    while(!ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
> +        switch (vfse.type) {
> +        case V4L2_FRMSIZE_TYPE_DISCRETE:
> +            av_log(ctx, AV_LOG_INFO, " %ux%u",
> +                   vfse.discrete.width, vfse.discrete.height);
> +        break;
> +        case V4L2_FRMSIZE_TYPE_CONTINUOUS:
> +            av_log(ctx, AV_LOG_INFO, " {Any}x{Any}");

the only driver using V4L2_FRMSIZE_TYPE_CONTINUOUS in 3.1 still sets
stepwise.* probably noting to rely on. Any sounds wrong since there
will be a min and max frame size. It's probably fine as is and
V4L2_FRMSIZE_TYPE_CONTINUOUS will be mostly ignored

> +        break;
> +        case V4L2_FRMSIZE_TYPE_STEPWISE:
> +            av_log(ctx, AV_LOG_INFO, " {%u-%u, %u}x{%u-%u, %u}",
> +                   vfse.stepwise.min_width,
> +                   vfse.stepwise.max_width,
> +                   vfse.stepwise.step_width,
> +                   vfse.stepwise.min_height,
> +                   vfse.stepwise.max_height,
> +                   vfse.stepwise.step_height);
> +        }
> +        vfse.index++;
> +    }
> +}
> +#endif
> +
> +static void list_formats(AVFormatContext *ctx, int fd, int type)
> +{
> +    struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
> +
> +    while(!ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
> +        enum CodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
> +        enum PixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);
> +
> +        vfd.index++;
> +
> +        if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
> +            type & V4L_RAWFORMATS) {
> +            const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
> +            av_log(ctx, AV_LOG_INFO, "R : %9s : %20s :",
> +                   fmt_name ? fmt_name : "Unsupported",
> +                   vfd.description);
> +        } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
> +                   type & V4L_COMPFORMATS) {
> +            AVCodec *codec = avcodec_find_encoder(codec_id);
> +            av_log(ctx, AV_LOG_INFO, "C : %9s : %20s :",
> +                   codec ? codec->name : "Unsupported",
> +                   vfd.description);
> +        } else {
> +            continue;
> +        }
> +
> +        if (vfd.flags & V4L2_FMT_FLAG_EMULATED) {
> +            av_log(ctx, AV_LOG_WARNING, "%s", "Emulated");
> +            continue;
> +        }
> +#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
> +        list_framesizes(ctx, fd, vfd.pixelformat);
> +#endif
> +        av_log(ctx, AV_LOG_INFO, "\n");
> +    }
> +}
> +
>  static int mmap_init(AVFormatContext *ctx)
>  {
>      struct video_data *s = ctx->priv_data;
> @@ -621,6 +692,12 @@ static int v4l2_read_header(AVFormatContext *s1, 
> AVFormatParameters *ap)
>          goto out;
>      }
>  
> +    if (s->list_format) {
> +        list_formats(s1, s->fd, s->list_format);
> +        res = AVERROR_EXIT;
> +        goto out;
> +    }
> +
>      avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
>  
>      if (s->video_size &&
> @@ -629,12 +706,18 @@ 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) {
> +
> +        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) {
> @@ -737,6 +820,10 @@ static const AVOption options[] = {
>      { "video_size",   "A string describing frame size, such as 640x480 or 
> hd720.", OFFSET(video_size),   AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,      
>  DEC },
>      { "pixel_format", "",                                                    
>       OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       
> DEC },
>      { "framerate",    "",                                                    
>       OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       
> DEC },
> +    { "list_formats", "List available formats and exit",                     
>       OFFSET(list_format),  AV_OPT_TYPE_INT,    {.dbl = 0 },  0, INT_MAX, 
> DEC, "list_formats" },
> +    { "all",          "Show all available formats",                          
>       OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.dbl = V4L_ALLFORMATS  },    
> 0, INT_MAX, DEC, "list_formats" },
> +    { "raw",          "Show only non-compressed formats",                    
>       OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.dbl = V4L_RAWFORMATS  },    
> 0, INT_MAX, DEC, "list_formats" },
> +    { "compressed",   "Show only compressed formats",                        
>       OFFSET(list_format),  AV_OPT_TYPE_CONST,  {.dbl = V4L_COMPFORMATS },    
> 0, INT_MAX, DEC, "list_formats" },
>      { NULL },
>  };

still ok otherwise

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

Reply via email to