| Message ID | 20260818094507.4082940-1-elliot.chen@oss.nxp.com |
|---|---|
| State | Accepted |
| Headers | show |
| Series |
|
| Related | show |
Hi Elliot, On Tue, Aug 18, 2026 at 06:45:07PM +0900, elliot.chen@oss.nxp.com wrote: > From: Elliot Chen <elliot.chen@nxp.com> > > After initial negotiation, a downstream element may append extra > fields to the caps (e.g. colorimetry). The existing check only > handles empty peer caps. Add a structure comparison to detect such > changes and trigger reconfiguration with caps renegotiation. > Don't worry, I'll add Closes: https://gitlab.freedesktop.org/camera/libcamera/-/work_items/344 When applying > Signed-off-by: Elliot Chen <elliot.chen@nxp.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Nicolas: your tag was dropped, should I add it back when applying ? Thanks j > > --- > Changes in v3: > - rename caps structure > > Changes in v2: > - remove redundant checks both for caps and peercaps > > Changes in v1: > - Initial submission > --- > src/gstreamer/gstlibcamerasrc.cpp | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp > index 9061f9163..9541aa3f6 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -744,6 +744,18 @@ gst_libcamera_src_task_run(gpointer user_data) > reconfigure = true; > break; > } > + > + /* > + * Caps may gain extra fields after the initial negotiation (e.g. > + * colorimetry added by a downstream element). Detect such changes > + * and trigger reconfiguration. > + */ > + const GstStructure *caps0 = gst_caps_get_structure(caps, 0); > + const GstStructure *peercaps0 = gst_caps_get_structure(peercaps, 0); > + if (!gst_structure_is_equal(caps0, peercaps0)) { > + reconfigure = true; > + break; > + } > } > } > > -- > 2.34.1 >
Hi Jacopo, Thank you very much. NXP Confidential -----Original Message----- From: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Sent: Tuesday, August 18, 2026 5:52 PM To: Elliot Chen (OSS) <elliot.chen@oss.nxp.com>; nicolas@ndufresne.ca Cc: libcamera-devel@lists.libcamera.org; Elliot Chen <elliot.chen@nxp.com> Subject: Re: [PATCH v3] gstreamer: Reconfigure when peer caps gain extra fields [You don't often get email from jacopo.mondi@ideasonboard.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] Hi Elliot, On Tue, Aug 18, 2026 at 06:45:07PM +0900, elliot.chen@oss.nxp.com wrote: > From: Elliot Chen <elliot.chen@nxp.com> > > After initial negotiation, a downstream element may append extra > fields to the caps (e.g. colorimetry). The existing check only handles > empty peer caps. Add a structure comparison to detect such changes and > trigger reconfiguration with caps renegotiation. > Don't worry, I'll add Closes: https://gitlab.freedesktop.org/camera/libcamera/-/work_items/344 When applying > Signed-off-by: Elliot Chen <elliot.chen@nxp.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Nicolas: your tag was dropped, should I add it back when applying ? Thanks j > > --- > Changes in v3: > - rename caps structure > > Changes in v2: > - remove redundant checks both for caps and peercaps > > Changes in v1: > - Initial submission > --- > src/gstreamer/gstlibcamerasrc.cpp | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/src/gstreamer/gstlibcamerasrc.cpp > b/src/gstreamer/gstlibcamerasrc.cpp > index 9061f9163..9541aa3f6 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -744,6 +744,18 @@ gst_libcamera_src_task_run(gpointer user_data) > reconfigure = true; > break; > } > + > + /* > + * Caps may gain extra fields after the initial negotiation (e.g. > + * colorimetry added by a downstream element). Detect such changes > + * and trigger reconfiguration. > + */ > + const GstStructure *caps0 = gst_caps_get_structure(caps, 0); > + const GstStructure *peercaps0 = gst_caps_get_structure(peercaps, 0); > + if (!gst_structure_is_equal(caps0, peercaps0)) { > + reconfigure = true; > + break; > + } > } > } > > -- > 2.34.1 >
Hi, Le mardi 18 août 2026 à 18:45 +0900, elliot.chen@oss.nxp.com a écrit : > From: Elliot Chen <elliot.chen@nxp.com> > > After initial negotiation, a downstream element may append extra > fields to the caps (e.g. colorimetry). The existing check only > handles empty peer caps. Add a structure comparison to detect such > changes and trigger reconfiguration with caps renegotiation. To bring everyone ont he same page. In this scenarios we already negotiated our caps. But the reconfigure flag has been raised a pad, the pad raise it when it receives reconfigure event. Since we don't want to do a full reconfiguration everytime, which requires to stop and start the camera, we currently check if the previously negotiated caps intersect with the peer modified capabilities. # Get the currently configured caps, these are single structure, fixed caps = gst_pad_get_current_caps(srcpad); # Query downstream caps, passing our current caps as filter g_autoptr(GstCaps) peercaps = gst_pad_peer_query_caps(pad: srcpad, filter: caps); At this point, what the current code does is that if the result is empty, it means the current caps are not compatible with downstream. And this is always true due to that fact the a missing feild imply supporting any value of this field. The following return is entirely possible: current: video/x-raw,width=1,height=1,format=x peercaps: video/x-raw,width=1,height=1,format=x,colorimetry=bt709 Its a very niche case, but this is what Elliot is trying to catch. Its not a nice use case either, since the first negotiation had undefined colorimetry, which results depends on the guessing of downstream element. For that reason, if this is really the main reason for this patch, I would look into making sure we always negotiate a fixed colorimetry. Having it fixed, if we didn't pick one supported downstream before renegotation, then the return filter will be empty since the two will no longer intersect. > > Signed-off-by: Elliot Chen <elliot.chen@nxp.com> > > --- > Changes in v3: > - rename caps structure > > Changes in v2: > - remove redundant checks both for caps and peercaps > > Changes in v1: > - Initial submission > --- > src/gstreamer/gstlibcamerasrc.cpp | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp > index 9061f9163..9541aa3f6 100644 > --- a/src/gstreamer/gstlibcamerasrc.cpp > +++ b/src/gstreamer/gstlibcamerasrc.cpp > @@ -744,6 +744,18 @@ gst_libcamera_src_task_run(gpointer user_data) > reconfigure = true; > break; > } > + > + /* > + * Caps may gain extra fields after the initial negotiation (e.g. > + * colorimetry added by a downstream element). Detect such changes > + * and trigger reconfiguration. > + */ > + const GstStructure *caps0 = gst_caps_get_structure(caps, 0); > + const GstStructure *peercaps0 = gst_caps_get_structure(peercaps, 0); > + if (!gst_structure_is_equal(caps0, peercaps0)) { > + reconfigure = true; > + break; > + } So while I don't think this is fundamentally broken, its a bit off to me. We should address undefined behaviors at their source first. Not-Accepted Nicolas > } > } >
Hi Nicolas Dufresne,
1. For this patch itself, it ensures that the first caps in the new queried caps must be equal to the current one and should trigger caps negotiation again if not. The current caps may in the queried caps again but not the first one.
It's not just check whether the new queried caps gain extra field. I'll modify the comment about it.
2. For many common cases, it will not add colorimetry field in the caps explicitly except v4l2 encoder. This behavior is no related to one plugin.
Some Examples without colorimetry field in the caps :
1. gst-launch-1.0 videotestsrc ! video/x-raw,format=RGBA ! waylandsink -v
2. gst-launch-1.0 videotestsrc ! video/x-raw,format=RGBA ! fakesink -v
3. gst-launch-1.0 libcamerasrc ! fakesink -v
4. gst-launch-1.0 libcamerasrc ! filesink location=test.bin -v
NXP Confidential
-----Original Message-----
From: Nicolas Dufresne <nicolas@ndufresne.ca>
Sent: Friday, August 21, 2026 4:13 AM
To: Elliot Chen (OSS) <elliot.chen@oss.nxp.com>; libcamera-devel@lists.libcamera.org
Cc: Elliot Chen <elliot.chen@nxp.com>
Subject: Re: [PATCH v3] gstreamer: Reconfigure when peer caps gain extra fields
Hi,
Le mardi 18 août 2026 à 18:45 +0900, elliot.chen@oss.nxp.com a écrit :
> From: Elliot Chen <elliot.chen@nxp.com>
>
> After initial negotiation, a downstream element may append extra
> fields to the caps (e.g. colorimetry). The existing check only handles
> empty peer caps. Add a structure comparison to detect such changes and
> trigger reconfiguration with caps renegotiation.
To bring everyone ont he same page. In this scenarios we already negotiated our caps. But the reconfigure flag has been raised a pad, the pad raise it when it receives reconfigure event.
Since we don't want to do a full reconfiguration everytime, which requires to stop and start the camera, we currently check if the previously negotiated caps intersect with the peer modified capabilities.
# Get the currently configured caps, these are single structure, fixed
caps = gst_pad_get_current_caps(srcpad);
# Query downstream caps, passing our current caps as filter
g_autoptr(GstCaps) peercaps = gst_pad_peer_query_caps(pad: srcpad, filter: caps);
At this point, what the current code does is that if the result is empty, it means the current caps are not compatible with downstream. And this is always true due to that fact the a missing feild imply supporting any value of this field. The following return is entirely possible:
current: video/x-raw,width=1,height=1,format=x
peercaps: video/x-raw,width=1,height=1,format=x,colorimetry=bt709
Its a very niche case, but this is what Elliot is trying to catch. Its not a nice use case either, since the first negotiation had undefined colorimetry, which results depends on the guessing of downstream element. For that reason, if this is really the main reason for this patch, I would look into making sure we always negotiate a fixed colorimetry. Having it fixed, if we didn't pick one supported downstream before renegotation, then the return filter will be empty since the two will no longer intersect.
>
> Signed-off-by: Elliot Chen <elliot.chen@nxp.com>
>
> ---
> Changes in v3:
> - rename caps structure
>
> Changes in v2:
> - remove redundant checks both for caps and peercaps
>
> Changes in v1:
> - Initial submission
> ---
> src/gstreamer/gstlibcamerasrc.cpp | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/src/gstreamer/gstlibcamerasrc.cpp
> b/src/gstreamer/gstlibcamerasrc.cpp
> index 9061f9163..9541aa3f6 100644
> --- a/src/gstreamer/gstlibcamerasrc.cpp
> +++ b/src/gstreamer/gstlibcamerasrc.cpp
> @@ -744,6 +744,18 @@ gst_libcamera_src_task_run(gpointer user_data)
> reconfigure = true;
> break;
> }
> +
> + /*
> + * Caps may gain extra fields after the initial negotiation (e.g.
> + * colorimetry added by a downstream element). Detect such changes
> + * and trigger reconfiguration.
> + */
> + const GstStructure *caps0 = gst_caps_get_structure(caps, 0);
> + const GstStructure *peercaps0 = gst_caps_get_structure(peercaps, 0);
> + if (!gst_structure_is_equal(caps0, peercaps0)) {
> + reconfigure = true;
> + break;
> + }
So while I don't think this is fundamentally broken, its a bit off to me. We should address undefined behaviors at their source first.
Not-Accepted
Nicolas
> }
> }
>
On Thu, Aug 20, 2026 at 04:12:59PM -0400, Nicolas Dufresne wrote: > Hi, > > Le mardi 18 août 2026 à 18:45 +0900, elliot.chen@oss.nxp.com a écrit : > > From: Elliot Chen <elliot.chen@nxp.com> > > > > After initial negotiation, a downstream element may append extra > > fields to the caps (e.g. colorimetry). The existing check only > > handles empty peer caps. Add a structure comparison to detect such > > changes and trigger reconfiguration with caps renegotiation. > > > To bring everyone ont he same page. In this scenarios we already negotiated our > caps. But the reconfigure flag has been raised a pad, the pad raise it when it > receives reconfigure event. > > Since we don't want to do a full reconfiguration everytime, which requires to > stop and start the camera, we currently check if the previously negotiated caps > intersect with the peer modified capabilities. > > # Get the currently configured caps, these are single structure, fixed > caps = gst_pad_get_current_caps(srcpad); > > # Query downstream caps, passing our current caps as filter > g_autoptr(GstCaps) peercaps = gst_pad_peer_query_caps(pad: srcpad, filter: caps); > > > At this point, what the current code does is that if the result is empty, it > means the current caps are not compatible with downstream. And this is always > true due to that fact the a missing feild imply supporting any value of this > field. The following return is entirely possible: > > current: video/x-raw,width=1,height=1,format=x > peercaps: video/x-raw,width=1,height=1,format=x,colorimetry=bt709 > > > Its a very niche case, but this is what Elliot is trying to catch. Its not a > nice use case either, since the first negotiation had undefined colorimetry, > which results depends on the guessing of downstream element. For that reason, if > this is really the main reason for this patch, I would look into making sure we > always negotiate a fixed colorimetry. Having it fixed, if we didn't pick one > supported downstream before renegotation, then the return filter will be empty > since the two will no longer intersect. > > > > > Signed-off-by: Elliot Chen <elliot.chen@nxp.com> > > > > --- > > Changes in v3: > > - rename caps structure > > > > Changes in v2: > > - remove redundant checks both for caps and peercaps > > > > Changes in v1: > > - Initial submission > > --- > > src/gstreamer/gstlibcamerasrc.cpp | 12 ++++++++++++ > > 1 file changed, 12 insertions(+) > > > > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp > > index 9061f9163..9541aa3f6 100644 > > --- a/src/gstreamer/gstlibcamerasrc.cpp > > +++ b/src/gstreamer/gstlibcamerasrc.cpp > > @@ -744,6 +744,18 @@ gst_libcamera_src_task_run(gpointer user_data) > > reconfigure = true; > > break; > > } > > + > > + /* > > + * Caps may gain extra fields after the initial negotiation (e.g. > > + * colorimetry added by a downstream element). Detect such changes > > + * and trigger reconfiguration. > > + */ > > + const GstStructure *caps0 = gst_caps_get_structure(caps, 0); > > + const GstStructure *peercaps0 = gst_caps_get_structure(peercaps, 0); > > + if (!gst_structure_is_equal(caps0, peercaps0)) { > > + reconfigure = true; > > + break; > > + } > > So while I don't think this is fundamentally broken, its a bit off to me. We > should address undefined behaviors at their source first. > > Not-Accepted > I already merged it yesterday unfortunately. What would you like me to do here ? revert or can this be worked on top ? > Nicolas > > > } > > } > >
Le vendredi 21 août 2026 à 06:31 +0000, Elliot Chen (OSS) a écrit : > Hi Nicolas Dufresne, > 1. For this patch itself, it ensures that the first caps in the new queried caps must be equal to the current one and should trigger caps negotiation again if not. The current caps may in the queried caps again but not the first one. > It's not just check whether the new queried caps gain extra field. I'll modify the comment about it. > 2. For many common cases, it will not add colorimetry field in the caps explicitly except v4l2 encoder. This behavior is no related to one plugin. > > Some Examples without colorimetry field in the caps : > 1. gst-launch-1.0 videotestsrc ! video/x-raw,format=RGBA ! waylandsink -v > 2. gst-launch-1.0 videotestsrc ! video/x-raw,format=RGBA ! fakesink -v > 3. gst-launch-1.0 libcamerasrc ! fakesink -v > 4. gst-launch-1.0 libcamerasrc ! filesink location=test.bin -v But this is bugs, not feature. The expected principle that allow adding field is not being respected. If a source makes any decision or have knowledge around a field, it should explicitly add it, regardless if downstream depends on it or not. waylandsink is a good example, it does not require colorimetry for backward compatibility reason, but the rendering behaviour is undefined if you don't specify it. I'll follow up fixing the lack of colorimetry produced by videotestsrc caps. > > > NXP Confidential driver by: this is probably accidental footer, but it has no place on public mailing list. > -----Original Message----- > From: Nicolas Dufresne <nicolas@ndufresne.ca> > Sent: Friday, August 21, 2026 4:13 AM > To: Elliot Chen (OSS) <elliot.chen@oss.nxp.com>; libcamera-devel@lists.libcamera.org > Cc: Elliot Chen <elliot.chen@nxp.com> > Subject: Re: [PATCH v3] gstreamer: Reconfigure when peer caps gain extra fields > > Hi, > > Le mardi 18 août 2026 à 18:45 +0900, elliot.chen@oss.nxp.com a écrit : > > From: Elliot Chen <elliot.chen@nxp.com> > > > > After initial negotiation, a downstream element may append extra > > fields to the caps (e.g. colorimetry). The existing check only handles > > empty peer caps. Add a structure comparison to detect such changes and > > trigger reconfiguration with caps renegotiation. > > > To bring everyone ont he same page. In this scenarios we already negotiated our caps. But the reconfigure flag has been raised a pad, the pad raise it when it receives reconfigure event. > > Since we don't want to do a full reconfiguration everytime, which requires to stop and start the camera, we currently check if the previously negotiated caps intersect with the peer modified capabilities. > > # Get the currently configured caps, these are single structure, fixed > caps = gst_pad_get_current_caps(srcpad); > > # Query downstream caps, passing our current caps as filter > g_autoptr(GstCaps) peercaps = gst_pad_peer_query_caps(pad: srcpad, filter: caps); > > > At this point, what the current code does is that if the result is empty, it means the current caps are not compatible with downstream. And this is always true due to that fact the a missing feild imply supporting any value of this field. The following return is entirely possible: > > current: video/x-raw,width=1,height=1,format=x > peercaps: video/x-raw,width=1,height=1,format=x,colorimetry=bt709 > > > Its a very niche case, but this is what Elliot is trying to catch. Its not a nice use case either, since the first negotiation had undefined colorimetry, which results depends on the guessing of downstream element. For that reason, if this is really the main reason for this patch, I would look into making sure we always negotiate a fixed colorimetry. Having it fixed, if we didn't pick one supported downstream before renegotation, then the return filter will be empty since the two will no longer intersect. > Since Jacopo merged your patch, I'll looking forward a fix on top that ensure relevant field are being fixated (and added) where needed. Nicolas > > > > Signed-off-by: Elliot Chen <elliot.chen@nxp.com> > > > > --- > > Changes in v3: > > - rename caps structure > > > > Changes in v2: > > - remove redundant checks both for caps and peercaps > > > > Changes in v1: > > - Initial submission > > --- > > src/gstreamer/gstlibcamerasrc.cpp | 12 ++++++++++++ > > 1 file changed, 12 insertions(+) > > > > diff --git a/src/gstreamer/gstlibcamerasrc.cpp > > b/src/gstreamer/gstlibcamerasrc.cpp > > index 9061f9163..9541aa3f6 100644 > > --- a/src/gstreamer/gstlibcamerasrc.cpp > > +++ b/src/gstreamer/gstlibcamerasrc.cpp > > @@ -744,6 +744,18 @@ gst_libcamera_src_task_run(gpointer user_data) > > reconfigure = true; > > break; > > } > > + > > + /* > > + * Caps may gain extra fields after the initial negotiation (e.g. > > + * colorimetry added by a downstream element). Detect such changes > > + * and trigger reconfiguration. > > + */ > > + const GstStructure *caps0 = gst_caps_get_structure(caps, 0); > > + const GstStructure *peercaps0 = gst_caps_get_structure(peercaps, 0); > > + if (!gst_structure_is_equal(caps0, peercaps0)) { > > + reconfigure = true; > > + break; > > + } > > So while I don't think this is fundamentally broken, its a bit off to me. We should address undefined behaviors at their source first. > > Not-Accepted > > Nicolas > > > } > > } > >
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 9061f9163..9541aa3f6 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -744,6 +744,18 @@ gst_libcamera_src_task_run(gpointer user_data) reconfigure = true; break; } + + /* + * Caps may gain extra fields after the initial negotiation (e.g. + * colorimetry added by a downstream element). Detect such changes + * and trigger reconfiguration. + */ + const GstStructure *caps0 = gst_caps_get_structure(caps, 0); + const GstStructure *peercaps0 = gst_caps_get_structure(peercaps, 0); + if (!gst_structure_is_equal(caps0, peercaps0)) { + reconfigure = true; + break; + } } }