diff mbox series

[v3,09/10] media: rkisp1: cap: simplify the link validation by compering the media bus code

Message ID 20200723132014.4597-10-dafna.hirschfeld@collabora.com (mailing list archive)
State New, archived
Headers show
Series media: staging: rkisp1: add support to V4L2_CAP_IO_MC | expand

Commit Message

Dafna Hirschfeld July 23, 2020, 1:20 p.m. UTC
The capture has a mapping of the mbus code needed for each pixelformat.
This can be used to simplify the link validation by comparing the mbus
code in the capture with the code in the resizer.

Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
---
 drivers/staging/media/rkisp1/rkisp1-capture.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

Comments

Niklas Söderlund Sept. 30, 2020, 7 p.m. UTC | #1
Hi Dafna,

This commit is not just a simplification but a change of behavior.  The 
change is for the better but it broke capture of NV12 and NV21 formats 
in libcamera unexpectedly.

The issue at hand is that libcamera when configuring the pipeline 
retrieves the mbus code for the ISP (rkisp1_isp) source pad (2) and then 
propagates it to the resizer (rkisp_resizer_{main,self}path) sink pad 
(0) and then to the resizers source pad (1). Effectively propagating 
MEDIA_BUS_FMT_YUYV8_2X8 for all formats.

At this point if the video node (main or self) is configured with a 
YUV420 format (NV12, NV21, etc) and with this change applied the link 
validation will fail as MEDIA_BUS_FMT_YUYV8_1_5X8 !=  
MEDIA_BUS_FMT_YUYV8_2X8. Given the nature of how link validation is 
implemented it's VIDIOC_QBUF that returns a -EPIPE when it fails and 
libcamera lockup the capture session.

I will submit a fix for this to libcamera to bring it in sync with this 
change.

Would it be possible to ask that future changes to the rkisp1 driver be 
tested with libcamera so we can track and update both the kernel and 
user-space components of this driver at the same time and avoid nasty 
surprises? :-)

On 2020-07-23 15:20:13 +0200, Dafna Hirschfeld wrote:
> The capture has a mapping of the mbus code needed for each pixelformat.
> This can be used to simplify the link validation by comparing the mbus
> code in the capture with the code in the resizer.
> 
> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
> ---
>  drivers/staging/media/rkisp1/rkisp1-capture.c | 18 ++++--------------
>  1 file changed, 4 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
> index 4dabd07a3da9..a5e2521577dd 100644
> --- a/drivers/staging/media/rkisp1/rkisp1-capture.c
> +++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
> @@ -1255,22 +1255,11 @@ static int rkisp1_capture_link_validate(struct media_link *link)
>  	struct v4l2_subdev *sd =
>  		media_entity_to_v4l2_subdev(link->source->entity);
>  	struct rkisp1_capture *cap = video_get_drvdata(vdev);
> -	struct rkisp1_isp *isp = &cap->rkisp1->isp;
> -	u8 isp_pix_enc = isp->src_fmt->pixel_enc;
> -	u8 cap_pix_enc = cap->pix.info->pixel_enc;
> +	const struct rkisp1_capture_fmt_cfg *fmt =
> +		rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
>  	struct v4l2_subdev_format sd_fmt;
>  	int ret;
>  
> -	if (cap_pix_enc != isp_pix_enc &&
> -	    !(isp_pix_enc == V4L2_PIXEL_ENC_YUV &&
> -	      cap_pix_enc == V4L2_PIXEL_ENC_RGB)) {
> -		dev_err(cap->rkisp1->dev,
> -			"format type mismatch in link '%s:%d->%s:%d'\n",
> -			link->source->entity->name, link->source->index,
> -			link->sink->entity->name, link->sink->index);
> -		return -EPIPE;
> -	}
> -
>  	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
>  	sd_fmt.pad = link->source->index;
>  	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
> @@ -1278,7 +1267,8 @@ static int rkisp1_capture_link_validate(struct media_link *link)
>  		return ret;
>  
>  	if (sd_fmt.format.height != cap->pix.fmt.height ||
> -	    sd_fmt.format.width != cap->pix.fmt.width)
> +	    sd_fmt.format.width != cap->pix.fmt.width ||
> +	    sd_fmt.format.code != fmt->mbus)
>  		return -EPIPE;
>  
>  	return 0;
> -- 
> 2.17.1
>
Laurent Pinchart Oct. 1, 2020, 2:03 a.m. UTC | #2
Hello,

