diff mbox series

[04/18] media: allegro: implement S_FMT for CAPTURE

Message ID 20201203110106.2939463-5-m.tretter@pengutronix.de (mailing list archive)
State New, archived
Headers show
Series media: allegro: add HEVC support | expand

Commit Message

Michael Tretter Dec. 3, 2020, 11 a.m. UTC
In order to support different codecs, the driver must support changing
the format on CAPTURE. Therefore, the driver needs to handle S_FMT on
CAPTURE.

As the driver will have a different number of formats for OUTPUT and
CAPTURE, split the check for the format index in ENUM_FMT into CAPTURE
and OUTPUT.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 .../media/platform/allegro-dvt/allegro-core.c | 23 ++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

Comments

Hans Verkuil Jan. 7, 2021, 11:55 a.m. UTC | #1
On 03/12/2020 12:00, Michael Tretter wrote:
> In order to support different codecs, the driver must support changing
> the format on CAPTURE. Therefore, the driver needs to handle S_FMT on
> CAPTURE.
> 
> As the driver will have a different number of formats for OUTPUT and
> CAPTURE, split the check for the format index in ENUM_FMT into CAPTURE
> and OUTPUT.
> 
> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
> ---
>  .../media/platform/allegro-dvt/allegro-core.c | 23 ++++++++++++++++---
>  1 file changed, 20 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c
> index 6b5cbee05040..a733049c8727 100644
> --- a/drivers/media/platform/allegro-dvt/allegro-core.c
> +++ b/drivers/media/platform/allegro-dvt/allegro-core.c
> @@ -2503,13 +2503,15 @@ static int allegro_querycap(struct file *file, void *fh,
>  static int allegro_enum_fmt_vid(struct file *file, void *fh,
>  				struct v4l2_fmtdesc *f)
>  {
> -	if (f->index)
> -		return -EINVAL;
>  	switch (f->type) {
>  	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
> +		if (f->index >= 1)
> +			return -EINVAL;
>  		f->pixelformat = V4L2_PIX_FMT_NV12;
>  		break;
>  	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
> +		if (f->index >= 1)
> +			return -EINVAL;
>  		f->pixelformat = V4L2_PIX_FMT_H264;
>  		break;
>  	default:
> @@ -2557,6 +2559,21 @@ static int allegro_try_fmt_vid_cap(struct file *file, void *fh,
>  	return 0;
>  }
>  
> +static int allegro_s_fmt_vid_cap(struct file *file, void *fh,
> +				 struct v4l2_format *f)
> +{
> +	struct allegro_channel *channel = fh_to_channel(fh);
> +	int err;
> +
> +	err = allegro_try_fmt_vid_cap(file, fh, f);
> +	if (err)
> +		return err;

This needs an additional check:

	struct v4l2_m2m_ctx *m2m_ctx = channel->fh.m2m_ctx;
	struct vb2_queue vq = v4l2_m2m_get_vq(m2m_ctx, f->type);
	if (vb2_is_busy(vq))
		return -EBUSY;

This wasn't necessary before since there was only one possible pixelformat,
but now there are two (H264 and HEVC), so you need to prevent switching
codec while the queue is busy.

Regards,

	Hans

> +
> +	channel->codec = f->fmt.pix.pixelformat;
> +
> +	return 0;
> +}
> +
>  static int allegro_g_fmt_vid_out(struct file *file, void *fh,
>  				 struct v4l2_format *f)
>  {
> @@ -2769,7 +2786,7 @@ static const struct v4l2_ioctl_ops allegro_ioctl_ops = {
>  	.vidioc_enum_fmt_vid_out = allegro_enum_fmt_vid,
>  	.vidioc_g_fmt_vid_cap = allegro_g_fmt_vid_cap,
>  	.vidioc_try_fmt_vid_cap = allegro_try_fmt_vid_cap,
> -	.vidioc_s_fmt_vid_cap = allegro_try_fmt_vid_cap,
> +	.vidioc_s_fmt_vid_cap = allegro_s_fmt_vid_cap,
>  	.vidioc_g_fmt_vid_out = allegro_g_fmt_vid_out,
>  	.vidioc_try_fmt_vid_out = allegro_try_fmt_vid_out,
>  	.vidioc_s_fmt_vid_out = allegro_s_fmt_vid_out,
>
diff mbox series

Patch

diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c
index 6b5cbee05040..a733049c8727 100644
--- a/drivers/media/platform/allegro-dvt/allegro-core.c
+++ b/drivers/media/platform/allegro-dvt/allegro-core.c
@@ -2503,13 +2503,15 @@  static int allegro_querycap(struct file *file, void *fh,
 static int allegro_enum_fmt_vid(struct file *file, void *fh,
 				struct v4l2_fmtdesc *f)
 {
-	if (f->index)
-		return -EINVAL;
 	switch (f->type) {
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		if (f->index >= 1)
+			return -EINVAL;
 		f->pixelformat = V4L2_PIX_FMT_NV12;
 		break;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (f->index >= 1)
+			return -EINVAL;
 		f->pixelformat = V4L2_PIX_FMT_H264;
 		break;
 	default:
@@ -2557,6 +2559,21 @@  static int allegro_try_fmt_vid_cap(struct file *file, void *fh,
 	return 0;
 }
 
+static int allegro_s_fmt_vid_cap(struct file *file, void *fh,
+				 struct v4l2_format *f)
+{
+	struct allegro_channel *channel = fh_to_channel(fh);
+	int err;
+
+	err = allegro_try_fmt_vid_cap(file, fh, f);
+	if (err)
+		return err;
+
+	channel->codec = f->fmt.pix.pixelformat;
+
+	return 0;
+}
+
 static int allegro_g_fmt_vid_out(struct file *file, void *fh,
 				 struct v4l2_format *f)
 {
@@ -2769,7 +2786,7 @@  static const struct v4l2_ioctl_ops allegro_ioctl_ops = {
 	.vidioc_enum_fmt_vid_out = allegro_enum_fmt_vid,
 	.vidioc_g_fmt_vid_cap = allegro_g_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap = allegro_try_fmt_vid_cap,
-	.vidioc_s_fmt_vid_cap = allegro_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = allegro_s_fmt_vid_cap,
 	.vidioc_g_fmt_vid_out = allegro_g_fmt_vid_out,
 	.vidioc_try_fmt_vid_out = allegro_try_fmt_vid_out,
 	.vidioc_s_fmt_vid_out = allegro_s_fmt_vid_out,