|
@@ -40,10 +40,14 @@ module_param(debug, int, 0644);
|
|
|
#define call_qop(q, op, args...) \
|
|
|
(((q)->ops->op) ? ((q)->ops->op(args)) : 0)
|
|
|
|
|
|
+/* Flags that are set by the vb2 core */
|
|
|
#define V4L2_BUFFER_MASK_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
|
|
|
V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
|
|
|
V4L2_BUF_FLAG_PREPARED | \
|
|
|
V4L2_BUF_FLAG_TIMESTAMP_MASK)
|
|
|
+/* Output buffer flags that should be passed on to the driver */
|
|
|
+#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \
|
|
|
+ V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE)
|
|
|
|
|
|
/**
|
|
|
* __vb2_buf_mem_alloc() - allocate video memory for the given buffer
|
|
@@ -1025,9 +1029,21 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
|
|
|
|
|
|
}
|
|
|
|
|
|
- vb->v4l2_buf.field = b->field;
|
|
|
- vb->v4l2_buf.timestamp = b->timestamp;
|
|
|
+ /* Zero flags that the vb2 core handles */
|
|
|
vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_MASK_FLAGS;
|
|
|
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
|
|
|
+ /*
|
|
|
+ * For output buffers mask out the timecode flag:
|
|
|
+ * this will be handled later in vb2_internal_qbuf().
|
|
|
+ * The 'field' is valid metadata for this output buffer
|
|
|
+ * and so that needs to be copied here.
|
|
|
+ */
|
|
|
+ vb->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMECODE;
|
|
|
+ vb->v4l2_buf.field = b->field;
|
|
|
+ } else {
|
|
|
+ /* Zero any output buffer flags as this is a capture buffer */
|
|
|
+ vb->v4l2_buf.flags &= ~V4L2_BUFFER_OUT_FLAGS;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1261,6 +1277,10 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
|
|
|
}
|
|
|
|
|
|
vb->state = VB2_BUF_STATE_PREPARING;
|
|
|
+ vb->v4l2_buf.timestamp.tv_sec = 0;
|
|
|
+ vb->v4l2_buf.timestamp.tv_usec = 0;
|
|
|
+ vb->v4l2_buf.sequence = 0;
|
|
|
+
|
|
|
switch (q->memory) {
|
|
|
case V4L2_MEMORY_MMAP:
|
|
|
ret = __qbuf_mmap(vb, b);
|
|
@@ -1448,6 +1468,17 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
|
|
|
*/
|
|
|
list_add_tail(&vb->queued_entry, &q->queued_list);
|
|
|
vb->state = VB2_BUF_STATE_QUEUED;
|
|
|
+ if (V4L2_TYPE_IS_OUTPUT(q->type)) {
|
|
|
+ /*
|
|
|
+ * For output buffers copy the timestamp if needed,
|
|
|
+ * and the timecode field and flag if needed.
|
|
|
+ */
|
|
|
+ if (q->timestamp_type == V4L2_BUF_FLAG_TIMESTAMP_COPY)
|
|
|
+ vb->v4l2_buf.timestamp = b->timestamp;
|
|
|
+ vb->v4l2_buf.flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
|
|
|
+ if (b->flags & V4L2_BUF_FLAG_TIMECODE)
|
|
|
+ vb->v4l2_buf.timecode = b->timecode;
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* If already streaming, give the buffer to driver for processing.
|