On Wed, Sep 30, 2020 at 09:00:25PM +0200, Niklas Söderlund wrote:
> Hi Dafna,
> 
> This commit is not just a simplification but a change of behavior.  The 
> change is for the better but it broke capture of NV12 and NV21 formats 
> in libcamera unexpectedly.
> 
> The issue at hand is that libcamera when configuring the pipeline 
> retrieves the mbus code for the ISP (rkisp1_isp) source pad (2) and then 
> propagates it to the resizer (rkisp_resizer_{main,self}path) sink pad 
> (0) and then to the resizers source pad (1). Effectively propagating 
> MEDIA_BUS_FMT_YUYV8_2X8 for all formats.
> 
> At this point if the video node (main or self) is configured with a 
> YUV420 format (NV12, NV21, etc) and with this change applied the link 
> validation will fail as MEDIA_BUS_FMT_YUYV8_1_5X8 !=  
> MEDIA_BUS_FMT_YUYV8_2X8. Given the nature of how link validation is 
> implemented it's VIDIOC_QBUF that returns a -EPIPE when it fails and 
> libcamera lockup the capture session.

I would be very, very surprised is the hardware really used YUYV8_1_5X8.
YUYV8_1X16 is a much more likely bus format between the resizer and the
DMA engine, as well as between the ISP and the resizer.

> I will submit a fix for this to libcamera to bring it in sync with this 
> change.
> 
> Would it be possible to ask that future changes to the rkisp1 driver be 
> tested with libcamera so we can track and update both the kernel and 
> user-space components of this driver at the same time and avoid nasty 
> surprises? :-)

I strongly second this. Drivers that are supported in libcamera should
be tested with libcamera to catch regressions, for any chance submitted
to the kernel.

> On 2020-07-23 15:20:13 +0200, Dafna Hirschfeld wrote:
> > The capture has a mapping of the mbus code needed for each pixelformat.
> > This can be used to simplify the link validation by comparing the mbus
> > code in the capture with the code in the resizer.
> > 
> > Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
> > ---
> >  drivers/staging/media/rkisp1/rkisp1-capture.c | 18 ++++--------------
> >  1 file changed, 4 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
> > index 4dabd07a3da9..a5e2521577dd 100644
> > --- a/drivers/staging/media/rkisp1/rkisp1-capture.c
> > +++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
> > @@ -1255,22 +1255,11 @@ static int rkisp1_capture_link_validate(struct media_link *link)
> >  	struct v4l2_subdev *sd =
> >  		media_entity_to_v4l2_subdev(link->source->entity);
> >  	struct rkisp1_capture *cap = video_get_drvdata(vdev);
> > -	struct rkisp1_isp *isp = &cap->rkisp1->isp;
> > -	u8 isp_pix_enc = isp->src_fmt->pixel_enc;
> > -	u8 cap_pix_enc = cap->pix.info->pixel_enc;
> > +	const struct rkisp1_capture_fmt_cfg *fmt =
> > +		rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
> >  	struct v4l2_subdev_format sd_fmt;
> >  	int ret;
> >  
> > -	if (cap_pix_enc != isp_pix_enc &&
> > -	    !(isp_pix_enc == V4L2_PIXEL_ENC_YUV &&
> > -	      cap_pix_enc == V4L2_PIXEL_ENC_RGB)) {
> > -		dev_err(cap->rkisp1->dev,
> > -			"format type mismatch in link '%s:%d->%s:%d'\n",
> > -			link->source->entity->name, link->source->index,
> > -			link->sink->entity->name, link->sink->index);
> > -		return -EPIPE;
> > -	}
> > -
> >  	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> >  	sd_fmt.pad = link->source->index;
> >  	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
> > @@ -1278,7 +1267,8 @@ static int rkisp1_capture_link_validate(struct media_link *link)
> >  		return ret;
> >  
> >  	if (sd_fmt.format.height != cap->pix.fmt.height ||
> > -	    sd_fmt.format.width != cap->pix.fmt.width)
> > +	    sd_fmt.format.width != cap->pix.fmt.width ||
> > +	    sd_fmt.format.code != fmt->mbus)
> >  		return -EPIPE;
> >  
> >  	return 0;
Dafna Hirschfeld Oct. 1, 2020, 7:36 p.m. UTC | #3
Am 01.10.20 um 04:03 schrieb Laurent Pinchart:
> Hello,
> 
> On Wed, Sep 30, 2020 at 09:00:25PM +0200, Niklas Söderlund wrote:
>> Hi Dafna,
>>
>> This commit is not just a simplification but a change of behavior.  The
>> change is for the better but it broke capture of NV12 and NV21 formats
>> in libcamera unexpectedly.
>>
>> The issue at hand is that libcamera when configuring the pipeline
>> retrieves the mbus code for the ISP (rkisp1_isp) source pad (2) and then
>> propagates it to the resizer (rkisp_resizer_{main,self}path) sink pad
>> (0) and then to the resizers source pad (1). Effectively propagating
>> MEDIA_BUS_FMT_YUYV8_2X8 for all formats.
>>
>> At this point if the video node (main or self) is configured with a
>> YUV420 format (NV12, NV21, etc) and with this change applied the link
>> validation will fail as MEDIA_BUS_FMT_YUYV8_1_5X8 !=
>> MEDIA_BUS_FMT_YUYV8_2X8. Given the nature of how link validation is
>> implemented it's VIDIOC_QBUF that returns a -EPIPE when it fails and
>> libcamera lockup the capture session.
> 
> I would be very, very surprised is the hardware really used YUYV8_1_5X8.
> YUYV8_1X16 is a much more likely bus format between the resizer and the
> DMA engine, as well as between the ISP and the resizer.

