All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
To: Linux Media Mailing List <linux-media@vger.kernel.org>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>,
	Hans Verkuil <hverkuil-cisco@xs4all.nl>,
	Ezequiel Garcia <ezequiel@collabora.com>
Subject: Re: [PATCH v3] media: vim2m: better handle cap/out buffers with different sizes
Date: Thu, 28 Feb 2019 15:02:28 -0300	[thread overview]
Message-ID: <20190228150228.6b6fdcc4@coco.lan> (raw)
In-Reply-To: <2636657c4de4fcd32ab41a50c7b70445345c8561.1551376758.git.mchehab+samsung@kernel.org>

Em Thu, 28 Feb 2019 14:59:21 -0300
Mauro Carvalho Chehab <mchehab+samsung@kernel.org> escreveu:

> 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.
> 
> This is a temporary fix.

Please ignore this. Forgot to change one line (the one with a
comment).

Sending version 4.

> 
> A proper fix is to either implement a simple scaler at vim2m,
> or to better define the behaviour of M2M transform drivers
> at V4L2 API with regards to its capability of scaling the
> image or not.
> 
> In any case, such changes would deserve a separate patch
> anyway, as it would imply on some behavoral change.
> 
> Also, as we have an actual bug of writing data at wrong
> places, let's fix this here, and add a mental note that
> we need to properly address it.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
> ---
>  drivers/media/platform/vim2m.c | 117 +++++++++++++++++++++++----------
>  1 file changed, 81 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
> index 5157a59aeb58..1c55c47b151a 100644
> --- a/drivers/media/platform/vim2m.c
> +++ b/drivers/media/platform/vim2m.c
> @@ -267,46 +267,66 @@ static const char *type_name(enum v4l2_buf_type type)
>  #define CLIP(__color) \
>  	(u8)(((__color) > 0xff) ? 0xff : (((__color) < 0) ? 0 : (__color)))
>  
> -static void copy_two_pixels(struct vim2m_fmt *in, struct vim2m_fmt *out,
> +static int fast_copy_two_pixels(struct vim2m_q_data *q_data_in,
> +				 struct vim2m_q_data *q_data_out,
> +				 u8 **src, u8 **dst, int ypos, bool reverse)
> +{
> +	int depth = q_data_out->fmt->depth >> 3;
> +
> +	/* Only do fast copy when format and resolution are identical */
> +	if (q_data_in->fmt->fourcc != q_data_out->fmt->fourcc ||
> +	    q_data_in->width != q_data_out->width ||
> +	    q_data_in->height != q_data_out->height)
> +		return 0;
> +
> +	if (!reverse) {
> +		memcpy(*dst, *src, depth << 1);
> +		*src += depth << 1;
> +		*dst += depth << 1;
> +		return 1;
> +	}
> +
> +	/* Copy line at reverse order - YUYV format */
> +	if (q_data_in->fmt->fourcc == V4L2_PIX_FMT_YUYV) {
> +		int u, v, y, y1;
> +
> +		*src -= 2;
> +
> +		y1 = (*src)[0]; /* copy as second point */
> +		u  = (*src)[1];
> +		y  = (*src)[2]; /* copy as first point */
> +		v  = (*src)[3];
> +
> +		*src -= 2;
> +
> +		*(*dst)++ = y;
> +		*(*dst)++ = u;
> +		*(*dst)++ = y1;
> +		*(*dst)++ = v;
> +		return 1;
> +	}
> +
> +	/* copy RGB formats in reverse order */
> +	memcpy(*dst, *src, depth);
> +	memcpy(*dst + depth, *src - depth, depth);
> +	*src -= depth << 1;
> +	*dst += depth << 1;
> +	return 1;
> +}
> +
> +static void copy_two_pixels(struct vim2m_q_data *q_data_in,
> +			    struct vim2m_q_data *q_data_out,
>  			    u8 **src, u8 **dst, int ypos, bool reverse)
>  {
> +	struct vim2m_fmt *out = q_data_out->fmt;
> +	struct vim2m_fmt *in = q_data_in->fmt;
>  	u8 _r[2], _g[2], _b[2], *r, *g, *b;
>  	int i, step;
>  
>  	// If format is the same just copy the data, respecting the width
> -	if (in->fourcc == out->fourcc) {
> -		int depth = out->depth >> 3;
> -
> -		if (reverse) {
> -			if (in->fourcc == V4L2_PIX_FMT_YUYV) {
> -				int u, v, y, y1;
> -
> -				*src -= 2;
> -
> -				y1 = (*src)[0]; /* copy as second point */
> -				u  = (*src)[1];
> -				y  = (*src)[2]; /* copy as first point */
> -				v  = (*src)[3];
> -
> -				*src -= 2;
> -
> -				*(*dst)++ = y;
> -				*(*dst)++ = u;
> -				*(*dst)++ = y1;
> -				*(*dst)++ = v;
> -				return;
> -			}
> -
> -			memcpy(*dst, *src, depth);
> -			memcpy(*dst + depth, *src - depth, depth);
> -			*src -= depth << 1;
> -		} else {
> -			memcpy(*dst, *src, depth << 1);
> -			*src += depth << 1;
> -		}
> -		*dst += depth << 1;
> -		return;
> -	}
> +	if (fast_copy_two_pixels(q_data_in, q_data_out,
> +				 src, dst, ypos, reverse))
> +	  return;
>  
>  	/* Step 1: read two consecutive pixels from src pointer */
>  
> @@ -506,7 +526,9 @@ 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, bytesperline_out;
> +	unsigned int x, y, y_out;
> +	int start, end, step;
>  	struct vim2m_fmt *in, *out;
>  
>  	q_data_in = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
> @@ -516,8 +538,15 @@ 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);
> +	bytesperline_out = (q_data_out->width * q_data_out->fmt->depth) >> 3;
>  	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) {
> @@ -526,6 +555,17 @@ static int device_process(struct vim2m_ctx *ctx,
>  		return -EFAULT;
>  	}
>  
> +	/*
> +	 * FIXME: instead of cropping the image and zeroing any
> +	 * extra data, the proper behavior is to either scale the
> +	 * data or report that scale is not supported (with depends
> +	 * on some API for such purpose).
> +	 */
> +
> +	/* 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, q_data_out->sizeimage);
>  	out_vb->sequence = get_q_data(ctx,
>  				      V4L2_BUF_TYPE_VIDEO_CAPTURE)->sequence++;
>  	in_vb->sequence = q_data_in->sequence++;
> @@ -547,8 +587,13 @@ static int device_process(struct vim2m_ctx *ctx,
>  			p += bytesperline - (q_data_in->fmt->depth >> 3);
>  
>  		for (x = 0; x < width >> 1; x++)
> -			copy_two_pixels(in, out, &p, &p_out, y_out,
> +			copy_two_pixels(q_data_in, q_data_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;



Thanks,
Mauro

      reply	other threads:[~2019-02-28 18:02 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-28 17:59 [PATCH v3] media: vim2m: better handle cap/out buffers with different sizes Mauro Carvalho Chehab
2019-02-28 18:02 ` Mauro Carvalho Chehab [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190228150228.6b6fdcc4@coco.lan \
    --to=mchehab+samsung@kernel.org \
    --cc=ezequiel@collabora.com \
    --cc=hverkuil-cisco@xs4all.nl \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.