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. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> [hverkuil-cisco@xs4all.nl: replace spaces by tabs] Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
parent
71e37d2e4b
commit
77cdffcb0b
|
@ -146,7 +146,7 @@ static void __copy_timestamp(struct vb2_buffer *vb, const void *pb)
|
||||||
* and the timecode field and flag if needed.
|
* and the timecode field and flag if needed.
|
||||||
*/
|
*/
|
||||||
if (q->copy_timestamp)
|
if (q->copy_timestamp)
|
||||||
vb->timestamp = v4l2_timeval_to_ns(&b->timestamp);
|
vb->timestamp = v4l2_buffer_get_timestamp(b);
|
||||||
vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
|
vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
|
||||||
if (b->flags & V4L2_BUF_FLAG_TIMECODE)
|
if (b->flags & V4L2_BUF_FLAG_TIMECODE)
|
||||||
vbuf->timecode = b->timecode;
|
vbuf->timecode = b->timecode;
|
||||||
|
@ -482,7 +482,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
|
||||||
|
|
||||||
b->flags = vbuf->flags;
|
b->flags = vbuf->flags;
|
||||||
b->field = vbuf->field;
|
b->field = vbuf->field;
|
||||||
b->timestamp = ns_to_timeval(vb->timestamp);
|
v4l2_buffer_set_timestamp(b, vb->timestamp);
|
||||||
b->timecode = vbuf->timecode;
|
b->timecode = vbuf->timecode;
|
||||||
b->sequence = vbuf->sequence;
|
b->sequence = vbuf->sequence;
|
||||||
b->reserved2 = 0;
|
b->reserved2 = 0;
|
||||||
|
|
|
@ -1266,7 +1266,7 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||||
buf->flags |= V4L2_BUF_FLAG_DONE;
|
buf->flags |= V4L2_BUF_FLAG_DONE;
|
||||||
|
|
||||||
buf->field = V4L2_FIELD_NONE;
|
buf->field = V4L2_FIELD_NONE;
|
||||||
buf->timestamp = ns_to_timeval(meye.grab_buffer[index].ts);
|
v4l2_buffer_set_timestamp(buf, meye.grab_buffer[index].ts);
|
||||||
buf->sequence = meye.grab_buffer[index].sequence;
|
buf->sequence = meye.grab_buffer[index].sequence;
|
||||||
buf->memory = V4L2_MEMORY_MMAP;
|
buf->memory = V4L2_MEMORY_MMAP;
|
||||||
buf->m.offset = index * gbufsize;
|
buf->m.offset = index * gbufsize;
|
||||||
|
@ -1332,7 +1332,7 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||||
buf->bytesused = meye.grab_buffer[reqnr].size;
|
buf->bytesused = meye.grab_buffer[reqnr].size;
|
||||||
buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||||||
buf->field = V4L2_FIELD_NONE;
|
buf->field = V4L2_FIELD_NONE;
|
||||||
buf->timestamp = ns_to_timeval(meye.grab_buffer[reqnr].ts);
|
v4l2_buffer_set_timestamp(buf, meye.grab_buffer[reqnr].ts);
|
||||||
buf->sequence = meye.grab_buffer[reqnr].sequence;
|
buf->sequence = meye.grab_buffer[reqnr].sequence;
|
||||||
buf->memory = V4L2_MEMORY_MMAP;
|
buf->memory = V4L2_MEMORY_MMAP;
|
||||||
buf->m.offset = reqnr * gbufsize;
|
buf->m.offset = reqnr * gbufsize;
|
||||||
|
|
|
@ -800,7 +800,7 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||||
break;
|
break;
|
||||||
case FRAME_READY:
|
case FRAME_READY:
|
||||||
buf->bytesused = cam->buffers[buf->index].length;
|
buf->bytesused = cam->buffers[buf->index].length;
|
||||||
buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts);
|
v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts);
|
||||||
buf->sequence = cam->buffers[buf->index].seq;
|
buf->sequence = cam->buffers[buf->index].seq;
|
||||||
buf->flags = V4L2_BUF_FLAG_DONE;
|
buf->flags = V4L2_BUF_FLAG_DONE;
|
||||||
break;
|
break;
|
||||||
|
@ -907,7 +907,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||||
buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE
|
buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE
|
||||||
| V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
| V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||||||
buf->field = V4L2_FIELD_NONE;
|
buf->field = V4L2_FIELD_NONE;
|
||||||
buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts);
|
v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts);
|
||||||
buf->sequence = cam->buffers[buf->index].seq;
|
buf->sequence = cam->buffers[buf->index].seq;
|
||||||
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
|
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
|
||||||
buf->length = cam->frame_size;
|
buf->length = cam->frame_size;
|
||||||
|
|
|
@ -1125,7 +1125,7 @@ static int stk_vidioc_dqbuf(struct file *filp,
|
||||||
sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
|
sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
|
||||||
sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
|
sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
|
||||||
sbuf->v4lbuf.sequence = ++dev->sequence;
|
sbuf->v4lbuf.sequence = ++dev->sequence;
|
||||||
sbuf->v4lbuf.timestamp = ns_to_timeval(ktime_get_ns());
|
v4l2_buffer_set_timestamp(&sbuf->v4lbuf, ktime_get_ns());
|
||||||
|
|
||||||
*buf = sbuf->v4lbuf;
|
*buf = sbuf->v4lbuf;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -696,7 +696,7 @@ static int vidioc_querybuf(struct file *file,
|
||||||
vb->length = usbvision->curwidth *
|
vb->length = usbvision->curwidth *
|
||||||
usbvision->curheight *
|
usbvision->curheight *
|
||||||
usbvision->palette.bytes_per_pixel;
|
usbvision->palette.bytes_per_pixel;
|
||||||
vb->timestamp = ns_to_timeval(usbvision->frame[vb->index].ts);
|
v4l2_buffer_set_timestamp(vb, usbvision->frame[vb->index].ts);
|
||||||
vb->sequence = usbvision->frame[vb->index].sequence;
|
vb->sequence = usbvision->frame[vb->index].sequence;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -765,7 +765,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *vb)
|
||||||
V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||||||
vb->index = f->index;
|
vb->index = f->index;
|
||||||
vb->sequence = f->sequence;
|
vb->sequence = f->sequence;
|
||||||
vb->timestamp = ns_to_timeval(f->ts);
|
v4l2_buffer_set_timestamp(vb, f->ts);
|
||||||
vb->field = V4L2_FIELD_NONE;
|
vb->field = V4L2_FIELD_NONE;
|
||||||
vb->bytesused = f->scanlength;
|
vb->bytesused = f->scanlength;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
#include <media/videobuf-core.h>
|
#include <media/videobuf-core.h>
|
||||||
|
#include <media/v4l2-common.h>
|
||||||
|
|
||||||
#define MAGIC_BUFFER 0x20070728
|
#define MAGIC_BUFFER 0x20070728
|
||||||
#define MAGIC_CHECK(is, should) \
|
#define MAGIC_CHECK(is, should) \
|
||||||
|
@ -364,7 +365,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
|
||||||
}
|
}
|
||||||
|
|
||||||
b->field = vb->field;
|
b->field = vb->field;
|
||||||
b->timestamp = ns_to_timeval(vb->ts);
|
v4l2_buffer_set_timestamp(b, vb->ts);
|
||||||
b->bytesused = vb->size;
|
b->bytesused = vb->size;
|
||||||
b->sequence = vb->field_count >> 1;
|
b->sequence = vb->field_count >> 1;
|
||||||
}
|
}
|
||||||
|
@ -578,7 +579,7 @@ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b)
|
||||||
|| q->type == V4L2_BUF_TYPE_SDR_OUTPUT) {
|
|| q->type == V4L2_BUF_TYPE_SDR_OUTPUT) {
|
||||||
buf->size = b->bytesused;
|
buf->size = b->bytesused;
|
||||||
buf->field = b->field;
|
buf->field = b->field;
|
||||||
buf->ts = v4l2_timeval_to_ns(&b->timestamp);
|
buf->ts = v4l2_buffer_get_timestamp(b);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case V4L2_MEMORY_USERPTR:
|
case V4L2_MEMORY_USERPTR:
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#ifndef V4L2_COMMON_H_
|
#ifndef V4L2_COMMON_H_
|
||||||
#define V4L2_COMMON_H_
|
#define V4L2_COMMON_H_
|
||||||
|
|
||||||
|
#include <linux/time.h>
|
||||||
#include <media/v4l2-dev.h>
|
#include <media/v4l2-dev.h>
|
||||||
|
|
||||||
/* Common printk constructs for v4l-i2c drivers. These macros create a unique
|
/* 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,
|
||||||
int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
|
int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat,
|
||||||
u32 width, u32 height);
|
u32 width, u32 height);
|
||||||
|
|
||||||
|
static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* When the timestamp comes from 32-bit user space, there may be
|
||||||
|
* uninitialized data in tv_usec, so cast it to u32.
|
||||||
|
* Otherwise allow invalid input for backwards compatibility.
|
||||||
|
*/
|
||||||
|
return buf->timestamp.tv_sec * NSEC_PER_SEC +
|
||||||
|
(u32)buf->timestamp.tv_usec * NSEC_PER_USEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void v4l2_buffer_set_timestamp(struct v4l2_buffer *buf,
|
||||||
|
u64 timestamp)
|
||||||
|
{
|
||||||
|
struct timespec64 ts = ns_to_timespec64(timestamp);
|
||||||
|
|
||||||
|
buf->timestamp.tv_sec = ts.tv_sec;
|
||||||
|
buf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* V4L2_COMMON_H_ */
|
#endif /* V4L2_COMMON_H_ */
|
||||||
|
|
|
@ -130,7 +130,7 @@ DECLARE_EVENT_CLASS(v4l2_event_class,
|
||||||
__entry->bytesused = buf->bytesused;
|
__entry->bytesused = buf->bytesused;
|
||||||
__entry->flags = buf->flags;
|
__entry->flags = buf->flags;
|
||||||
__entry->field = buf->field;
|
__entry->field = buf->field;
|
||||||
__entry->timestamp = timeval_to_ns(&buf->timestamp);
|
__entry->timestamp = v4l2_buffer_get_timestamp(buf);
|
||||||
__entry->timecode_type = buf->timecode.type;
|
__entry->timecode_type = buf->timecode.type;
|
||||||
__entry->timecode_flags = buf->timecode.flags;
|
__entry->timecode_flags = buf->timecode.flags;
|
||||||
__entry->timecode_frames = buf->timecode.frames;
|
__entry->timecode_frames = buf->timecode.frames;
|
||||||
|
|
|
@ -1017,6 +1017,7 @@ struct v4l2_buffer {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef __KERNEL__
|
||||||
/**
|
/**
|
||||||
* v4l2_timeval_to_ns - Convert timeval to nanoseconds
|
* v4l2_timeval_to_ns - Convert timeval to nanoseconds
|
||||||
* @ts: pointer to the timeval variable to be converted
|
* @ts: pointer to the timeval variable to be converted
|
||||||
|
@ -1028,6 +1029,7 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv)
|
||||||
{
|
{
|
||||||
return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000;
|
return (__u64)tv->tv_sec * 1000000000ULL + tv->tv_usec * 1000;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Flags for 'flags' field */
|
/* Flags for 'flags' field */
|
||||||
/* Buffer is mapped (flag) */
|
/* Buffer is mapped (flag) */
|
||||||
|
|
Loading…
Reference in New Issue