Format YUYV8_1X16 is for downsampling of 4:2:2, but the resizer has the ability
to downsample to 4:2:0.
I see there is also format YDYUYDYV8_1X16 for 4:2:0
maybe this is what I should set?

Actually according to the TRM the resizer send the stream to the DMA
engine through two separated buses, one for luma and one for chroma.

> 
>> I will submit a fix for this to libcamera to bring it in sync with this
>> change.
>>
>> Would it be possible to ask that future changes to the rkisp1 driver be
>> tested with libcamera so we can track and update both the kernel and
>> user-space components of this driver at the same time and avoid nasty
>> surprises? :-)
> 
> I strongly second this. Drivers that are supported in libcamera should
> be tested with libcamera to catch regressions, for any chance submitted
> to the kernel.

I can run several 'cam' commands with different formats and dimensions to
find regressions. I currently have unit test only in v4l-utils.

Thanks,
Dafna

> 
>> On 2020-07-23 15:20:13 +0200, Dafna Hirschfeld wrote:
>>> The capture has a mapping of the mbus code needed for each pixelformat.
>>> This can be used to simplify the link validation by comparing the mbus
>>> code in the capture with the code in the resizer.
>>>
>>> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
>>> ---
>>>   drivers/staging/media/rkisp1/rkisp1-capture.c | 18 ++++--------------
>>>   1 file changed, 4 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
>>> index 4dabd07a3da9..a5e2521577dd 100644
>>> --- a/drivers/staging/media/rkisp1/rkisp1-capture.c
>>> +++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
>>> @@ -1255,22 +1255,11 @@ static int rkisp1_capture_link_validate(struct media_link *link)
>>>   	struct v4l2_subdev *sd =
>>>   		media_entity_to_v4l2_subdev(link->source->entity);
>>>   	struct rkisp1_capture *cap = video_get_drvdata(vdev);
>>> -	struct rkisp1_isp *isp = &cap->rkisp1->isp;
>>> -	u8 isp_pix_enc = isp->src_fmt->pixel_enc;
>>> -	u8 cap_pix_enc = cap->pix.info->pixel_enc;
>>> +	const struct rkisp1_capture_fmt_cfg *fmt =
>>> +		rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
>>>   	struct v4l2_subdev_format sd_fmt;
>>>   	int ret;
>>>   
>>> -	if (cap_pix_enc != isp_pix_enc &&
>>> -	    !(isp_pix_enc == V4L2_PIXEL_ENC_YUV &&
>>> -	      cap_pix_enc == V4L2_PIXEL_ENC_RGB)) {
>>> -		dev_err(cap->rkisp1->dev,
>>> -			"format type mismatch in link '%s:%d->%s:%d'\n",
>>> -			link->source->entity->name, link->source->index,
>>> -			link->sink->entity->name, link->sink->index);
>>> -		return -EPIPE;
>>> -	}
>>> -
>>>   	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
>>>   	sd_fmt.pad = link->source->index;
>>>   	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
>>> @@ -1278,7 +1267,8 @@ static int rkisp1_capture_link_validate(struct media_link *link)
>>>   		return ret;
>>>   
>>>   	if (sd_fmt.format.height != cap->pix.fmt.height ||
>>> -	    sd_fmt.format.width != cap->pix.fmt.width)
>>> +	    sd_fmt.format.width != cap->pix.fmt.width ||
>>> +	    sd_fmt.format.code != fmt->mbus)
>>>   		return -EPIPE;
>>>   
>>>   	return 0;
>
Laurent Pinchart Oct. 1, 2020, 10:48 p.m. UTC | #4
Hi Dafna,

