History

media: v4l2: abstract timeval handling in v4l2_buffer

As a preparation for adding 64-bit time_t support in the uapi, change the drivers to no longer care about the format of the timestamp field in struct v4l2_buffer. The v4l2_timeval_to_ns() function is no longer needed in the kernel after this, but there is userspace code relying on it to be part of the uapi header.

Arnd Bergmann committed 6 years ago

Commit 77cdffc1 parent 71e37d29 files · +36 −12Browse files

Unified · Split

9 files
  1. drivers/media/common/videobuf2/videobuf2-v4l2.c +2 −2
  2. drivers/media/pci/meye/meye.c +2 −2
  3. drivers/media/usb/cpia2/cpia2_v4l.c +2 −2
  4. drivers/media/usb/stkwebcam/stk-webcam.c +1 −1
  5. drivers/media/usb/usbvision/usbvision-video.c +2 −2
  6. drivers/media/v4l2-core/videobuf-core.c +3 −2
  7. include/media/v4l2-common.h +21 −0
  8. include/trace/events/v4l2.h +1 −1
  9. include/uapi/linux/videodev2.h +2 −0
drivers/media/common/videobuf2/videobuf2-v4l2.c+2−2
@@ -146,7 +146,7 @@ static void __copy_timestamp(struct vb2_buffer *vb, const void *pb) · 145 unmodified lines
146 * and the timecode field and flag if needed.146 * and the timecode field and flag if needed.
147 */147 */
148 if (q->copy_timestamp)148 if (q->copy_timestamp)
149 vb->timestamp = v4l2_timeval_to_ns(&b->timestamp);149 vb->timestamp = v4l2_buffer_get_timestamp(b);
150 vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;150 vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
151 if (b->flags & V4L2_BUF_FLAG_TIMECODE)151 if (b->flags & V4L2_BUF_FLAG_TIMECODE)
152 vbuf->timecode = b->timecode;152 vbuf->timecode = b->timecode;
@@ -482,7 +482,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) · 329 unmodified lines
482 482
483 b->flags = vbuf->flags;483 b->flags = vbuf->flags;
484 b->field = vbuf->field;484 b->field = vbuf->field;
485 b->timestamp = ns_to_timeval(vb->timestamp);485 v4l2_buffer_set_timestamp(b, vb->timestamp);
486 b->timecode = vbuf->timecode;486 b->timecode = vbuf->timecode;
487 b->sequence = vbuf->sequence;487 b->sequence = vbuf->sequence;
488 b->reserved2 = 0;488 b->reserved2 = 0;
drivers/media/pci/meye/meye.c+2−2
@@ -1266,7 +1266,7 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 1265 unmodified lines
1266 buf->flags |= V4L2_BUF_FLAG_DONE;1266 buf->flags |= V4L2_BUF_FLAG_DONE;
1267 1267
1268 buf->field = V4L2_FIELD_NONE;1268 buf->field = V4L2_FIELD_NONE;
1269 buf->timestamp = ns_to_timeval(meye.grab_buffer[index].ts);1269 v4l2_buffer_set_timestamp(buf, meye.grab_buffer[index].ts);
1270 buf->sequence = meye.grab_buffer[index].sequence;1270 buf->sequence = meye.grab_buffer[index].sequence;
1271 buf->memory = V4L2_MEMORY_MMAP;1271 buf->memory = V4L2_MEMORY_MMAP;
1272 buf->m.offset = index * gbufsize;1272 buf->m.offset = index * gbufsize;
@@ -1332,7 +1332,7 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 59 unmodified lines
1332 buf->bytesused = meye.grab_buffer[reqnr].size;1332 buf->bytesused = meye.grab_buffer[reqnr].size;
1333 buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;1333 buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1334 buf->field = V4L2_FIELD_NONE;1334 buf->field = V4L2_FIELD_NONE;
1335 buf->timestamp = ns_to_timeval(meye.grab_buffer[reqnr].ts);1335 v4l2_buffer_set_timestamp(buf, meye.grab_buffer[reqnr].ts);
1336 buf->sequence = meye.grab_buffer[reqnr].sequence;1336 buf->sequence = meye.grab_buffer[reqnr].sequence;
1337 buf->memory = V4L2_MEMORY_MMAP;1337 buf->memory = V4L2_MEMORY_MMAP;
1338 buf->m.offset = reqnr * gbufsize;1338 buf->m.offset = reqnr * gbufsize;
drivers/media/usb/cpia2/cpia2_v4l.c+2−2
@@ -800,7 +800,7 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 799 unmodified lines
800 break;800 break;
801 case FRAME_READY:801 case FRAME_READY:
802 buf->bytesused = cam->buffers[buf->index].length;802 buf->bytesused = cam->buffers[buf->index].length;
803 buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts);803 v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts);
804 buf->sequence = cam->buffers[buf->index].seq;804 buf->sequence = cam->buffers[buf->index].seq;
805 buf->flags = V4L2_BUF_FLAG_DONE;805 buf->flags = V4L2_BUF_FLAG_DONE;
806 break;806 break;
@@ -907,7 +907,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 100 unmodified lines
907 buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE907 buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE
908 | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;908 | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
909 buf->field = V4L2_FIELD_NONE;909 buf->field = V4L2_FIELD_NONE;
910 buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts);910 v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts);
911 buf->sequence = cam->buffers[buf->index].seq;911 buf->sequence = cam->buffers[buf->index].seq;
912 buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;912 buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
913 buf->length = cam->frame_size;913 buf->length = cam->frame_size;
drivers/media/usb/stkwebcam/stk-webcam.c+1−1
@@ -1125,7 +1125,7 @@ static int stk_vidioc_dqbuf(struct file *filp, · 1124 unmodified lines
1125 sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;1125 sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
1126 sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;1126 sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
1127 sbuf->v4lbuf.sequence = ++dev->sequence;1127 sbuf->v4lbuf.sequence = ++dev->sequence;
1128 sbuf->v4lbuf.timestamp = ns_to_timeval(ktime_get_ns());1128 v4l2_buffer_set_timestamp(&sbuf->v4lbuf, ktime_get_ns());
1129 1129
1130 *buf = sbuf->v4lbuf;1130 *buf = sbuf->v4lbuf;
1131 return 0;1131 return 0;
drivers/media/usb/usbvision/usbvision-video.c+2−2
@@ -696,7 +696,7 @@ static int vidioc_querybuf(struct file *file, · 695 unmodified lines
696 vb->length = usbvision->curwidth *696 vb->length = usbvision->curwidth *
697 usbvision->curheight *697 usbvision->curheight *
698 usbvision->palette.bytes_per_pixel;698 usbvision->palette.bytes_per_pixel;
699 vb->timestamp = ns_to_timeval(usbvision->frame[vb->index].ts);699 v4l2_buffer_set_timestamp(vb, usbvision->frame[vb->index].ts);
700 vb->sequence = usbvision->frame[vb->index].sequence;700 vb->sequence = usbvision->frame[vb->index].sequence;
701 return 0;701 return 0;
702}702}
@@ -765,7 +765,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *vb) · 62 unmodified lines
765 V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;765 V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
766 vb->index = f->index;766 vb->index = f->index;
767 vb->sequence = f->sequence;767 vb->sequence = f->sequence;
768 vb->timestamp = ns_to_timeval(f->ts);768 v4l2_buffer_set_timestamp(vb, f->ts);
769 vb->field = V4L2_FIELD_NONE;769 vb->field = V4L2_FIELD_NONE;
770 vb->bytesused = f->scanlength;770 vb->bytesused = f->scanlength;
771 771
drivers/media/v4l2-core/videobuf-core.c+3−2
@@ -19,6 +19,7 @@ · 18 unmodified lines
19#include <linux/interrupt.h>19#include <linux/interrupt.h>
20 20
21#include <media/videobuf-core.h>21#include <media/videobuf-core.h>
22#include <media/v4l2-common.h>
22 23
23#define MAGIC_BUFFER 0x2007072824#define MAGIC_BUFFER 0x20070728
24#define MAGIC_CHECK(is, should) \25#define MAGIC_CHECK(is, should) \
@@ -364,7 +365,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, · 339 unmodified lines
364 }365 }
365 366
366 b->field = vb->field;367 b->field = vb->field;
367 b->timestamp = ns_to_timeval(vb->ts);368 v4l2_buffer_set_timestamp(b, vb->ts);
368 b->bytesused = vb->size;369 b->bytesused = vb->size;
369 b->sequence = vb->field_count >> 1;370 b->sequence = vb->field_count >> 1;
370}371}
@@ -578,7 +579,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b) · 207 unmodified lines
578 || q->type == V4L2_BUF_TYPE_SDR_OUTPUT) {579 || q->type == V4L2_BUF_TYPE_SDR_OUTPUT) {
579 buf->size = b->bytesused;580 buf->size = b->bytesused;
580 buf->field = b->field;581 buf->field = b->field;
581 buf->ts = v4l2_timeval_to_ns(&b->timestamp);582 buf->ts = v4l2_buffer_get_timestamp(b);
582 }583 }
583 break;584 break;
584 case V4L2_MEMORY_USERPTR:585 case V4L2_MEMORY_USERPTR:
include/media/v4l2-common.h+21−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#ifndef V4L2_COMMON_H_14#ifndef V4L2_COMMON_H_
15#define V4L2_COMMON_H_15#define V4L2_COMMON_H_
16 16
17#include <linux/time.h>
17#include <media/v4l2-dev.h>18#include <media/v4l2-dev.h>
18 19
19/* Common printk constructs for v4l-i2c drivers. These macros create a unique20/* Common printk constructs for v4l-i2c drivers. These macros create a unique
@@ -518,4 +519,24 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, · 498 unmodified lines
518int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,519int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
519 u32 width, u32 height);520 u32 width, u32 height);
520 521
522static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf)
523{
524 /*
525 * When the timestamp comes from 32-bit user space, there may be
526 * uninitialized data in tv_usec, so cast it to u32.
527 * Otherwise allow invalid input for backwards compatibility.
528 */
529 return buf->timestamp.tv_sec * NSEC_PER_SEC +
530 (u32)buf->timestamp.tv_usec * NSEC_PER_USEC;
531}
532
533static inline void v4l2_buffer_set_timestamp(struct v4l2_buffer *buf,
534 u64 timestamp)
535{
536 struct timespec64 ts = ns_to_timespec64(timestamp);
537
538 buf->timestamp.tv_sec = ts.tv_sec;
539 buf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
540}
541
521#endif /* V4L2_COMMON_H_ */542#endif /* V4L2_COMMON_H_ */
include/trace/events/v4l2.h+1−1
@@ -130,7 +130,7 @@ DECLARE_EVENT_CLASS(v4l2_event_class, · 129 unmodified lines
130 __entry->bytesused = buf->bytesused;130 __entry->bytesused = buf->bytesused;
131 __entry->flags = buf->flags;131 __entry->flags = buf->flags;
132 __entry->field = buf->field;132 __entry->field = buf->field;
133 __entry->timestamp = timeval_to_ns(&buf->timestamp);133 __entry->timestamp = v4l2_buffer_get_timestamp(buf);
134 __entry->timecode_type = buf->timecode.type;134 __entry->timecode_type = buf->timecode.type;
135 __entry->timecode_flags = buf->timecode.flags;135 __entry->timecode_flags = buf->timecode.flags;
136 __entry->timecode_frames = buf->timecode.frames;136 __entry->timecode_frames = buf->timecode.frames;
include/uapi/linux/videodev2.h+2−0
@@ -1017,6 +1017,7 @@ struct v4l2_buffer { · 1016 unmodified lines
1017 };1017 };
1018};1018};
1019 1019
1020#ifndef __KERNEL__
1020/**1021/**
1021 * v4l2_timeval_to_ns - Convert timeval to nanoseconds1022 * v4l2_timeval_to_ns - Convert timeval to nanoseconds
1022 * @ts: pointer to the timeval variable to be converted1023 * @ts: pointer to the timeval variable to be converted
@@ -1028,6 +1029,7 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv) · 5 unmodified lines
1028{1029{
1029 return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000;1030 return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000;
1030}1031}
1032#endif
1031 1033
1032/* Flags for 'flags' field */1034/* Flags for 'flags' field */
1033/* Buffer is mapped (flag) */1035/* Buffer is mapped (flag) */