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
146146 * and the timecode field and flag if needed.
147147 */
148148 if (q->copy_timestamp)
149− vb->timestamp = v4l2_timeval_to_ns(&b->timestamp);
149+ vb->timestamp = v4l2_buffer_get_timestamp(b);
150150 vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
151151 if (b->flags & V4L2_BUF_FLAG_TIMECODE)
152152 vbuf->timecode = b->timecode;
@@ -482,7 +482,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) · 329 unmodified lines
482482
483483 b->flags = vbuf->flags;
484484 b->field = vbuf->field;
485− b->timestamp = ns_to_timeval(vb->timestamp);
485+ v4l2_buffer_set_timestamp(b, vb->timestamp);
486486 b->timecode = vbuf->timecode;
487487 b->sequence = vbuf->sequence;
488488 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
12661266 buf->flags |= V4L2_BUF_FLAG_DONE;
12671267
12681268 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);
12701270 buf->sequence = meye.grab_buffer[index].sequence;
12711271 buf->memory = V4L2_MEMORY_MMAP;
12721272 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
13321332 buf->bytesused = meye.grab_buffer[reqnr].size;
13331333 buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
13341334 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);
13361336 buf->sequence = meye.grab_buffer[reqnr].sequence;
13371337 buf->memory = V4L2_MEMORY_MMAP;
13381338 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
800800 break;
801801 case FRAME_READY:
802802 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);
804804 buf->sequence = cam->buffers[buf->index].seq;
805805 buf->flags = V4L2_BUF_FLAG_DONE;
806806 break;
@@ -907,7 +907,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) · 100 unmodified lines
907907 buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE
908908 | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
909909 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);
911911 buf->sequence = cam->buffers[buf->index].seq;
912912 buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
913913 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
11251125 sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
11261126 sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
11271127 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());
11291129
11301130 *buf = sbuf->v4lbuf;
11311131 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
696696 vb->length = usbvision->curwidth *
697697 usbvision->curheight *
698698 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);
700700 vb->sequence = usbvision->frame[vb->index].sequence;
701701 return 0;
702702 }
@@ -765,7 +765,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *vb) · 62 unmodified lines
765765 V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
766766 vb->index = f->index;
767767 vb->sequence = f->sequence;
768− vb->timestamp = ns_to_timeval(f->ts);
768+ v4l2_buffer_set_timestamp(vb, f->ts);
769769 vb->field = V4L2_FIELD_NONE;
770770 vb->bytesused = f->scanlength;
771771
drivers/media/v4l2-core/videobuf-core.c+3−2
@@ -19,6 +19,7 @@ · 18 unmodified lines
1919 #include <linux/interrupt.h>
2020
2121 #include <media/videobuf-core.h>
22+#include <media/v4l2-common.h>
2223
2324 #define MAGIC_BUFFER 0x20070728
2425 #define MAGIC_CHECK(is, should) \
@@ -364,7 +365,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, · 339 unmodified lines
364365 }
365366
366367 b->field = vb->field;
367− b->timestamp = ns_to_timeval(vb->ts);
368+ v4l2_buffer_set_timestamp(b, vb->ts);
368369 b->bytesused = vb->size;
369370 b->sequence = vb->field_count >> 1;
370371 }
@@ -578,7 +579,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b) · 207 unmodified lines
578579 || q->type == V4L2_BUF_TYPE_SDR_OUTPUT) {
579580 buf->size = b->bytesused;
580581 buf->field = b->field;
581− buf->ts = v4l2_timeval_to_ns(&b->timestamp);
582+ buf->ts = v4l2_buffer_get_timestamp(b);
582583 }
583584 break;
584585 case V4L2_MEMORY_USERPTR:
include/media/v4l2-common.h+21−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #ifndef V4L2_COMMON_H_
1515 #define V4L2_COMMON_H_
1616
17+#include <linux/time.h>
1718 #include <media/v4l2-dev.h>
1819
1920 /* 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
518519 int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
519520 u32 width, u32 height);
520521
522+static 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+
533+static 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+
521542 #endif /* V4L2_COMMON_H_ */
include/trace/events/v4l2.h+1−1
@@ -130,7 +130,7 @@ DECLARE_EVENT_CLASS(v4l2_event_class, · 129 unmodified lines
130130 __entry->bytesused = buf->bytesused;
131131 __entry->flags = buf->flags;
132132 __entry->field = buf->field;
133− __entry->timestamp = timeval_to_ns(&buf->timestamp);
133+ __entry->timestamp = v4l2_buffer_get_timestamp(buf);
134134 __entry->timecode_type = buf->timecode.type;
135135 __entry->timecode_flags = buf->timecode.flags;
136136 __entry->timecode_frames = buf->timecode.frames;
include/uapi/linux/videodev2.h+2−0
@@ -1017,6 +1017,7 @@ struct v4l2_buffer { · 1016 unmodified lines
10171017 };
10181018 };
10191019
1020+#ifndef __KERNEL__
10201021 /**
10211022 * v4l2_timeval_to_ns - Convert timeval to nanoseconds
10221023 * @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
10281029 {
10291030 return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000;
10301031 }
1032+#endif
10311033
10321034 /* Flags for 'flags' field */
10331035 /* Buffer is mapped (flag) */