On Thu, Oct 01, 2020 at 09:36:07PM +0200, Dafna Hirschfeld wrote:
> Am 01.10.20 um 04:03 schrieb Laurent Pinchart:
> > On Wed, Sep 30, 2020 at 09:00:25PM +0200, Niklas Söderlund wrote:
> >> Hi Dafna,
> >>
> >> This commit is not just a simplification but a change of behavior.  The
> >> change is for the better but it broke capture of NV12 and NV21 formats
> >> in libcamera unexpectedly.
> >>
> >> The issue at hand is that libcamera when configuring the pipeline
> >> retrieves the mbus code for the ISP (rkisp1_isp) source pad (2) and then
> >> propagates it to the resizer (rkisp_resizer_{main,self}path) sink pad
> >> (0) and then to the resizers source pad (1). Effectively propagating
> >> MEDIA_BUS_FMT_YUYV8_2X8 for all formats.
> >>
> >> At this point if the video node (main or self) is configured with a
> >> YUV420 format (NV12, NV21, etc) and with this change applied the link
> >> validation will fail as MEDIA_BUS_FMT_YUYV8_1_5X8 !=
> >> MEDIA_BUS_FMT_YUYV8_2X8. Given the nature of how link validation is
> >> implemented it's VIDIOC_QBUF that returns a -EPIPE when it fails and
> >> libcamera lockup the capture session.
> > 
> > I would be very, very surprised is the hardware really used YUYV8_1_5X8.
> > YUYV8_1X16 is a much more likely bus format between the resizer and the
> > DMA engine, as well as between the ISP and the resizer.
> 
> Format YUYV8_1X16 is for downsampling of 4:2:2, but the resizer has the ability
> to downsample to 4:2:0.
> I see there is also format YDYUYDYV8_1X16 for 4:2:0
> maybe this is what I should set?
> 
> Actually according to the TRM the resizer send the stream to the DMA
> engine through two separated buses, one for luma and one for chroma.

In which document is this documented ? Is this two 8-bit buses side by
side ?

Looking at the registers, the output formats are controlled by the
global MI_CTRL register, common to both the main and self paths, which
should correspond to the DMA engine. I think it would make sense to
model this at the video node level, and hardcode YUYV8_1X16 between the
resizer and the video node.

> >> I will submit a fix for this to libcamera to bring it in sync with this
> >> change.
> >>
> >> Would it be possible to ask that future changes to the rkisp1 driver be
> >> tested with libcamera so we can track and update both the kernel and
> >> user-space components of this driver at the same time and avoid nasty
> >> surprises? :-)
> > 
> > I strongly second this. Drivers that are supported in libcamera should
> > be tested with libcamera to catch regressions, for any chance submitted
> > to the kernel.
> 
> I can run several 'cam' commands with different formats and dimensions to
> find regressions. I currently have unit test only in v4l-utils.

That would be great :-) We will work on a test suite for higher-level
tests (something similar to the Android CTS) at some point, which should
also help catching regressions.

