Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: uvcvideo: Add a metadata device node

Some UVC video cameras contain metadata in their payload headers. This
patch extracts that data, adding more clock synchronisation information,
on both bulk and isochronous endpoints and makes it available to the user
space on a separate video node, using the V4L2_CAP_META_CAPTURE capability
and the V4L2_BUF_TYPE_META_CAPTURE buffer queue type. By default, only the
V4L2_META_FMT_UVC pixel format is available from those nodes. However,
cameras can be added to the device ID table to additionally specify their
own metadata format, in which case that format will also become available
from the metadata node.

[Use put_unaligned instead of __put_unaligned_cpu64]
[Use put_unaligned for the sof field as well]

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@intel.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Guennadi Liakhovetski and committed by
Mauro Carvalho Chehab
088ead25 3bc85817

+396 -22
+1 -1
drivers/media/usb/uvc/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \ 3 - uvc_status.o uvc_isight.o uvc_debugfs.o 3 + uvc_status.o uvc_isight.o uvc_debugfs.o uvc_metadata.o 4 4 ifeq ($(CONFIG_MEDIA_CONTROLLER),y) 5 5 uvcvideo-objs += uvc_entity.o 6 6 endif
+14 -1
drivers/media/usb/uvc/uvc_driver.c
··· 1883 1883 continue; 1884 1884 1885 1885 video_unregister_device(&stream->vdev); 1886 + video_unregister_device(&stream->meta.vdev); 1886 1887 1887 1888 uvc_debugfs_cleanup_stream(stream); 1888 1889 } ··· 1931 1930 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1932 1931 vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; 1933 1932 break; 1933 + case V4L2_BUF_TYPE_META_CAPTURE: 1934 + vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; 1935 + break; 1934 1936 } 1935 1937 1936 1938 strlcpy(vdev->name, dev->name, sizeof vdev->name); ··· 1969 1965 } 1970 1966 1971 1967 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1972 - stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE; 1968 + stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE 1969 + | V4L2_CAP_META_CAPTURE; 1973 1970 else 1974 1971 stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT; 1975 1972 ··· 2008 2003 if (ret < 0) 2009 2004 return ret; 2010 2005 2006 + /* Register a metadata node, but ignore a possible failure, 2007 + * complete registration of video nodes anyway. 2008 + */ 2009 + uvc_meta_register(stream); 2010 + 2011 2011 term->vdev = &stream->vdev; 2012 2012 } 2013 2013 ··· 2047 2037 2048 2038 struct uvc_device_info { 2049 2039 u32 quirks; 2040 + u32 meta_format; 2050 2041 }; 2051 2042 2052 2043 static int uvc_probe(struct usb_interface *intf, ··· 2085 2074 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; 2086 2075 dev->quirks = (uvc_quirks_param == -1) 2087 2076 ? quirks : uvc_quirks_param; 2077 + if (info) 2078 + dev->meta_format = info->meta_format; 2088 2079 2089 2080 if (udev->product != NULL) 2090 2081 strlcpy(dev->name, udev->product, sizeof dev->name);
+1 -1
drivers/media/usb/uvc/uvc_isight.c
··· 100 100 } 101 101 102 102 void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, 103 - struct uvc_buffer *buf) 103 + struct uvc_buffer *buf, struct uvc_buffer *meta_buf) 104 104 { 105 105 int ret, i; 106 106
+179
drivers/media/usb/uvc/uvc_metadata.c
··· 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 + 13 + #include <linux/kernel.h> 14 + #include <linux/list.h> 15 + #include <linux/module.h> 16 + #include <linux/usb.h> 17 + #include <linux/videodev2.h> 18 + 19 + #include <media/v4l2-ioctl.h> 20 + #include <media/videobuf2-v4l2.h> 21 + #include <media/videobuf2-vmalloc.h> 22 + 23 + #include "uvcvideo.h" 24 + 25 + /* ----------------------------------------------------------------------------- 26 + * V4L2 ioctls 27 + */ 28 + 29 + static int uvc_meta_v4l2_querycap(struct file *file, void *fh, 30 + struct v4l2_capability *cap) 31 + { 32 + struct v4l2_fh *vfh = file->private_data; 33 + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); 34 + struct uvc_video_chain *chain = stream->chain; 35 + 36 + strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver)); 37 + strlcpy(cap->card, vfh->vdev->name, sizeof(cap->card)); 38 + usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info)); 39 + cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING 40 + | chain->caps; 41 + 42 + return 0; 43 + } 44 + 45 + static int uvc_meta_v4l2_get_format(struct file *file, void *fh, 46 + struct v4l2_format *format) 47 + { 48 + struct v4l2_fh *vfh = file->private_data; 49 + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); 50 + struct v4l2_meta_format *fmt = &format->fmt.meta; 51 + 52 + if (format->type != vfh->vdev->queue->type) 53 + return -EINVAL; 54 + 55 + memset(fmt, 0, sizeof(*fmt)); 56 + 57 + fmt->dataformat = stream->meta.format; 58 + fmt->buffersize = UVC_METATADA_BUF_SIZE; 59 + 60 + return 0; 61 + } 62 + 63 + static int uvc_meta_v4l2_try_format(struct file *file, void *fh, 64 + struct v4l2_format *format) 65 + { 66 + struct v4l2_fh *vfh = file->private_data; 67 + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); 68 + struct uvc_device *dev = stream->dev; 69 + struct v4l2_meta_format *fmt = &format->fmt.meta; 70 + u32 fmeta = fmt->dataformat; 71 + 72 + if (format->type != vfh->vdev->queue->type) 73 + return -EINVAL; 74 + 75 + memset(fmt, 0, sizeof(*fmt)); 76 + 77 + fmt->dataformat = fmeta == dev->meta_format ? fmeta : V4L2_META_FMT_UVC; 78 + fmt->buffersize = UVC_METATADA_BUF_SIZE; 79 + 80 + return 0; 81 + } 82 + 83 + static int uvc_meta_v4l2_set_format(struct file *file, void *fh, 84 + struct v4l2_format *format) 85 + { 86 + struct v4l2_fh *vfh = file->private_data; 87 + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); 88 + struct v4l2_meta_format *fmt = &format->fmt.meta; 89 + int ret; 90 + 91 + ret = uvc_meta_v4l2_try_format(file, fh, format); 92 + if (ret < 0) 93 + return ret; 94 + 95 + /* 96 + * We could in principle switch at any time, also during streaming. 97 + * Metadata buffers would still be perfectly parseable, but it's more 98 + * consistent and cleaner to disallow that. 99 + */ 100 + mutex_lock(&stream->mutex); 101 + 102 + if (uvc_queue_allocated(&stream->queue)) 103 + ret = -EBUSY; 104 + else 105 + stream->meta.format = fmt->dataformat; 106 + 107 + mutex_unlock(&stream->mutex); 108 + 109 + return ret; 110 + } 111 + 112 + static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh, 113 + struct v4l2_fmtdesc *fdesc) 114 + { 115 + struct v4l2_fh *vfh = file->private_data; 116 + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); 117 + struct uvc_device *dev = stream->dev; 118 + u32 index = fdesc->index; 119 + 120 + if (fdesc->type != vfh->vdev->queue->type || 121 + index > 1U || (index && !dev->meta_format)) 122 + return -EINVAL; 123 + 124 + memset(fdesc, 0, sizeof(*fdesc)); 125 + 126 + fdesc->type = vfh->vdev->queue->type; 127 + fdesc->index = index; 128 + fdesc->pixelformat = index ? dev->meta_format : V4L2_META_FMT_UVC; 129 + 130 + return 0; 131 + } 132 + 133 + static const struct v4l2_ioctl_ops uvc_meta_ioctl_ops = { 134 + .vidioc_querycap = uvc_meta_v4l2_querycap, 135 + .vidioc_g_fmt_meta_cap = uvc_meta_v4l2_get_format, 136 + .vidioc_s_fmt_meta_cap = uvc_meta_v4l2_set_format, 137 + .vidioc_try_fmt_meta_cap = uvc_meta_v4l2_try_format, 138 + .vidioc_enum_fmt_meta_cap = uvc_meta_v4l2_enum_formats, 139 + .vidioc_reqbufs = vb2_ioctl_reqbufs, 140 + .vidioc_querybuf = vb2_ioctl_querybuf, 141 + .vidioc_qbuf = vb2_ioctl_qbuf, 142 + .vidioc_dqbuf = vb2_ioctl_dqbuf, 143 + .vidioc_create_bufs = vb2_ioctl_create_bufs, 144 + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 145 + .vidioc_streamon = vb2_ioctl_streamon, 146 + .vidioc_streamoff = vb2_ioctl_streamoff, 147 + }; 148 + 149 + /* ----------------------------------------------------------------------------- 150 + * V4L2 File Operations 151 + */ 152 + 153 + static const struct v4l2_file_operations uvc_meta_fops = { 154 + .owner = THIS_MODULE, 155 + .unlocked_ioctl = video_ioctl2, 156 + .open = v4l2_fh_open, 157 + .release = vb2_fop_release, 158 + .poll = vb2_fop_poll, 159 + .mmap = vb2_fop_mmap, 160 + }; 161 + 162 + int uvc_meta_register(struct uvc_streaming *stream) 163 + { 164 + struct uvc_device *dev = stream->dev; 165 + struct video_device *vdev = &stream->meta.vdev; 166 + struct uvc_video_queue *queue = &stream->meta.queue; 167 + 168 + stream->meta.format = V4L2_META_FMT_UVC; 169 + 170 + /* 171 + * The video interface queue uses manual locking and thus does not set 172 + * the queue pointer. Set it manually here. 173 + */ 174 + vdev->queue = &queue->queue; 175 + 176 + return uvc_register_video_device(dev, stream, vdev, queue, 177 + V4L2_BUF_TYPE_META_CAPTURE, 178 + &uvc_meta_fops, &uvc_meta_ioctl_ops); 179 + }
+37 -7
drivers/media/usb/uvc/uvc_queue.c
··· 79 79 unsigned int sizes[], struct device *alloc_devs[]) 80 80 { 81 81 struct uvc_video_queue *queue = vb2_get_drv_priv(vq); 82 - struct uvc_streaming *stream = uvc_queue_to_stream(queue); 83 - unsigned size = stream->ctrl.dwMaxVideoFrameSize; 82 + struct uvc_streaming *stream; 83 + unsigned int size; 84 + 85 + switch (vq->type) { 86 + case V4L2_BUF_TYPE_META_CAPTURE: 87 + size = UVC_METATADA_BUF_SIZE; 88 + break; 89 + 90 + default: 91 + stream = uvc_queue_to_stream(queue); 92 + size = stream->ctrl.dwMaxVideoFrameSize; 93 + break; 94 + } 84 95 85 96 /* 86 97 * When called with plane sizes, validate them. The driver supports ··· 125 114 buf->error = 0; 126 115 buf->mem = vb2_plane_vaddr(vb, 0); 127 116 buf->length = vb2_plane_size(vb, 0); 128 - if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 117 + if (vb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 129 118 buf->bytesused = 0; 130 119 else 131 120 buf->bytesused = vb2_get_plane_payload(vb, 0); ··· 188 177 static void uvc_stop_streaming(struct vb2_queue *vq) 189 178 { 190 179 struct uvc_video_queue *queue = vb2_get_drv_priv(vq); 191 - struct uvc_streaming *stream = uvc_queue_to_stream(queue); 192 180 unsigned long flags; 193 181 194 - uvc_video_enable(stream, 0); 182 + if (vq->type != V4L2_BUF_TYPE_META_CAPTURE) 183 + uvc_video_enable(uvc_queue_to_stream(queue), 0); 195 184 196 185 spin_lock_irqsave(&queue->irqlock, flags); 197 186 uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR); ··· 209 198 .stop_streaming = uvc_stop_streaming, 210 199 }; 211 200 201 + static const struct vb2_ops uvc_meta_queue_qops = { 202 + .queue_setup = uvc_queue_setup, 203 + .buf_prepare = uvc_buffer_prepare, 204 + .buf_queue = uvc_buffer_queue, 205 + .wait_prepare = vb2_ops_wait_prepare, 206 + .wait_finish = vb2_ops_wait_finish, 207 + .stop_streaming = uvc_stop_streaming, 208 + }; 209 + 212 210 int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, 213 211 int drop_corrupted) 214 212 { 215 213 int ret; 216 214 217 215 queue->queue.type = type; 218 - queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 216 + queue->queue.io_modes = VB2_MMAP | VB2_USERPTR; 219 217 queue->queue.drv_priv = queue; 220 218 queue->queue.buf_struct_size = sizeof(struct uvc_buffer); 221 - queue->queue.ops = &uvc_queue_qops; 222 219 queue->queue.mem_ops = &vb2_vmalloc_memops; 223 220 queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 224 221 | V4L2_BUF_FLAG_TSTAMP_SRC_SOE; 225 222 queue->queue.lock = &queue->mutex; 223 + 224 + switch (type) { 225 + case V4L2_BUF_TYPE_META_CAPTURE: 226 + queue->queue.ops = &uvc_meta_queue_qops; 227 + break; 228 + default: 229 + queue->queue.io_modes |= VB2_DMABUF; 230 + queue->queue.ops = &uvc_queue_qops; 231 + break; 232 + } 233 + 226 234 ret = vb2_queue_init(&queue->queue); 227 235 if (ret) 228 236 return ret;
+124 -10
drivers/media/usb/uvc/uvc_video.c
··· 1120 1120 } 1121 1121 1122 1122 /* ------------------------------------------------------------------------ 1123 + * Metadata 1124 + */ 1125 + 1126 + /* 1127 + * Additionally to the payload headers we also want to provide the user with USB 1128 + * Frame Numbers and system time values. The resulting buffer is thus composed 1129 + * of blocks, containing a 64-bit timestamp in nanoseconds, a 16-bit USB Frame 1130 + * Number, and a copy of the payload header. 1131 + * 1132 + * Ideally we want to capture all payload headers for each frame. However, their 1133 + * number is unknown and unbound. We thus drop headers that contain no vendor 1134 + * data and that either contain no SCR value or an SCR value identical to the 1135 + * previous header. 1136 + */ 1137 + static void uvc_video_decode_meta(struct uvc_streaming *stream, 1138 + struct uvc_buffer *meta_buf, 1139 + const u8 *mem, unsigned int length) 1140 + { 1141 + struct uvc_meta_buf *meta; 1142 + size_t len_std = 2; 1143 + bool has_pts, has_scr; 1144 + unsigned long flags; 1145 + unsigned int sof; 1146 + ktime_t time; 1147 + const u8 *scr; 1148 + 1149 + if (!meta_buf || length == 2) 1150 + return; 1151 + 1152 + if (meta_buf->length - meta_buf->bytesused < 1153 + length + sizeof(meta->ns) + sizeof(meta->sof)) { 1154 + meta_buf->error = 1; 1155 + return; 1156 + } 1157 + 1158 + has_pts = mem[1] & UVC_STREAM_PTS; 1159 + has_scr = mem[1] & UVC_STREAM_SCR; 1160 + 1161 + if (has_pts) { 1162 + len_std += 4; 1163 + scr = mem + 6; 1164 + } else { 1165 + scr = mem + 2; 1166 + } 1167 + 1168 + if (has_scr) 1169 + len_std += 6; 1170 + 1171 + if (stream->meta.format == V4L2_META_FMT_UVC) 1172 + length = len_std; 1173 + 1174 + if (length == len_std && (!has_scr || 1175 + !memcmp(scr, stream->clock.last_scr, 6))) 1176 + return; 1177 + 1178 + meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused); 1179 + local_irq_save(flags); 1180 + time = uvc_video_get_time(); 1181 + sof = usb_get_current_frame_number(stream->dev->udev); 1182 + local_irq_restore(flags); 1183 + put_unaligned(ktime_to_ns(time), &meta->ns); 1184 + put_unaligned(sof, &meta->sof); 1185 + 1186 + if (has_scr) 1187 + memcpy(stream->clock.last_scr, scr, 6); 1188 + 1189 + memcpy(&meta->length, mem, length); 1190 + meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof); 1191 + 1192 + uvc_trace(UVC_TRACE_FRAME, 1193 + "%s(): t-sys %lluns, SOF %u, len %u, flags 0x%x, PTS %u, STC %u frame SOF %u\n", 1194 + __func__, time, meta->sof, meta->length, meta->flags, 1195 + has_pts ? *(u32 *)meta->buf : 0, 1196 + has_scr ? *(u32 *)scr : 0, 1197 + has_scr ? *(u32 *)(scr + 4) & 0x7ff : 0); 1198 + } 1199 + 1200 + /* ------------------------------------------------------------------------ 1123 1201 * URB handling 1124 1202 */ 1125 1203 ··· 1215 1137 /* 1216 1138 * Completion handler for video URBs. 1217 1139 */ 1140 + 1141 + static void uvc_video_next_buffers(struct uvc_streaming *stream, 1142 + struct uvc_buffer **video_buf, struct uvc_buffer **meta_buf) 1143 + { 1144 + if (*meta_buf) { 1145 + struct vb2_v4l2_buffer *vb2_meta = &(*meta_buf)->buf; 1146 + const struct vb2_v4l2_buffer *vb2_video = &(*video_buf)->buf; 1147 + 1148 + vb2_meta->sequence = vb2_video->sequence; 1149 + vb2_meta->field = vb2_video->field; 1150 + vb2_meta->vb2_buf.timestamp = vb2_video->vb2_buf.timestamp; 1151 + 1152 + (*meta_buf)->state = UVC_BUF_STATE_READY; 1153 + if (!(*meta_buf)->error) 1154 + (*meta_buf)->error = (*video_buf)->error; 1155 + *meta_buf = uvc_queue_next_buffer(&stream->meta.queue, 1156 + *meta_buf); 1157 + } 1158 + *video_buf = uvc_queue_next_buffer(&stream->queue, *video_buf); 1159 + } 1160 + 1218 1161 static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, 1219 - struct uvc_buffer *buf) 1162 + struct uvc_buffer *buf, struct uvc_buffer *meta_buf) 1220 1163 { 1221 1164 u8 *mem; 1222 1165 int ret, i; ··· 1259 1160 urb->iso_frame_desc[i].actual_length); 1260 1161 if (ret == -EAGAIN) { 1261 1162 uvc_video_validate_buffer(stream, buf); 1262 - buf = uvc_queue_next_buffer(&stream->queue, 1263 - buf); 1163 + uvc_video_next_buffers(stream, &buf, &meta_buf); 1264 1164 } 1265 1165 } while (ret == -EAGAIN); 1266 1166 1267 1167 if (ret < 0) 1268 1168 continue; 1169 + 1170 + uvc_video_decode_meta(stream, meta_buf, mem, ret); 1269 1171 1270 1172 /* Decode the payload data. */ 1271 1173 uvc_video_decode_data(stream, buf, mem + ret, ··· 1278 1178 1279 1179 if (buf->state == UVC_BUF_STATE_READY) { 1280 1180 uvc_video_validate_buffer(stream, buf); 1281 - buf = uvc_queue_next_buffer(&stream->queue, buf); 1181 + uvc_video_next_buffers(stream, &buf, &meta_buf); 1282 1182 } 1283 1183 } 1284 1184 } 1285 1185 1286 1186 static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, 1287 - struct uvc_buffer *buf) 1187 + struct uvc_buffer *buf, struct uvc_buffer *meta_buf) 1288 1188 { 1289 1189 u8 *mem; 1290 1190 int len, ret; ··· 1307 1207 do { 1308 1208 ret = uvc_video_decode_start(stream, buf, mem, len); 1309 1209 if (ret == -EAGAIN) 1310 - buf = uvc_queue_next_buffer(&stream->queue, 1311 - buf); 1210 + uvc_video_next_buffers(stream, &buf, &meta_buf); 1312 1211 } while (ret == -EAGAIN); 1313 1212 1314 1213 /* If an error occurred skip the rest of the payload. */ ··· 1316 1217 } else { 1317 1218 memcpy(stream->bulk.header, mem, ret); 1318 1219 stream->bulk.header_size = ret; 1220 + 1221 + uvc_video_decode_meta(stream, meta_buf, mem, ret); 1319 1222 1320 1223 mem += ret; 1321 1224 len -= ret; ··· 1342 1241 uvc_video_decode_end(stream, buf, stream->bulk.header, 1343 1242 stream->bulk.payload_size); 1344 1243 if (buf->state == UVC_BUF_STATE_READY) 1345 - uvc_queue_next_buffer(&stream->queue, buf); 1244 + uvc_video_next_buffers(stream, &buf, &meta_buf); 1346 1245 } 1347 1246 1348 1247 stream->bulk.header_size = 0; ··· 1352 1251 } 1353 1252 1354 1253 static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream, 1355 - struct uvc_buffer *buf) 1254 + struct uvc_buffer *buf, struct uvc_buffer *meta_buf) 1356 1255 { 1357 1256 u8 *mem = urb->transfer_buffer; 1358 1257 int len = stream->urb_size, ret; ··· 1398 1297 { 1399 1298 struct uvc_streaming *stream = urb->context; 1400 1299 struct uvc_video_queue *queue = &stream->queue; 1300 + struct uvc_video_queue *qmeta = &stream->meta.queue; 1301 + struct vb2_queue *vb2_qmeta = stream->meta.vdev.queue; 1401 1302 struct uvc_buffer *buf = NULL; 1303 + struct uvc_buffer *buf_meta = NULL; 1402 1304 unsigned long flags; 1403 1305 int ret; 1404 1306 ··· 1420 1316 case -ECONNRESET: /* usb_unlink_urb() called. */ 1421 1317 case -ESHUTDOWN: /* The endpoint is being disabled. */ 1422 1318 uvc_queue_cancel(queue, urb->status == -ESHUTDOWN); 1319 + if (vb2_qmeta) 1320 + uvc_queue_cancel(qmeta, urb->status == -ESHUTDOWN); 1423 1321 return; 1424 1322 } 1425 1323 ··· 1431 1325 queue); 1432 1326 spin_unlock_irqrestore(&queue->irqlock, flags); 1433 1327 1434 - stream->decode(urb, stream, buf); 1328 + if (vb2_qmeta) { 1329 + spin_lock_irqsave(&qmeta->irqlock, flags); 1330 + if (!list_empty(&qmeta->irqqueue)) 1331 + buf_meta = list_first_entry(&qmeta->irqqueue, 1332 + struct uvc_buffer, queue); 1333 + spin_unlock_irqrestore(&qmeta->irqlock, flags); 1334 + } 1335 + 1336 + stream->decode(urb, stream, buf, buf_meta); 1435 1337 1436 1338 if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 1437 1339 uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
+14 -2
drivers/media/usb/uvc/uvcvideo.h
··· 479 479 unsigned int max_sof; /* Maximum STC.SOF value */ 480 480 }; 481 481 482 + #define UVC_METATADA_BUF_SIZE 1024 483 + 482 484 struct uvc_streaming { 483 485 struct list_head list; 484 486 struct uvc_device *dev; ··· 512 510 unsigned int frozen : 1; 513 511 struct uvc_video_queue queue; 514 512 void (*decode) (struct urb *urb, struct uvc_streaming *video, 515 - struct uvc_buffer *buf); 513 + struct uvc_buffer *buf, struct uvc_buffer *meta_buf); 514 + 515 + struct { 516 + struct video_device vdev; 517 + struct uvc_video_queue queue; 518 + __u32 format; 519 + } meta; 516 520 517 521 /* Context data used by the bulk completion handler. */ 518 522 struct { ··· 560 552 u16 last_sof; 561 553 u16 sof_offset; 562 554 555 + u8 last_scr[6]; 556 + 563 557 spinlock_t lock; 564 558 } clock; 565 559 }; ··· 571 561 struct usb_interface *intf; 572 562 unsigned long warnings; 573 563 __u32 quirks; 564 + __u32 meta_format; 574 565 int intfnum; 575 566 char name[32]; 576 567 ··· 726 715 void uvc_video_clock_update(struct uvc_streaming *stream, 727 716 struct vb2_v4l2_buffer *vbuf, 728 717 struct uvc_buffer *buf); 718 + int uvc_meta_register(struct uvc_streaming *stream); 729 719 730 720 int uvc_register_video_device(struct uvc_device *dev, 731 721 struct uvc_streaming *stream, ··· 789 777 790 778 /* Quirks support */ 791 779 void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, 792 - struct uvc_buffer *buf); 780 + struct uvc_buffer *buf, struct uvc_buffer *meta_buf); 793 781 794 782 /* debugfs and statistics */ 795 783 void uvc_debugfs_init(void);
+26
include/uapi/linux/uvcvideo.h
··· 68 68 #define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping) 69 69 #define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query) 70 70 71 + /* 72 + * Metadata node 73 + */ 74 + 75 + /** 76 + * struct uvc_meta_buf - metadata buffer building block 77 + * @ns - system timestamp of the payload in nanoseconds 78 + * @sof - USB Frame Number 79 + * @length - length of the payload header 80 + * @flags - payload header flags 81 + * @buf - optional device-specific header data 82 + * 83 + * UVC metadata nodes fill buffers with possibly multiple instances of this 84 + * struct. The first two fields are added by the driver, they can be used for 85 + * clock synchronisation. The rest is an exact copy of a UVC payload header. 86 + * Only complete objects with complete buffers are included. Therefore it's 87 + * always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large. 88 + */ 89 + struct uvc_meta_buf { 90 + __u64 ns; 91 + __u16 sof; 92 + __u8 length; 93 + __u8 flags; 94 + __u8 buf[]; 95 + } __packed; 96 + 71 97 #endif