uvc_metadata.c 5.1 KB

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