> >> On 2020-07-23 15:20:13 +0200, Dafna Hirschfeld wrote:
> >>> The capture has a mapping of the mbus code needed for each pixelformat.
> >>> This can be used to simplify the link validation by comparing the mbus
> >>> code in the capture with the code in the resizer.
> >>>
> >>> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
> >>> ---
> >>>   drivers/staging/media/rkisp1/rkisp1-capture.c | 18 ++++--------------
> >>>   1 file changed, 4 insertions(+), 14 deletions(-)
> >>>
> >>> diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
> >>> index 4dabd07a3da9..a5e2521577dd 100644
> >>> --- a/drivers/staging/media/rkisp1/rkisp1-capture.c
> >>> +++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
> >>> @@ -1255,22 +1255,11 @@ static int rkisp1_capture_link_validate(struct media_link *link)
> >>>   	struct v4l2_subdev *sd =
> >>>   		media_entity_to_v4l2_subdev(link->source->entity);
> >>>   	struct rkisp1_capture *cap = video_get_drvdata(vdev);
> >>> -	struct rkisp1_isp *isp = &cap->rkisp1->isp;
> >>> -	u8 isp_pix_enc = isp->src_fmt->pixel_enc;
> >>> -	u8 cap_pix_enc = cap->pix.info->pixel_enc;
> >>> +	const struct rkisp1_capture_fmt_cfg *fmt =
> >>> +		rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
> >>>   	struct v4l2_subdev_format sd_fmt;
> >>>   	int ret;
> >>>   
> >>> -	if (cap_pix_enc != isp_pix_enc &&
> >>> -	    !(isp_pix_enc == V4L2_PIXEL_ENC_YUV &&
> >>> -	      cap_pix_enc == V4L2_PIXEL_ENC_RGB)) {
> >>> -		dev_err(cap->rkisp1->dev,
> >>> -			"format type mismatch in link '%s:%d->%s:%d'\n",
> >>> -			link->source->entity->name, link->source->index,
> >>> -			link->sink->entity->name, link->sink->index);
> >>> -		return -EPIPE;
> >>> -	}
> >>> -
> >>>   	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> >>>   	sd_fmt.pad = link->source->index;
> >>>   	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
> >>> @@ -1278,7 +1267,8 @@ static int rkisp1_capture_link_validate(struct media_link *link)
> >>>   		return ret;
> >>>   
> >>>   	if (sd_fmt.format.height != cap->pix.fmt.height ||
> >>> -	    sd_fmt.format.width != cap->pix.fmt.width)
> >>> +	    sd_fmt.format.width != cap->pix.fmt.width ||
> >>> +	    sd_fmt.format.code != fmt->mbus)
> >>>   		return -EPIPE;
> >>>   
> >>>   	return 0;
Dafna Hirschfeld Oct. 2, 2020, 7:04 a.m. UTC | #5
Hi,


Am 02.10.20 um 00:48 schrieb Laurent Pinchart:
> Hi Dafna,
> 
> On Thu, Oct 01, 2020 at 09:36:07PM +0200, Dafna Hirschfeld wrote:
>> Am 01.10.20 um 04:03 schrieb Laurent Pinchart:
>>> On Wed, Sep 30, 2020 at 09:00:25PM +0200, Niklas Söderlund wrote:
>>>> Hi Dafna,
>>>>
>>>> This commit is not just a simplification but a change of behavior.  The
>>>> change is for the better but it broke capture of NV12 and NV21 formats
>>>> in libcamera unexpectedly.
>>>>
>>>> The issue at hand is that libcamera when configuring the pipeline
>>>> retrieves the mbus code for the ISP (rkisp1_isp) source pad (2) and then
>>>> propagates it to the resizer (rkisp_resizer_{main,self}path) sink pad
>>>> (0) and then to the resizers source pad (1). Effectively propagating
>>>> MEDIA_BUS_FMT_YUYV8_2X8 for all formats.
>>>>
>>>> At this point if the video node (main or self) is configured with a
>>>> YUV420 format (NV12, NV21, etc) and with this change applied the link
>>>> validation will fail as MEDIA_BUS_FMT_YUYV8_1_5X8 !=
>>>> MEDIA_BUS_FMT_YUYV8_2X8. Given the nature of how link validation is
>>>> implemented it's VIDIOC_QBUF that returns a -EPIPE when it fails and
>>>> libcamera lockup the capture session.
>>>
>>> I would be very, very surprised is the hardware really used YUYV8_1_5X8.
>>> YUYV8_1X16 is a much more likely bus format between the resizer and the
>>> DMA engine, as well as between the ISP and the resizer.
>>
>> Format YUYV8_1X16 is for downsampling of 4:2:2, but the resizer has the ability
>> to downsample to 4:2:0.
>> I see there is also format YDYUYDYV8_1X16 for 4:2:0
>> maybe this is what I should set?
>>
>> Actually according to the TRM the resizer send the stream to the DMA
>> engine through two separated buses, one for luma and one for chroma.
> 
> In which document is this documented ? Is this two 8-bit buses side by
> side ?

here: https://rockchip.fr/RK3288%20TRM/rk3288-chapter-31-image-signal-processing-(isp).pdf

It is described that there is a splitter component before the
resizer. The diagram shows that those two separate streams are also
sent further to the DMA engine.

