root/drivers/media/usb/uvc/uvc_metadata.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uvc_meta_v4l2_querycap
  2. uvc_meta_v4l2_get_format
  3. uvc_meta_v4l2_try_format
  4. uvc_meta_v4l2_set_format
  5. uvc_meta_v4l2_enum_formats
  6. uvc_meta_register

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *      uvc_metadata.c  --  USB Video Class driver - Metadata handling
   4  *
   5  *      Copyright (C) 2016
   6  *          Guennadi Liakhovetski (guennadi.liakhovetski@intel.com)
   7  */
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/list.h>
  11 #include <linux/module.h>
  12 #include <linux/usb.h>
  13 #include <linux/videodev2.h>
  14 
  15 #include <media/v4l2-ioctl.h>
  16 #include <media/videobuf2-v4l2.h>
  17 #include <media/videobuf2-vmalloc.h>
  18 
  19 #include "uvcvideo.h"
  20 
  21 /* -----------------------------------------------------------------------------
  22  * V4L2 ioctls
  23  */
  24 
  25 static int uvc_meta_v4l2_querycap(struct file *file, void *fh,
  26                                   struct v4l2_capability *cap)
  27 {
  28         struct v4l2_fh *vfh = file->private_data;
  29         struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
  30         struct uvc_video_chain *chain = stream->chain;
  31 
  32         strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
  33         strscpy(cap->card, vfh->vdev->name, sizeof(cap->card));
  34         usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
  35         cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
  36                           | chain->caps;
  37 
  38         return 0;
  39 }
  40 
  41 static int uvc_meta_v4l2_get_format(struct file *file, void *fh,
  42                                     struct v4l2_format *format)
  43 {
  44         struct v4l2_fh *vfh = file->private_data;
  45         struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
  46         struct v4l2_meta_format *fmt = &format->fmt.meta;
  47 
  48         if (format->type != vfh->vdev->queue->type)
  49                 return -EINVAL;
  50 
  51         memset(fmt, 0, sizeof(*fmt));
  52 
  53         fmt->dataformat = stream->meta.format;
  54         fmt->buffersize = UVC_METATADA_BUF_SIZE;
  55 
  56         return 0;
  57 }
  58 
  59 static int uvc_meta_v4l2_try_format(struct file *file, void *fh,
  60                                     struct v4l2_format *format)
  61 {
  62         struct v4l2_fh *vfh = file->private_data;
  63         struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
  64         struct uvc_device *dev = stream->dev;
  65         struct v4l2_meta_format *fmt = &format->fmt.meta;
  66         u32 fmeta = fmt->dataformat;
  67 
  68         if (format->type != vfh->vdev->queue->type)
  69                 return -EINVAL;
  70 
  71         memset(fmt, 0, sizeof(*fmt));
  72 
  73         fmt->dataformat = fmeta == dev->info->meta_format
  74                         ? fmeta : V4L2_META_FMT_UVC;
  75         fmt->buffersize = UVC_METATADA_BUF_SIZE;
  76 
  77         return 0;
  78 }
  79 
  80 static int uvc_meta_v4l2_set_format(struct file *file, void *fh,
  81                                     struct v4l2_format *format)
  82 {
  83         struct v4l2_fh *vfh = file->private_data;
  84         struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
  85         struct v4l2_meta_format *fmt = &format->fmt.meta;
  86         int ret;
  87 
  88         ret = uvc_meta_v4l2_try_format(file, fh, format);
  89         if (ret < 0)
  90                 return ret;
  91 
  92         /*
  93          * We could in principle switch at any time, also during streaming.
  94          * Metadata buffers would still be perfectly parseable, but it's more
  95          * consistent and cleaner to disallow that.
  96          */
  97         mutex_lock(&stream->mutex);
  98 
  99         if (uvc_queue_allocated(&stream->queue))
 100                 ret = -EBUSY;
 101         else
 102                 stream->meta.format = fmt->dataformat;
 103 
 104         mutex_unlock(&stream->mutex);
 105 
 106         return ret;
 107 }
 108 
 109 static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh,
 110                                       struct v4l2_fmtdesc *fdesc)
 111 {
 112         struct v4l2_fh *vfh = file->private_data;
 113         struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
 114         struct uvc_device *dev = stream->dev;
 115         u32 index = fdesc->index;
 116 
 117         if (fdesc->type != vfh->vdev->queue->type ||
 118             index > 1U || (index && !dev->info->meta_format))
 119                 return -EINVAL;
 120 
 121         memset(fdesc, 0, sizeof(*fdesc));
 122 
 123         fdesc->type = vfh->vdev->queue->type;
 124         fdesc->index = index;
 125         fdesc->pixelformat = index ? dev->info->meta_format : V4L2_META_FMT_UVC;
 126 
 127         return 0;
 128 }
 129 
 130 static const struct v4l2_ioctl_ops uvc_meta_ioctl_ops = {
 131         .vidioc_querycap                = uvc_meta_v4l2_querycap,
 132         .vidioc_g_fmt_meta_cap          = uvc_meta_v4l2_get_format,
 133         .vidioc_s_fmt_meta_cap          = uvc_meta_v4l2_set_format,
 134         .vidioc_try_fmt_meta_cap        = uvc_meta_v4l2_try_format,
 135         .vidioc_enum_fmt_meta_cap       = uvc_meta_v4l2_enum_formats,
 136         .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
 137         .vidioc_querybuf                = vb2_ioctl_querybuf,
 138         .vidioc_qbuf                    = vb2_ioctl_qbuf,
 139         .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
 140         .vidioc_create_bufs             = vb2_ioctl_create_bufs,
 141         .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
 142         .vidioc_streamon                = vb2_ioctl_streamon,
 143         .vidioc_streamoff               = vb2_ioctl_streamoff,
 144 };
 145 
 146 /* -----------------------------------------------------------------------------
 147  * V4L2 File Operations
 148  */
 149 
 150 static const struct v4l2_file_operations uvc_meta_fops = {
 151         .owner = THIS_MODULE,
 152         .unlocked_ioctl = video_ioctl2,
 153         .open = v4l2_fh_open,
 154         .release = vb2_fop_release,
 155         .poll = vb2_fop_poll,
 156         .mmap = vb2_fop_mmap,
 157 };
 158 
 159 int uvc_meta_register(struct uvc_streaming *stream)
 160 {
 161         struct uvc_device *dev = stream->dev;
 162         struct video_device *vdev = &stream->meta.vdev;
 163         struct uvc_video_queue *queue = &stream->meta.queue;
 164 
 165         stream->meta.format = V4L2_META_FMT_UVC;
 166 
 167         /*
 168          * The video interface queue uses manual locking and thus does not set
 169          * the queue pointer. Set it manually here.
 170          */
 171         vdev->queue = &queue->queue;
 172 
 173         return uvc_register_video_device(dev, stream, vdev, queue,
 174                                          V4L2_BUF_TYPE_META_CAPTURE,
 175                                          &uvc_meta_fops, &uvc_meta_ioctl_ops);
 176 }

/* [<][>][^][v][top][bottom][index][help] */