diff mbox series

media: vim2m: better handle cap/out buffers with different sizes

Message ID 013d728f6a252d6973d75d92017bdad7ddcff8f3.1551182030.git.mchehab+samsung@kernel.org (mailing list archive)
State New, archived
Headers show
Series media: vim2m: better handle cap/out buffers with different sizes | expand

Commit Message

Mauro Carvalho Chehab Feb. 26, 2019, 11:53 a.m. UTC
The vim2m driver doesn't enforce that the capture and output
buffers would have the same size. Do the right thing if the
buffers are different, zeroing the buffer before writing,
ensuring that lines will be aligned and it won't write past
the buffer area.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
 drivers/media/platform/vim2m.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index d95a905bdfc5..37f27082054d 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -469,7 +469,8 @@  static int device_process(struct vim2m_ctx *ctx,
 	struct vim2m_dev *dev = ctx->dev;
 	struct vim2m_q_data *q_data_in, *q_data_out;
 	u8 *p_in, *p, *p_out;
-	int width, height, bytesperline, x, y, y_out, start, end, step;
+	unsigned int width, height, bytesperline, x, y, y_out, imgsize;
+	int start, end, step;
 	struct vim2m_fmt *in, *out;
 
 	q_data_in = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
@@ -479,8 +480,16 @@  static int device_process(struct vim2m_ctx *ctx,
 	bytesperline = (q_data_in->width * q_data_in->fmt->depth) >> 3;
 
 	q_data_out = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	imgsize = (q_data_out->width * q_data_out->fmt->depth) >> 3;
+	imgsize *= q_data_out->height;
 	out = q_data_out->fmt;
 
+	/* Crop to the limits of the destination image */
+	if (width > q_data_out->width)
+		width = q_data_out->width;
+	if (height > q_data_out->height)
+		height = q_data_out->height;
+
 	p_in = vb2_plane_vaddr(&in_vb->vb2_buf, 0);
 	p_out = vb2_plane_vaddr(&out_vb->vb2_buf, 0);
 	if (!p_in || !p_out) {
@@ -489,6 +498,10 @@  static int device_process(struct vim2m_ctx *ctx,
 		return -EFAULT;
 	}
 
+	/* Image size is different. Zero buffer first */
+	if (q_data_in->width  != q_data_out->width ||
+	    q_data_in->height != q_data_out->height)
+		memset(p_out, 0, imgsize);
 	out_vb->sequence = get_q_data(ctx,
 				      V4L2_BUF_TYPE_VIDEO_CAPTURE)->sequence++;
 	in_vb->sequence = q_data_in->sequence++;
@@ -512,6 +525,11 @@  static int device_process(struct vim2m_ctx *ctx,
 		for (x = 0; x < width >> 1; x++)
 			copy_two_pixels(in, out, &p, &p_out, y_out,
 					ctx->mode & MEM2MEM_HFLIP);
+
+		/* Go to the next line at the out buffer*/
+		if (width < q_data_out->width)
+			p_out += ((q_data_out->width - width)
+				  * q_data_out->fmt->depth) >> 3;
 	}
 
 	return 0;