> 
> Looking at the registers, the output formats are controlled by the
> global MI_CTRL register, common to both the main and self paths, which
> should correspond to the DMA engine. I think it would make sense to
> model this at the video node level, and hardcode YUYV8_1X16 between the
> resizer and the video node.

Ok, I can change the mbus code. Is there a difference from userspace point of
view? If userspace wants to stream YUV 4:2:0, he should set the pixelformat on
the video node and should only care that the resizer and the video node agree
on the mbus code.

Thanks,
Dafna

> 
>>>> I will submit a fix for this to libcamera to bring it in sync with this
>>>> change.
>>>>
>>>> Would it be possible to ask that future changes to the rkisp1 driver be
>>>> tested with libcamera so we can track and update both the kernel and
>>>> user-space components of this driver at the same time and avoid nasty
>>>> surprises? :-)
>>>
>>> I strongly second this. Drivers that are supported in libcamera should
>>> be tested with libcamera to catch regressions, for any chance submitted
>>> to the kernel.
>>
>> I can run several 'cam' commands with different formats and dimensions to
>> find regressions. I currently have unit test only in v4l-utils.
> 
> That would be great :-) We will work on a test suite for higher-level
> tests (something similar to the Android CTS) at some point, which should
> also help catching regressions.
> 
>>>> On 2020-07-23 15:20:13 +0200, Dafna Hirschfeld wrote:
>>>>> The capture has a mapping of the mbus code needed for each pixelformat.
>>>>> This can be used to simplify the link validation by comparing the mbus
>>>>> code in the capture with the code in the resizer.
>>>>>
>>>>> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
>>>>> ---
>>>>>    drivers/staging/media/rkisp1/rkisp1-capture.c | 18 ++++--------------
>>>>>    1 file changed, 4 insertions(+), 14 deletions(-)
>>>>>
>>>>> diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
>>>>> index 4dabd07a3da9..a5e2521577dd 100644
>>>>> --- a/drivers/staging/media/rkisp1/rkisp1-capture.c
>>>>> +++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
>>>>> @@ -1255,22 +1255,11 @@ static int rkisp1_capture_link_validate(struct media_link *link)
>>>>>    	struct v4l2_subdev *sd =
>>>>>    		media_entity_to_v4l2_subdev(link->source->entity);
>>>>>    	struct rkisp1_capture *cap = video_get_drvdata(vdev);
>>>>> -	struct rkisp1_isp *isp = &cap->rkisp1->isp;
>>>>> -	u8 isp_pix_enc = isp->src_fmt->pixel_enc;
>>>>> -	u8 cap_pix_enc = cap->pix.info->pixel_enc;
>>>>> +	const struct rkisp1_capture_fmt_cfg *fmt =
>>>>> +		rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
>>>>>    	struct v4l2_subdev_format sd_fmt;
>>>>>    	int ret;
>>>>>    
>>>>> -	if (cap_pix_enc != isp_pix_enc &&
>>>>> -	    !(isp_pix_enc == V4L2_PIXEL_ENC_YUV &&
>>>>> -	      cap_pix_enc == V4L2_PIXEL_ENC_RGB)) {
>>>>> -		dev_err(cap->rkisp1->dev,
>>>>> -			"format type mismatch in link '%s:%d->%s:%d'\n",
>>>>> -			link->source->entity->name, link->source->index,
>>>>> -			link->sink->entity->name, link->sink->index);
>>>>> -		return -EPIPE;
>>>>> -	}
>>>>> -
>>>>>    	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
>>>>>    	sd_fmt.pad = link->source->index;
>>>>>    	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
>>>>> @@ -1278,7 +1267,8 @@ static int rkisp1_capture_link_validate(struct media_link *link)
>>>>>    		return ret;
>>>>>    
>>>>>    	if (sd_fmt.format.height != cap->pix.fmt.height ||
>>>>> -	    sd_fmt.format.width != cap->pix.fmt.width)
>>>>> +	    sd_fmt.format.width != cap->pix.fmt.width ||
>>>>> +	    sd_fmt.format.code != fmt->mbus)
>>>>>    		return -EPIPE;
>>>>>    
>>>>>    	return 0;
>
Helen Mae Koike Fornazier Oct. 22, 2020, 11:02 a.m. UTC | #6
Hi Laurent,

Thanks for your comments.
There is one thing that is still confusing to me (please see my question
below).

