@@ -1296,10 +1296,10 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
d_buf->timecode = s_buf->timecode;
}
d_buf->sequence = ctx->sequence;
- d_buf->field = ctx->field;
d_q_data = &ctx->q_data[Q_DATA_DST];
if (d_q_data->flags & Q_DATA_INTERLACED) {
+ d_buf->field = ctx->field;
if (ctx->field == V4L2_FIELD_BOTTOM) {
ctx->sequence++;
ctx->field = V4L2_FIELD_TOP;
@@ -1308,6 +1308,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
ctx->field = V4L2_FIELD_BOTTOM;
}
} else {
+ d_buf->field = V4L2_FIELD_NONE;
ctx->sequence++;
}
@@ -1880,6 +1881,16 @@ static int vpe_buf_prepare(struct vb2_buffer *vb)
q_data = get_q_data(ctx, vb->vb2_queue->type);
num_planes = q_data->fmt->coplanar ? 2 : 1;
+ if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ if (!(q_data->flags & Q_DATA_INTERLACED)) {
+ vb->v4l2_buf.field = V4L2_FIELD_NONE;
+ } else {
+ if (vb->v4l2_buf.field != V4L2_FIELD_TOP &&
+ vb->v4l2_buf.field != V4L2_FIELD_BOTTOM)
+ return -EINVAL;
+ }
+ }
+
for (i = 0; i < num_planes; i++) {
if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
vpe_err(ctx->dev,
The vpe driver wasn't setting the correct field parameter for dequed CAPTURE type buffers for the case where the captured output is progressive. Set the field to V4L2_FIELD_NONE for the completed destination buffers when the captured output is progressive. For OUTPUT type buffers, a queued buffer's field is forced to V4L2_FIELD_NONE if the pixel format(configured through s_fmt for the buffer type V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE specifies) the field type isn't interlaced. If the pixel format specified was V4L2_FIELD_ALTERNATE, and the queued buffer's field isn't V4L2_FIELD_TOP or V4L2_FIELD_BOTTOM, the vb2 buf_prepare op returns an error. This ensures compliance, and that the dequeued output and captured buffers contain the field type that the driver used internally. Signed-off-by: Archit Taneja <archit@ti.com> --- drivers/media/platform/ti-vpe/vpe.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)