On 10/1/20 7:48 PM, Laurent Pinchart wrote:
> Hi Dafna,
> 
> On Thu, Oct 01, 2020 at 09:36:07PM +0200, Dafna Hirschfeld wrote:
>> Am 01.10.20 um 04:03 schrieb Laurent Pinchart:
>>> On Wed, Sep 30, 2020 at 09:00:25PM +0200, Niklas Söderlund wrote:
>>>> Hi Dafna,
>>>>
>>>> This commit is not just a simplification but a change of behavior.  The
>>>> change is for the better but it broke capture of NV12 and NV21 formats
>>>> in libcamera unexpectedly.
>>>>
>>>> The issue at hand is that libcamera when configuring the pipeline
>>>> retrieves the mbus code for the ISP (rkisp1_isp) source pad (2) and then
>>>> propagates it to the resizer (rkisp_resizer_{main,self}path) sink pad
>>>> (0) and then to the resizers source pad (1). Effectively propagating
>>>> MEDIA_BUS_FMT_YUYV8_2X8 for all formats.
>>>>
>>>> At this point if the video node (main or self) is configured with a
>>>> YUV420 format (NV12, NV21, etc) and with this change applied the link
>>>> validation will fail as MEDIA_BUS_FMT_YUYV8_1_5X8 !=
>>>> MEDIA_BUS_FMT_YUYV8_2X8. Given the nature of how link validation is
>>>> implemented it's VIDIOC_QBUF that returns a -EPIPE when it fails and
>>>> libcamera lockup the capture session.
>>>
>>> I would be very, very surprised is the hardware really used YUYV8_1_5X8.
>>> YUYV8_1X16 is a much more likely bus format between the resizer and the
>>> DMA engine, as well as between the ISP and the resizer.
>>
>> Format YUYV8_1X16 is for downsampling of 4:2:2, but the resizer has the ability
>> to downsample to 4:2:0.
>> I see there is also format YDYUYDYV8_1X16 for 4:2:0
>> maybe this is what I should set?
>>
>> Actually according to the TRM the resizer send the stream to the DMA
>> engine through two separated buses, one for luma and one for chroma.
> 
> In which document is this documented ? Is this two 8-bit buses side by
> side ?
> 
> Looking at the registers, the output formats are controlled by the
> global MI_CTRL register, common to both the main and self paths, which
> should correspond to the DMA engine. I think it would make sense to
> model this at the video node level, and hardcode YUYV8_1X16 between the
> resizer and the video node.

If I understand correctly, in a 4:2:0 format, we have 4 luminance
components per chrominance.

And with the YUYV8_1X16, we have 2 luminance per chrominance.

Are you suggesting that, when userspace sets 4:2:0 (NV12, NV21, YU12, YV12),
we should use MEDIA_BUS_FMT_YUYV8_1X16 between the resizer and the DMA engine?

But then, down sampling rate here won't match (this is where my confusion
comes from).

Or, are you assuming that the DMA engine receives 4:2:2 and performs the
conversion?

I would appreciate if you could help clarify this.


Just to note here, in the docs Dafna pointed, it's written:

"The Resize module is able to process luminance and chrominance data
independently, i.e. there are separate pipelines for luminance and
chrominance processing using dedicated scale factors and phase offsets.
This allows format conversion to be done by the Resize block (YCbCr 4:2:2 to
4:2:0, 4:1:1, 4:1:0)."

Thanks
Helen


> 
>>>> I will submit a fix for this to libcamera to bring it in sync with this
>>>> change.
>>>>
>>>> Would it be possible to ask that future changes to the rkisp1 driver be
>>>> tested with libcamera so we can track and update both the kernel and
>>>> user-space components of this driver at the same time and avoid nasty
>>>> surprises? :-)
>>>
>>> I strongly second this. Drivers that are supported in libcamera should
>>> be tested with libcamera to catch regressions, for any chance submitted
>>> to the kernel.
>>
>> I can run several 'cam' commands with different formats and dimensions to
>> find regressions. I currently have unit test only in v4l-utils.
> 
> That would be great :-) We will work on a test suite for higher-level
> tests (something similar to the Android CTS) at some point, which should
> also help catching regressions.
> 
>>>> On 2020-07-23 15:20:13 +0200, Dafna Hirschfeld wrote:
>>>>> The capture has a mapping of the mbus code needed for each pixelformat.
>>>>> This can be used to simplify the link validation by comparing the mbus
>>>>> code in the capture with the code in the resizer.
>>>>>
>>>>> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
>>>>> ---
>>>>>   drivers/staging/media/rkisp1/rkisp1-capture.c | 18 ++++--------------
>>>>>   1 file changed, 4 insertions(+), 14 deletions(-)
>>>>>
>>>>> diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
>>>>> index 4dabd07a3da9..a5e2521577dd 100644
>>>>> --- a/drivers/staging/media/rkisp1/rkisp1-capture.c
>>>>> +++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
>>>>> @@ -1255,22 +1255,11 @@ static int rkisp1_capture_link_validate(struct media_link *link)
>>>>>   	struct v4l2_subdev *sd =
>>>>>   		media_entity_to_v4l2_subdev(link->source->entity);
>>>>>   	struct rkisp1_capture *cap = video_get_drvdata(vdev);
>>>>> -	struct rkisp1_isp *isp = &cap->rkisp1->isp;
>>>>> -	u8 isp_pix_enc = isp->src_fmt->pixel_enc;
>>>>> -	u8 cap_pix_enc = cap->pix.info->pixel_enc;
>>>>> +	const struct rkisp1_capture_fmt_cfg *fmt =
>>>>> +		rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
>>>>>   	struct v4l2_subdev_format sd_fmt;
>>>>>   	int ret;
>>>>>   
>>>>> -	if (cap_pix_enc != isp_pix_enc &&
>>>>> -	    !(isp_pix_enc == V4L2_PIXEL_ENC_YUV &&
>>>>> -	      cap_pix_enc == V4L2_PIXEL_ENC_RGB)) {
>>>>> -		dev_err(cap->rkisp1->dev,
>>>>> -			"format type mismatch in link '%s:%d->%s:%d'\n",
>>>>> -			link->source->entity->name, link->source->index,
>>>>> -			link->sink->entity->name, link->sink->index);
>>>>> -		return -EPIPE;
>>>>> -	}
>>>>> -
>>>>>   	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
>>>>>   	sd_fmt.pad = link->source->index;
>>>>>   	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
>>>>> @@ -1278,7 +1267,8 @@ static int rkisp1_capture_link_validate(struct media_link *link)
>>>>>   		return ret;
>>>>>   
>>>>>   	if (sd_fmt.format.height != cap->pix.fmt.height ||
>>>>> -	    sd_fmt.format.width != cap->pix.fmt.width)
>>>>> +	    sd_fmt.format.width != cap->pix.fmt.width ||
>>>>> +	    sd_fmt.format.code != fmt->mbus)
>>>>>   		return -EPIPE;
>>>>>   
>>>>>   	return 0;
>
diff mbox series

Patch

diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
index 4dabd07a3da9..a5e2521577dd 100644
--- a/drivers/staging/media/rkisp1/rkisp1-capture.c
+++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
@@ -1255,22 +1255,11 @@  static int rkisp1_capture_link_validate(struct media_link *link)
 	struct v4l2_subdev *sd =
 		media_entity_to_v4l2_subdev(link->source->entity);
 	struct rkisp1_capture *cap = video_get_drvdata(vdev);
-	struct rkisp1_isp *isp = &cap->rkisp1->isp;
-	u8 isp_pix_enc = isp->src_fmt->pixel_enc;
-	u8 cap_pix_enc = cap->pix.info->pixel_enc;
+	const struct rkisp1_capture_fmt_cfg *fmt =
+		rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
 	struct v4l2_subdev_format sd_fmt;
 	int ret;
 
-	if (cap_pix_enc != isp_pix_enc &&
-	    !(isp_pix_enc == V4L2_PIXEL_ENC_YUV &&
-	      cap_pix_enc == V4L2_PIXEL_ENC_RGB)) {
-		dev_err(cap->rkisp1->dev,
-			"format type mismatch in link '%s:%d->%s:%d'\n",
-			link->source->entity->name, link->source->index,
-			link->sink->entity->name, link->sink->index);
-		return -EPIPE;
-	}
-
 	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
 	sd_fmt.pad = link->source->index;
 	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
@@ -1278,7 +1267,8 @@  static int rkisp1_capture_link_validate(struct media_link *link)
 		return ret;
 
 	if (sd_fmt.format.height != cap->pix.fmt.height ||
-	    sd_fmt.format.width != cap->pix.fmt.width)
+	    sd_fmt.format.width != cap->pix.fmt.width ||
+	    sd_fmt.format.code != fmt->mbus)
 		return -EPIPE;
 
 	return 0;