[{"id":32722,"web_url":"https://patchwork.libcamera.org/comment/32722/","msgid":"<9f9100544b024594ee3c9baa5173fc0f9cd912cd.camel@ndufresne.ca>","date":"2024-12-13T18:23:54","subject":"Re: [PATCH v2] gstreamer: keep same transfer with that in\n\tnegotiated caps","submitter":{"id":30,"url":"https://patchwork.libcamera.org/api/people/30/","name":"Nicolas Dufresne","email":"nicolas@ndufresne.ca"},"content":"Hi,\n\nLe vendredi 13 décembre 2024 à 15:03 +0900, Hou Qi a écrit :\n> The conversions back and forth between GStreamer colorimetry and\n> libcamera color space are not invariant for the bt601 colorimetry.\n> The reason is that Rec709 transfer function defined in GStreamer\n> as GST_VIDEO_TRANSFER_BT709 (5), is to be replaced by its alias\n> GST_VIDEO_TRANSFER_BT601 (16) only for the case of bt601 (aka 2:4:16:4)\n> colorimetry - see [1].\n> \n> Currently the composition of the GStreamer/libcamera conversions:\n> colorimetry_from_colorspace (colorspace_from_colorimetry (bt601))\n> returns 2:4:5:4 instead of the expected 2:4:16:4 (bt601). This\n> causes negotiation error when the downstream element explicitly\n> expects bt601 colorimetry.\n> \n> Minimal example to reproduce the issue is with a pipeline handler\n> that do not set the optional color space in the stream configuration,\n> for instance vimc or imx8-isi:\n> export LIBCAMERA_PIPELINES_MATCH_LIST=\"vimc,imx8-isi\"\n> gst-launch-1.0 -v libcamerasrc ! video/x-raw,colorimetry=bt601 ! fakesink\n> \n> Above pipeline fails to start. This change memorizes downstream required\n> transfer function when mapped libcamera transfer is Rec709 in\n> gst_libcamera_configure_stream_from_caps(), and restores the transfer\n> function in gst_libcamera_stream_formats_to_caps().\n> \n> [1] https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/724\n> \n> Bug: https://bugs.libcamera.org/show_bug.cgi?id=150\n> Signed-off-by: Hou Qi <qi.hou@nxp.com>\n\n\nLooks good now. We could have improved the naming for the variable \"transfer\",\nbut can't think of a good suggestion, and it does not change anything to the\nlogic which I believe is right.\n\nReviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n\nThanks for you work,\nNicolas\n\n> ---\n>  src/gstreamer/gstlibcamera-utils.cpp | 19 +++++++++++--------\n>  src/gstreamer/gstlibcamera-utils.h   |  5 +++--\n>  src/gstreamer/gstlibcamerasrc.cpp    |  6 ++++--\n>  3 files changed, 18 insertions(+), 12 deletions(-)\n> \n> diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp\n> index 732987ef..23756b15 100644\n> --- a/src/gstreamer/gstlibcamera-utils.cpp\n> +++ b/src/gstreamer/gstlibcamera-utils.cpp\n> @@ -85,7 +85,7 @@ static struct {\n>  };\n>  \n>  static GstVideoColorimetry\n> -colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> +colorimetry_from_colorspace(const ColorSpace &colorSpace, GstVideoTransferFunction transfer)\n>  {\n>  \tGstVideoColorimetry colorimetry;\n>  \n> @@ -113,6 +113,8 @@ colorimetry_from_colorspace(const ColorSpace &colorSpace)\n>  \t\tbreak;\n>  \tcase ColorSpace::TransferFunction::Rec709:\n>  \t\tcolorimetry.transfer = GST_VIDEO_TRANSFER_BT709;\n> +\t\tif (transfer)\n> +\t\t\tcolorimetry.transfer = transfer;\n>  \t\tbreak;\n>  \t}\n>  \n> @@ -144,7 +146,7 @@ colorimetry_from_colorspace(const ColorSpace &colorSpace)\n>  }\n>  \n>  static std::optional<ColorSpace>\n> -colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry)\n> +colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry, GstVideoTransferFunction *transfer)\n>  {\n>  \tstd::optional<ColorSpace> colorspace = ColorSpace::Raw;\n>  \n> @@ -188,6 +190,7 @@ colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry)\n>  \tcase GST_VIDEO_TRANSFER_BT2020_12:\n>  \tcase GST_VIDEO_TRANSFER_BT709:\n>  \t\tcolorspace->transferFunction = ColorSpace::TransferFunction::Rec709;\n> +\t\t*transfer = colorimetry.transfer;\n>  \t\tbreak;\n>  \tdefault:\n>  \t\tGST_WARNING(\"Colorimetry transfer function %d not mapped in gstlibcamera\",\n> @@ -379,7 +382,8 @@ gst_libcamera_stream_formats_to_caps(const StreamFormats &formats)\n>  }\n>  \n>  GstCaps *\n> -gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg)\n> +gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg,\n> +\t\t\t\t\t   GstVideoTransferFunction transfer)\n>  {\n>  \tGstCaps *caps = gst_caps_new_empty();\n>  \tGstStructure *s = bare_structure_from_format(stream_cfg.pixelFormat);\n> @@ -390,7 +394,7 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg\n>  \t\t\t  nullptr);\n>  \n>  \tif (stream_cfg.colorSpace) {\n> -\t\tGstVideoColorimetry colorimetry = colorimetry_from_colorspace(stream_cfg.colorSpace.value());\n> +\t\tGstVideoColorimetry colorimetry = colorimetry_from_colorspace(stream_cfg.colorSpace.value(), transfer);\n>  \t\tg_autofree gchar *colorimetry_str = gst_video_colorimetry_to_string(&colorimetry);\n>  \n>  \t\tif (colorimetry_str)\n> @@ -405,9 +409,8 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg\n>  \treturn caps;\n>  }\n>  \n> -void\n> -gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> -\t\t\t\t\t GstCaps *caps)\n> +void gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> +\t\t\t\t\t      GstCaps *caps, GstVideoTransferFunction *transfer)\n>  {\n>  \tGstVideoFormat gst_format = pixel_format_to_gst_format(stream_cfg.pixelFormat);\n>  \tguint i;\n> @@ -495,7 +498,7 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n>  \t\tif (!gst_video_colorimetry_from_string(&colorimetry, colorimetry_str))\n>  \t\t\tg_critical(\"Invalid colorimetry %s\", colorimetry_str);\n>  \n> -\t\tstream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry);\n> +\t\tstream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry, transfer);\n>  \t}\n>  }\n>  \n> diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h\n> index cab1c814..4978987c 100644\n> --- a/src/gstreamer/gstlibcamera-utils.h\n> +++ b/src/gstreamer/gstlibcamera-utils.h\n> @@ -16,9 +16,10 @@\n>  #include <gst/video/video.h>\n>  \n>  GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats);\n> -GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg);\n> +GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg,\n> +\t\t\t\t\t\t    GstVideoTransferFunction transfer);\n>  void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg,\n> -\t\t\t\t\t      GstCaps *caps);\n> +\t\t\t\t\t      GstCaps *caps, GstVideoTransferFunction *transfer);\n>  void gst_libcamera_get_framerate_from_caps(GstCaps *caps, GstStructure *element_caps);\n>  void gst_libcamera_clamp_and_set_frameduration(libcamera::ControlList &controls,\n>  \t\t\t\t\t       const libcamera::ControlInfoMap &camera_controls,\n> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> index 8efa25f4..0f0d501e 100644\n> --- a/src/gstreamer/gstlibcamerasrc.cpp\n> +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> @@ -433,12 +433,14 @@ static bool\n>  gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n>  {\n>  \tGstLibcameraSrcState *state = self->state;\n> +\tGstVideoTransferFunction transfer[state->srcpads_.size()];\n>  \n>  \tg_autoptr(GstStructure) element_caps = gst_structure_new_empty(\"caps\");\n>  \n>  \tfor (gsize i = 0; i < state->srcpads_.size(); i++) {\n>  \t\tGstPad *srcpad = state->srcpads_[i];\n>  \t\tStreamConfiguration &stream_cfg = state->config_->at(i);\n> +\t\ttransfer[i] = GST_VIDEO_TRANSFER_UNKNOWN;\n>  \n>  \t\t/* Retrieve the supported caps. */\n>  \t\tg_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats());\n> @@ -448,7 +450,7 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n>  \n>  \t\t/* Fixate caps and configure the stream. */\n>  \t\tcaps = gst_caps_make_writable(caps);\n> -\t\tgst_libcamera_configure_stream_from_caps(stream_cfg, caps);\n> +\t\tgst_libcamera_configure_stream_from_caps(stream_cfg, caps, &transfer[i]);\n>  \t\tgst_libcamera_get_framerate_from_caps(caps, element_caps);\n>  \t}\n>  \n> @@ -476,7 +478,7 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n>  \t\tGstPad *srcpad = state->srcpads_[i];\n>  \t\tconst StreamConfiguration &stream_cfg = state->config_->at(i);\n>  \n> -\t\tg_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg);\n> +\t\tg_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg, transfer[i]);\n>  \t\tgst_libcamera_framerate_to_caps(caps, element_caps);\n>  \n>  \t\tif (!gst_pad_push_event(srcpad, gst_event_new_caps(caps)))","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 10438C32EA\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 13 Dec 2024 18:23:59 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CAEBE67EFC;\n\tFri, 13 Dec 2024 19:23:57 +0100 (CET)","from mail-qv1-xf33.google.com (mail-qv1-xf33.google.com\n\t[IPv6:2607:f8b0:4864:20::f33])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B8A866189C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Dec 2024 19:23:56 +0100 (CET)","by mail-qv1-xf33.google.com with SMTP id\n\t6a1803df08f44-6d8a3e99e32so17721486d6.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 13 Dec 2024 10:23:56 -0800 (PST)","from nicolas-tpx395.localdomain ([2606:6d00:15:862e::7a9])\n\tby smtp.gmail.com with ESMTPSA id\n\t6a1803df08f44-6d92f7c2bc1sm37108826d6.83.2024.12.13.10.23.55\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 13 Dec 2024 10:23:55 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=ndufresne-ca.20230601.gappssmtp.com\n\theader.i=@ndufresne-ca.20230601.gappssmtp.com\n\theader.b=\"Zf0KM6nH\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ndufresne-ca.20230601.gappssmtp.com; s=20230601; t=1734114236;\n\tx=1734719036; darn=lists.libcamera.org; \n\th=mime-version:user-agent:content-transfer-encoding:references\n\t:in-reply-to:date:cc:to:from:subject:message-id:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=6CCPPgJJk46xtk76N2XniXyxdnWQaDJGRbpqqVfpNrg=;\n\tb=Zf0KM6nHf5/qqSGNTlXJaC+PKTiTKqVl7/bqqxGTDpyzSV7QZRrd2CEKFrQCOqVBH/\n\t4cVjvwqAmQMBaOZ4ifc/IX6oxEbL+yZj3/9iFXtOs5Dbmro3HmTJnLYyg83BRKZCgbm4\n\tTktoMHLXW0hktj0VyVUZS5DNmk8yhgSbjf/fwR0jbxJuiOwrv/+2iu4nep9hUMiNzqZO\n\taekaJB9kbufB7nBdKII7qW5MFD8QuEseY1sWcnZFlpppMuSMVZrMmzxsO4SNj5vGPtjo\n\tyBO7ZCMBeZdH1c8KkNrEdKKq8Vztyyq3aBc60tKFpy+SdpQNuGfJzouQ7VRUgcnyTVzr\n\t6lhQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1734114236; x=1734719036;\n\th=mime-version:user-agent:content-transfer-encoding:references\n\t:in-reply-to:date:cc:to:from:subject:message-id:x-gm-message-state\n\t:from:to:cc:subject:date:message-id:reply-to;\n\tbh=6CCPPgJJk46xtk76N2XniXyxdnWQaDJGRbpqqVfpNrg=;\n\tb=OJdSZiUgzjtF9w2O5qmCGSaojK1A4VKShO34MxOC2ZhY6TVo03g0s/GCvYJqzaxEYL\n\tLUZaYxDOmfZ1o++GskGcm4z9ZkuNoVBFDcY0u7z8+ceAQqix2A9nKo790/32CS7cYd8L\n\tYOmS4bgmFYlpdki0RJSg6X8tbhTeQCwtZ7a1N+i/RNVUogRahN7Rb72GKMYeHxf/AS8Z\n\t+mun2H4JYBvN95bc8eLzoJXZ/kZQOZjyvR83g+aC7emgrqBqkBLvwyNlBfaRnvK2zaf7\n\tjFwSmBa8ZnTgO700jW4Z8LgRfgK8CQilDJdbggvBKQVy3L352cIzghombh3tF9V1UXqm\n\t7vkQ==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCW74dVqtJcYEhCUXZL1jPToFcNX4EY6gAlNjf/tgyCbCI0guMrNjR1O1ii8ziTa7/yUXUX8gh3R2O99frFO4kY=@lists.libcamera.org","X-Gm-Message-State":"AOJu0YyaUv4ec1z7+gBBhxHaX2Ez/3cA5YaO/Z5QS5TlalNreewRmJAY\n\t4rgcLAi7Scj9n8GDB33LCoCXnKOK7UWjfyy2rB4qvILTPgEjWgHEs8bbyACUq4Y=","X-Gm-Gg":"ASbGncsqKnAGGOARbxhyEDubVFQ79OVzx6Ct0fChZXomoKj2I9B3QRppFzxPRxPgmgZ\n\tsyaQht7XfRwYjmYnocfDdTR+0U5VMl6IM9bKRBp2RjxGatEbdtC82VAu1cO3aCMo0dnW/pV4m9P\n\tCKfPENdRFOON2TdXaIebcSCIXdyNm3zDsgJx466Ad11I1cHOm0kIxqPJ4CTccYVF3kRJgOY6Mev\n\tSWIFMgXXC4C/QxbMgm5XHg7fjBtmlC4LcNyzOL9hRSSMGYfql4EM0ExUQ==","X-Google-Smtp-Source":"AGHT+IFi3b+6dctPoH2WHra4E9IOVy/sG9Ns9dtffv2ybhxSSwX19xmK2gNcsECM01Mj+3efLYJ2MQ==","X-Received":"by 2002:a05:6214:21a9:b0:6d4:1e43:f395 with SMTP id\n\t6a1803df08f44-6dc8ca92c49mr66088416d6.24.1734114235641; \n\tFri, 13 Dec 2024 10:23:55 -0800 (PST)","Message-ID":"<9f9100544b024594ee3c9baa5173fc0f9cd912cd.camel@ndufresne.ca>","Subject":"Re: [PATCH v2] gstreamer: keep same transfer with that in\n\tnegotiated caps","From":"Nicolas Dufresne <nicolas@ndufresne.ca>","To":"Hou Qi <qi.hou@nxp.com>, libcamera-devel@lists.libcamera.org","Cc":"jared.hu@nxp.com, julien.vuillaumier@nxp.com","Date":"Fri, 13 Dec 2024 13:23:54 -0500","In-Reply-To":"<20241213060319.2877936-1-qi.hou@nxp.com>","References":"<20241213060319.2877936-1-qi.hou@nxp.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","User-Agent":"Evolution 3.54.2 (3.54.2-1.fc41) ","MIME-Version":"1.0","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":32724,"web_url":"https://patchwork.libcamera.org/comment/32724/","msgid":"<20241215140428.GD25852@pendragon.ideasonboard.com>","date":"2024-12-15T14:04:28","subject":"Re: [PATCH v2] gstreamer: keep same transfer with that in negotiated\n\tcaps","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Dec 13, 2024 at 01:23:54PM -0500, Nicolas Dufresne wrote:\n> Hi,\n> \n> Le vendredi 13 décembre 2024 à 15:03 +0900, Hou Qi a écrit :\n> > The conversions back and forth between GStreamer colorimetry and\n> > libcamera color space are not invariant for the bt601 colorimetry.\n> > The reason is that Rec709 transfer function defined in GStreamer\n> > as GST_VIDEO_TRANSFER_BT709 (5), is to be replaced by its alias\n> > GST_VIDEO_TRANSFER_BT601 (16) only for the case of bt601 (aka 2:4:16:4)\n> > colorimetry - see [1].\n> > \n> > Currently the composition of the GStreamer/libcamera conversions:\n> > colorimetry_from_colorspace (colorspace_from_colorimetry (bt601))\n> > returns 2:4:5:4 instead of the expected 2:4:16:4 (bt601). This\n> > causes negotiation error when the downstream element explicitly\n> > expects bt601 colorimetry.\n> > \n> > Minimal example to reproduce the issue is with a pipeline handler\n> > that do not set the optional color space in the stream configuration,\n> > for instance vimc or imx8-isi:\n> > export LIBCAMERA_PIPELINES_MATCH_LIST=\"vimc,imx8-isi\"\n> > gst-launch-1.0 -v libcamerasrc ! video/x-raw,colorimetry=bt601 ! fakesink\n> > \n> > Above pipeline fails to start. This change memorizes downstream required\n> > transfer function when mapped libcamera transfer is Rec709 in\n> > gst_libcamera_configure_stream_from_caps(), and restores the transfer\n> > function in gst_libcamera_stream_formats_to_caps().\n> > \n> > [1] https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/724\n> > \n> > Bug: https://bugs.libcamera.org/show_bug.cgi?id=150\n> > Signed-off-by: Hou Qi <qi.hou@nxp.com>\n> \n> Looks good now. We could have improved the naming for the variable \"transfer\",\n> but can't think of a good suggestion, and it does not change anything to the\n> logic which I believe is right.\n\nI have a few extra comments, please see below.\n\n> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n> \n> Thanks for you work,\n> Nicolas\n> \n> > ---\n> >  src/gstreamer/gstlibcamera-utils.cpp | 19 +++++++++++--------\n> >  src/gstreamer/gstlibcamera-utils.h   |  5 +++--\n> >  src/gstreamer/gstlibcamerasrc.cpp    |  6 ++++--\n> >  3 files changed, 18 insertions(+), 12 deletions(-)\n> > \n> > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp\n> > index 732987ef..23756b15 100644\n> > --- a/src/gstreamer/gstlibcamera-utils.cpp\n> > +++ b/src/gstreamer/gstlibcamera-utils.cpp\n> > @@ -85,7 +85,7 @@ static struct {\n> >  };\n> >  \n> >  static GstVideoColorimetry\n> > -colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> > +colorimetry_from_colorspace(const ColorSpace &colorSpace, GstVideoTransferFunction transfer)\n> >  {\n> >  \tGstVideoColorimetry colorimetry;\n> >  \n> > @@ -113,6 +113,8 @@ colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> >  \t\tbreak;\n> >  \tcase ColorSpace::TransferFunction::Rec709:\n> >  \t\tcolorimetry.transfer = GST_VIDEO_TRANSFER_BT709;\n> > +\t\tif (transfer)\n\nI'd write\n\n\t\tif (transfer != GST_VIDEO_TRANSFER_UNKNOWN)\n\nto avoid depending on the fact that GST_VIDEO_TRANSFER_UNKNOWN == 0.\n\n> > +\t\t\tcolorimetry.transfer = transfer;\n> >  \t\tbreak;\n> >  \t}\n> >  \n> > @@ -144,7 +146,7 @@ colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> >  }\n> >  \n> >  static std::optional<ColorSpace>\n> > -colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry)\n> > +colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry, GstVideoTransferFunction *transfer)\n\nThis should be wrapped:\n\ncolorspace_from_colorimetry(const GstVideoColorimetry &colorimetry,\n\t\t\t    GstVideoTransferFunction *transfer)\n\nNo need for a v3, I'll make those changes when applying.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> >  {\n> >  \tstd::optional<ColorSpace> colorspace = ColorSpace::Raw;\n> >  \n> > @@ -188,6 +190,7 @@ colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry)\n> >  \tcase GST_VIDEO_TRANSFER_BT2020_12:\n> >  \tcase GST_VIDEO_TRANSFER_BT709:\n> >  \t\tcolorspace->transferFunction = ColorSpace::TransferFunction::Rec709;\n> > +\t\t*transfer = colorimetry.transfer;\n> >  \t\tbreak;\n> >  \tdefault:\n> >  \t\tGST_WARNING(\"Colorimetry transfer function %d not mapped in gstlibcamera\",\n> > @@ -379,7 +382,8 @@ gst_libcamera_stream_formats_to_caps(const StreamFormats &formats)\n> >  }\n> >  \n> >  GstCaps *\n> > -gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg)\n> > +gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg,\n> > +\t\t\t\t\t   GstVideoTransferFunction transfer)\n> >  {\n> >  \tGstCaps *caps = gst_caps_new_empty();\n> >  \tGstStructure *s = bare_structure_from_format(stream_cfg.pixelFormat);\n> > @@ -390,7 +394,7 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg\n> >  \t\t\t  nullptr);\n> >  \n> >  \tif (stream_cfg.colorSpace) {\n> > -\t\tGstVideoColorimetry colorimetry = colorimetry_from_colorspace(stream_cfg.colorSpace.value());\n> > +\t\tGstVideoColorimetry colorimetry = colorimetry_from_colorspace(stream_cfg.colorSpace.value(), transfer);\n> >  \t\tg_autofree gchar *colorimetry_str = gst_video_colorimetry_to_string(&colorimetry);\n> >  \n> >  \t\tif (colorimetry_str)\n> > @@ -405,9 +409,8 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg\n> >  \treturn caps;\n> >  }\n> >  \n> > -void\n> > -gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> > -\t\t\t\t\t GstCaps *caps)\n> > +void gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> > +\t\t\t\t\t      GstCaps *caps, GstVideoTransferFunction *transfer)\n> >  {\n> >  \tGstVideoFormat gst_format = pixel_format_to_gst_format(stream_cfg.pixelFormat);\n> >  \tguint i;\n> > @@ -495,7 +498,7 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> >  \t\tif (!gst_video_colorimetry_from_string(&colorimetry, colorimetry_str))\n> >  \t\t\tg_critical(\"Invalid colorimetry %s\", colorimetry_str);\n> >  \n> > -\t\tstream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry);\n> > +\t\tstream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry, transfer);\n> >  \t}\n> >  }\n> >  \n> > diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h\n> > index cab1c814..4978987c 100644\n> > --- a/src/gstreamer/gstlibcamera-utils.h\n> > +++ b/src/gstreamer/gstlibcamera-utils.h\n> > @@ -16,9 +16,10 @@\n> >  #include <gst/video/video.h>\n> >  \n> >  GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats);\n> > -GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg);\n> > +GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg,\n> > +\t\t\t\t\t\t    GstVideoTransferFunction transfer);\n> >  void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg,\n> > -\t\t\t\t\t      GstCaps *caps);\n> > +\t\t\t\t\t      GstCaps *caps, GstVideoTransferFunction *transfer);\n> >  void gst_libcamera_get_framerate_from_caps(GstCaps *caps, GstStructure *element_caps);\n> >  void gst_libcamera_clamp_and_set_frameduration(libcamera::ControlList &controls,\n> >  \t\t\t\t\t       const libcamera::ControlInfoMap &camera_controls,\n> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> > index 8efa25f4..0f0d501e 100644\n> > --- a/src/gstreamer/gstlibcamerasrc.cpp\n> > +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> > @@ -433,12 +433,14 @@ static bool\n> >  gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n> >  {\n> >  \tGstLibcameraSrcState *state = self->state;\n> > +\tGstVideoTransferFunction transfer[state->srcpads_.size()];\n> >  \n> >  \tg_autoptr(GstStructure) element_caps = gst_structure_new_empty(\"caps\");\n> >  \n> >  \tfor (gsize i = 0; i < state->srcpads_.size(); i++) {\n> >  \t\tGstPad *srcpad = state->srcpads_[i];\n> >  \t\tStreamConfiguration &stream_cfg = state->config_->at(i);\n> > +\t\ttransfer[i] = GST_VIDEO_TRANSFER_UNKNOWN;\n> >  \n> >  \t\t/* Retrieve the supported caps. */\n> >  \t\tg_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats());\n> > @@ -448,7 +450,7 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n> >  \n> >  \t\t/* Fixate caps and configure the stream. */\n> >  \t\tcaps = gst_caps_make_writable(caps);\n> > -\t\tgst_libcamera_configure_stream_from_caps(stream_cfg, caps);\n> > +\t\tgst_libcamera_configure_stream_from_caps(stream_cfg, caps, &transfer[i]);\n> >  \t\tgst_libcamera_get_framerate_from_caps(caps, element_caps);\n> >  \t}\n> >  \n> > @@ -476,7 +478,7 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n> >  \t\tGstPad *srcpad = state->srcpads_[i];\n> >  \t\tconst StreamConfiguration &stream_cfg = state->config_->at(i);\n> >  \n> > -\t\tg_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg);\n> > +\t\tg_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg, transfer[i]);\n> >  \t\tgst_libcamera_framerate_to_caps(caps, element_caps);\n> >  \n> >  \t\tif (!gst_pad_push_event(srcpad, gst_event_new_caps(caps)))","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 656B4C32F6\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 15 Dec 2024 14:04:59 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9257F67EFC;\n\tSun, 15 Dec 2024 15:04:58 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C2D567EEE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 15 Dec 2024 15:04:45 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5A4B799F;\n\tSun, 15 Dec 2024 15:04:09 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"wel816jB\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1734271449;\n\tbh=cQ95mtcoE+hvdTujyBbCnSgD+CQiMjYrggKax1eOlAc=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=wel816jBqDEyGQXb7gEEW7niPIW5B5MkDRkaRO7CHAb+cQqoWFI82UTWMiAaFL44t\n\tpmFRNGNtfKx1A/y+MJtCHjgOyJbxk4POoQor4snF7B3Lhmd1WswXd+M6AqlRPqNU5k\n\tqpoSXKjGVlWZ0OTT3kkob0Am60uhsmtlQM6rx3Qw=","Date":"Sun, 15 Dec 2024 16:04:28 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Nicolas Dufresne <nicolas@ndufresne.ca>","Cc":"Hou Qi <qi.hou@nxp.com>, libcamera-devel@lists.libcamera.org,\n\tjared.hu@nxp.com, julien.vuillaumier@nxp.com","Subject":"Re: [PATCH v2] gstreamer: keep same transfer with that in negotiated\n\tcaps","Message-ID":"<20241215140428.GD25852@pendragon.ideasonboard.com>","References":"<20241213060319.2877936-1-qi.hou@nxp.com>\n\t<9f9100544b024594ee3c9baa5173fc0f9cd912cd.camel@ndufresne.ca>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<9f9100544b024594ee3c9baa5173fc0f9cd912cd.camel@ndufresne.ca>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":32725,"web_url":"https://patchwork.libcamera.org/comment/32725/","msgid":"<20241215150910.GE25852@pendragon.ideasonboard.com>","date":"2024-12-15T15:09:10","subject":"Re: [PATCH v2] gstreamer: keep same transfer with that in negotiated\n\tcaps","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"I'm afraid this patch breaks compilation with clang 18 and 19 :-(\n\n../../src/gstreamer/gstlibcamerasrc.cpp:436:36: error: variable length arrays in C++ are a Clang extension [-Werror,-Wvla-cxx-extension]\n  436 |         GstVideoTransferFunction transfer[state->srcpads_.size()];\n      |                                           ^~~~~~~~~~~~~~~~~~~~~~\n../../src/gstreamer/gstlibcamerasrc.cpp:436:36: note: read of non-constexpr variable 'state' is not allowed in a constant expression\n../../src/gstreamer/gstlibcamerasrc.cpp:435:24: note: declared here\n  435 |         GstLibcameraSrcState *state = self->state;\n      |\n\nI've now enabled build tests with clang 19 in CI, see\nhttps://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1330267 for\na full test report.\n\nHou, could I ask you for a v3 that addresses those issues, as well as\nthe couple of comments below ?\n\nOn Sun, Dec 15, 2024 at 04:04:28PM +0200, Laurent Pinchart wrote:\n> On Fri, Dec 13, 2024 at 01:23:54PM -0500, Nicolas Dufresne wrote:\n> > Le vendredi 13 décembre 2024 à 15:03 +0900, Hou Qi a écrit :\n> > > The conversions back and forth between GStreamer colorimetry and\n> > > libcamera color space are not invariant for the bt601 colorimetry.\n> > > The reason is that Rec709 transfer function defined in GStreamer\n> > > as GST_VIDEO_TRANSFER_BT709 (5), is to be replaced by its alias\n> > > GST_VIDEO_TRANSFER_BT601 (16) only for the case of bt601 (aka 2:4:16:4)\n> > > colorimetry - see [1].\n> > > \n> > > Currently the composition of the GStreamer/libcamera conversions:\n> > > colorimetry_from_colorspace (colorspace_from_colorimetry (bt601))\n> > > returns 2:4:5:4 instead of the expected 2:4:16:4 (bt601). This\n> > > causes negotiation error when the downstream element explicitly\n> > > expects bt601 colorimetry.\n> > > \n> > > Minimal example to reproduce the issue is with a pipeline handler\n> > > that do not set the optional color space in the stream configuration,\n> > > for instance vimc or imx8-isi:\n> > > export LIBCAMERA_PIPELINES_MATCH_LIST=\"vimc,imx8-isi\"\n> > > gst-launch-1.0 -v libcamerasrc ! video/x-raw,colorimetry=bt601 ! fakesink\n> > > \n> > > Above pipeline fails to start. This change memorizes downstream required\n> > > transfer function when mapped libcamera transfer is Rec709 in\n> > > gst_libcamera_configure_stream_from_caps(), and restores the transfer\n> > > function in gst_libcamera_stream_formats_to_caps().\n> > > \n> > > [1] https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/724\n> > > \n> > > Bug: https://bugs.libcamera.org/show_bug.cgi?id=150\n> > > Signed-off-by: Hou Qi <qi.hou@nxp.com>\n> > \n> > Looks good now. We could have improved the naming for the variable \"transfer\",\n> > but can't think of a good suggestion, and it does not change anything to the\n> > logic which I believe is right.\n> \n> I have a few extra comments, please see below.\n> \n> > Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n> > \n> > Thanks for you work,\n> > Nicolas\n> > \n> > > ---\n> > >  src/gstreamer/gstlibcamera-utils.cpp | 19 +++++++++++--------\n> > >  src/gstreamer/gstlibcamera-utils.h   |  5 +++--\n> > >  src/gstreamer/gstlibcamerasrc.cpp    |  6 ++++--\n> > >  3 files changed, 18 insertions(+), 12 deletions(-)\n> > > \n> > > diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp\n> > > index 732987ef..23756b15 100644\n> > > --- a/src/gstreamer/gstlibcamera-utils.cpp\n> > > +++ b/src/gstreamer/gstlibcamera-utils.cpp\n> > > @@ -85,7 +85,7 @@ static struct {\n> > >  };\n> > >  \n> > >  static GstVideoColorimetry\n> > > -colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> > > +colorimetry_from_colorspace(const ColorSpace &colorSpace, GstVideoTransferFunction transfer)\n> > >  {\n> > >  \tGstVideoColorimetry colorimetry;\n> > >  \n> > > @@ -113,6 +113,8 @@ colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> > >  \t\tbreak;\n> > >  \tcase ColorSpace::TransferFunction::Rec709:\n> > >  \t\tcolorimetry.transfer = GST_VIDEO_TRANSFER_BT709;\n> > > +\t\tif (transfer)\n> \n> I'd write\n> \n> \t\tif (transfer != GST_VIDEO_TRANSFER_UNKNOWN)\n> \n> to avoid depending on the fact that GST_VIDEO_TRANSFER_UNKNOWN == 0.\n> \n> > > +\t\t\tcolorimetry.transfer = transfer;\n> > >  \t\tbreak;\n> > >  \t}\n> > >  \n> > > @@ -144,7 +146,7 @@ colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> > >  }\n> > >  \n> > >  static std::optional<ColorSpace>\n> > > -colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry)\n> > > +colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry, GstVideoTransferFunction *transfer)\n> \n> This should be wrapped:\n> \n> colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry,\n> \t\t\t    GstVideoTransferFunction *transfer)\n> \n> No need for a v3, I'll make those changes when applying.\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> > >  {\n> > >  \tstd::optional<ColorSpace> colorspace = ColorSpace::Raw;\n> > >  \n> > > @@ -188,6 +190,7 @@ colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry)\n> > >  \tcase GST_VIDEO_TRANSFER_BT2020_12:\n> > >  \tcase GST_VIDEO_TRANSFER_BT709:\n> > >  \t\tcolorspace->transferFunction = ColorSpace::TransferFunction::Rec709;\n> > > +\t\t*transfer = colorimetry.transfer;\n> > >  \t\tbreak;\n> > >  \tdefault:\n> > >  \t\tGST_WARNING(\"Colorimetry transfer function %d not mapped in gstlibcamera\",\n> > > @@ -379,7 +382,8 @@ gst_libcamera_stream_formats_to_caps(const StreamFormats &formats)\n> > >  }\n> > >  \n> > >  GstCaps *\n> > > -gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg)\n> > > +gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg,\n> > > +\t\t\t\t\t   GstVideoTransferFunction transfer)\n> > >  {\n> > >  \tGstCaps *caps = gst_caps_new_empty();\n> > >  \tGstStructure *s = bare_structure_from_format(stream_cfg.pixelFormat);\n> > > @@ -390,7 +394,7 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg\n> > >  \t\t\t  nullptr);\n> > >  \n> > >  \tif (stream_cfg.colorSpace) {\n> > > -\t\tGstVideoColorimetry colorimetry = colorimetry_from_colorspace(stream_cfg.colorSpace.value());\n> > > +\t\tGstVideoColorimetry colorimetry = colorimetry_from_colorspace(stream_cfg.colorSpace.value(), transfer);\n> > >  \t\tg_autofree gchar *colorimetry_str = gst_video_colorimetry_to_string(&colorimetry);\n> > >  \n> > >  \t\tif (colorimetry_str)\n> > > @@ -405,9 +409,8 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg\n> > >  \treturn caps;\n> > >  }\n> > >  \n> > > -void\n> > > -gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> > > -\t\t\t\t\t GstCaps *caps)\n> > > +void gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> > > +\t\t\t\t\t      GstCaps *caps, GstVideoTransferFunction *transfer)\n> > >  {\n> > >  \tGstVideoFormat gst_format = pixel_format_to_gst_format(stream_cfg.pixelFormat);\n> > >  \tguint i;\n> > > @@ -495,7 +498,7 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> > >  \t\tif (!gst_video_colorimetry_from_string(&colorimetry, colorimetry_str))\n> > >  \t\t\tg_critical(\"Invalid colorimetry %s\", colorimetry_str);\n> > >  \n> > > -\t\tstream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry);\n> > > +\t\tstream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry, transfer);\n> > >  \t}\n> > >  }\n> > >  \n> > > diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h\n> > > index cab1c814..4978987c 100644\n> > > --- a/src/gstreamer/gstlibcamera-utils.h\n> > > +++ b/src/gstreamer/gstlibcamera-utils.h\n> > > @@ -16,9 +16,10 @@\n> > >  #include <gst/video/video.h>\n> > >  \n> > >  GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats);\n> > > -GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg);\n> > > +GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg,\n> > > +\t\t\t\t\t\t    GstVideoTransferFunction transfer);\n> > >  void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg,\n> > > -\t\t\t\t\t      GstCaps *caps);\n> > > +\t\t\t\t\t      GstCaps *caps, GstVideoTransferFunction *transfer);\n> > >  void gst_libcamera_get_framerate_from_caps(GstCaps *caps, GstStructure *element_caps);\n> > >  void gst_libcamera_clamp_and_set_frameduration(libcamera::ControlList &controls,\n> > >  \t\t\t\t\t       const libcamera::ControlInfoMap &camera_controls,\n> > > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> > > index 8efa25f4..0f0d501e 100644\n> > > --- a/src/gstreamer/gstlibcamerasrc.cpp\n> > > +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> > > @@ -433,12 +433,14 @@ static bool\n> > >  gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n> > >  {\n> > >  \tGstLibcameraSrcState *state = self->state;\n> > > +\tGstVideoTransferFunction transfer[state->srcpads_.size()];\n> > >  \n> > >  \tg_autoptr(GstStructure) element_caps = gst_structure_new_empty(\"caps\");\n> > >  \n> > >  \tfor (gsize i = 0; i < state->srcpads_.size(); i++) {\n> > >  \t\tGstPad *srcpad = state->srcpads_[i];\n> > >  \t\tStreamConfiguration &stream_cfg = state->config_->at(i);\n> > > +\t\ttransfer[i] = GST_VIDEO_TRANSFER_UNKNOWN;\n> > >  \n> > >  \t\t/* Retrieve the supported caps. */\n> > >  \t\tg_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats());\n> > > @@ -448,7 +450,7 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n> > >  \n> > >  \t\t/* Fixate caps and configure the stream. */\n> > >  \t\tcaps = gst_caps_make_writable(caps);\n> > > -\t\tgst_libcamera_configure_stream_from_caps(stream_cfg, caps);\n> > > +\t\tgst_libcamera_configure_stream_from_caps(stream_cfg, caps, &transfer[i]);\n> > >  \t\tgst_libcamera_get_framerate_from_caps(caps, element_caps);\n> > >  \t}\n> > >  \n> > > @@ -476,7 +478,7 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n> > >  \t\tGstPad *srcpad = state->srcpads_[i];\n> > >  \t\tconst StreamConfiguration &stream_cfg = state->config_->at(i);\n> > >  \n> > > -\t\tg_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg);\n> > > +\t\tg_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg, transfer[i]);\n> > >  \t\tgst_libcamera_framerate_to_caps(caps, element_caps);\n> > >  \n> > >  \t\tif (!gst_pad_push_event(srcpad, gst_event_new_caps(caps)))","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id A8A4CC32EA\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 15 Dec 2024 15:09:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BB4ED67F00;\n\tSun, 15 Dec 2024 16:09:27 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id AAF2A67EEE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 15 Dec 2024 16:09:26 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 78E8BA57;\n\tSun, 15 Dec 2024 16:08:50 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ikGHEHAr\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1734275330;\n\tbh=tLjDYNc9VR0eVKiWVkvPFSXeVkrwXZOYEjrutjaGQ8Y=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=ikGHEHArDWIAxxNoG8a9bR5FiDMXlbsa9/8TJGtvAGwLjIQOTZJ2cpkCzyeq5Ku3K\n\tdX2su6joMHcqC+hqaqP52hLrCvJc8kr0IT2FVSCLRLmsndMiNPjhADb1dVxy+8w5HW\n\tlYJOoKyc0WEbsqGFDaT9MhjSHG3dQfR6cSCd4Nfw=","Date":"Sun, 15 Dec 2024 17:09:10 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Nicolas Dufresne <nicolas@ndufresne.ca>","Cc":"Hou Qi <qi.hou@nxp.com>, libcamera-devel@lists.libcamera.org,\n\tjared.hu@nxp.com, julien.vuillaumier@nxp.com","Subject":"Re: [PATCH v2] gstreamer: keep same transfer with that in negotiated\n\tcaps","Message-ID":"<20241215150910.GE25852@pendragon.ideasonboard.com>","References":"<20241213060319.2877936-1-qi.hou@nxp.com>\n\t<9f9100544b024594ee3c9baa5173fc0f9cd912cd.camel@ndufresne.ca>\n\t<20241215140428.GD25852@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20241215140428.GD25852@pendragon.ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":32746,"web_url":"https://patchwork.libcamera.org/comment/32746/","msgid":"<PAXPR04MB8285D71FA1DA82AAD643E070973B2@PAXPR04MB8285.eurprd04.prod.outlook.com>","date":"2024-12-16T03:16:19","subject":"RE: [EXT] Re: [PATCH v2] gstreamer: keep same transfer with that in\n\tnegotiated caps","submitter":{"id":195,"url":"https://patchwork.libcamera.org/api/people/195/","name":"Qi Hou","email":"qi.hou@nxp.com"},"content":"Hi Laurent Pinchart,\n\nI have sent out v3. Can you help check if build issue is gone? Thanks.\n\nRegards,\nQi Hou\n\n-----Original Message-----\nFrom: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nSent: 2024年12月15日 23:09\nTo: Nicolas Dufresne <nicolas@ndufresne.ca>\nCc: Qi Hou <qi.hou@nxp.com>; libcamera-devel@lists.libcamera.org; Jared Hu <jared.hu@nxp.com>; Julien Vuillaumier <julien.vuillaumier@nxp.com>\nSubject: [EXT] Re: [PATCH v2] gstreamer: keep same transfer with that in negotiated caps\n\nCaution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button\n\n\nI'm afraid this patch breaks compilation with clang 18 and 19 :-(\n\n../../src/gstreamer/gstlibcamerasrc.cpp:436:36: error: variable length arrays in C++ are a Clang extension [-Werror,-Wvla-cxx-extension]\n  436 |         GstVideoTransferFunction transfer[state->srcpads_.size()];\n      |                                           ^~~~~~~~~~~~~~~~~~~~~~\n../../src/gstreamer/gstlibcamerasrc.cpp:436:36: note: read of non-constexpr variable 'state' is not allowed in a constant expression\n../../src/gstreamer/gstlibcamerasrc.cpp:435:24: note: declared here\n  435 |         GstLibcameraSrcState *state = self->state;\n      |\n\nI've now enabled build tests with clang 19 in CI, see\nhttps://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1330267 for a full test report.\n\nHou, could I ask you for a v3 that addresses those issues, as well as the couple of comments below ?\n\nOn Sun, Dec 15, 2024 at 04:04:28PM +0200, Laurent Pinchart wrote:\n> On Fri, Dec 13, 2024 at 01:23:54PM -0500, Nicolas Dufresne wrote:\n> > Le vendredi 13 décembre 2024 à 15:03 +0900, Hou Qi a écrit :\n> > > The conversions back and forth between GStreamer colorimetry and\n> > > libcamera color space are not invariant for the bt601 colorimetry.\n> > > The reason is that Rec709 transfer function defined in GStreamer\n> > > as GST_VIDEO_TRANSFER_BT709 (5), is to be replaced by its alias\n> > > GST_VIDEO_TRANSFER_BT601 (16) only for the case of bt601 (aka\n> > > 2:4:16:4) colorimetry - see [1].\n> > >\n> > > Currently the composition of the GStreamer/libcamera conversions:\n> > > colorimetry_from_colorspace (colorspace_from_colorimetry (bt601))\n> > > returns 2:4:5:4 instead of the expected 2:4:16:4 (bt601). This\n> > > causes negotiation error when the downstream element explicitly\n> > > expects bt601 colorimetry.\n> > >\n> > > Minimal example to reproduce the issue is with a pipeline handler\n> > > that do not set the optional color space in the stream\n> > > configuration, for instance vimc or imx8-isi:\n> > > export LIBCAMERA_PIPELINES_MATCH_LIST=\"vimc,imx8-isi\"\n> > > gst-launch-1.0 -v libcamerasrc ! video/x-raw,colorimetry=bt601 !\n> > > fakesink\n> > >\n> > > Above pipeline fails to start. This change memorizes downstream\n> > > required transfer function when mapped libcamera transfer is\n> > > Rec709 in gst_libcamera_configure_stream_from_caps(), and restores\n> > > the transfer function in gst_libcamera_stream_formats_to_caps().\n> > >\n> > > [1]\n> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2F\n> > > gitlab.freedesktop.org%2Fgstreamer%2Fgst-plugins-base%2F-%2Fmerge_\n> > > requests%2F724&data=05%7C02%7Cqi.hou%40nxp.com%7Cf5b9b27b3aeb4b700\n> > > 78908dd1d1a779a%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63869\n> > > 8721704182571%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYi\n> > > OiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7\n> > > C0%7C%7C%7C&sdata=4bYgndaOutdSPuXKFFFpy4P9gtZQet1R12rtYvCO3wE%3D&r\n> > > eserved=0\n> > >\n> > > Bug:\n> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2F\n> > > bugs.libcamera.org%2Fshow_bug.cgi%3Fid%3D150&data=05%7C02%7Cqi.hou\n> > > %40nxp.com%7Cf5b9b27b3aeb4b70078908dd1d1a779a%7C686ea1d3bc2b4c6fa9\n> > > 2cd99c5c301635%7C0%7C0%7C638698721704200278%7CUnknown%7CTWFpbGZsb3\n> > > d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFO\n> > > IjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=R29Q2iwz0%2Bnt9R4M\n> > > 4rc0aDzTMOhIuppPHNDcLs87WAo%3D&reserved=0\n> > > Signed-off-by: Hou Qi <qi.hou@nxp.com>\n> >\n> > Looks good now. We could have improved the naming for the variable\n> > \"transfer\", but can't think of a good suggestion, and it does not\n> > change anything to the logic which I believe is right.\n>\n> I have a few extra comments, please see below.\n>\n> > Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n> >\n> > Thanks for you work,\n> > Nicolas\n> >\n> > > ---\n> > >  src/gstreamer/gstlibcamera-utils.cpp | 19 +++++++++++--------\n> > >  src/gstreamer/gstlibcamera-utils.h   |  5 +++--\n> > >  src/gstreamer/gstlibcamerasrc.cpp    |  6 ++++--\n> > >  3 files changed, 18 insertions(+), 12 deletions(-)\n> > >\n> > > diff --git a/src/gstreamer/gstlibcamera-utils.cpp\n> > > b/src/gstreamer/gstlibcamera-utils.cpp\n> > > index 732987ef..23756b15 100644\n> > > --- a/src/gstreamer/gstlibcamera-utils.cpp\n> > > +++ b/src/gstreamer/gstlibcamera-utils.cpp\n> > > @@ -85,7 +85,7 @@ static struct {\n> > >  };\n> > >\n> > >  static GstVideoColorimetry\n> > > -colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> > > +colorimetry_from_colorspace(const ColorSpace &colorSpace,\n> > > +GstVideoTransferFunction transfer)\n> > >  {\n> > >   GstVideoColorimetry colorimetry;\n> > >\n> > > @@ -113,6 +113,8 @@ colorimetry_from_colorspace(const ColorSpace &colorSpace)\n> > >           break;\n> > >   case ColorSpace::TransferFunction::Rec709:\n> > >           colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;\n> > > +         if (transfer)\n>\n> I'd write\n>\n>               if (transfer != GST_VIDEO_TRANSFER_UNKNOWN)\n>\n> to avoid depending on the fact that GST_VIDEO_TRANSFER_UNKNOWN == 0.\n>\n> > > +                 colorimetry.transfer = transfer;\n> > >           break;\n> > >   }\n> > >\n> > > @@ -144,7 +146,7 @@ colorimetry_from_colorspace(const ColorSpace\n> > > &colorSpace)  }\n> > >\n> > >  static std::optional<ColorSpace>\n> > > -colorspace_from_colorimetry(const GstVideoColorimetry\n> > > &colorimetry)\n> > > +colorspace_from_colorimetry(const GstVideoColorimetry\n> > > +&colorimetry, GstVideoTransferFunction *transfer)\n>\n> This should be wrapped:\n>\n> colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry,\n>                           GstVideoTransferFunction *transfer)\n>\n> No need for a v3, I'll make those changes when applying.\n>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n> > >  {\n> > >   std::optional<ColorSpace> colorspace = ColorSpace::Raw;\n> > >\n> > > @@ -188,6 +190,7 @@ colorspace_from_colorimetry(const GstVideoColorimetry &colorimetry)\n> > >   case GST_VIDEO_TRANSFER_BT2020_12:\n> > >   case GST_VIDEO_TRANSFER_BT709:\n> > >           colorspace->transferFunction =\n> > > ColorSpace::TransferFunction::Rec709;\n> > > +         *transfer = colorimetry.transfer;\n> > >           break;\n> > >   default:\n> > >           GST_WARNING(\"Colorimetry transfer function %d not mapped\n> > > in gstlibcamera\", @@ -379,7 +382,8 @@\n> > > gst_libcamera_stream_formats_to_caps(const StreamFormats &formats)\n> > > }\n> > >\n> > >  GstCaps *\n> > > -gst_libcamera_stream_configuration_to_caps(const\n> > > StreamConfiguration &stream_cfg)\n> > > +gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg,\n> > > +                                    GstVideoTransferFunction\n> > > +transfer)\n> > >  {\n> > >   GstCaps *caps = gst_caps_new_empty();\n> > >   GstStructure *s =\n> > > bare_structure_from_format(stream_cfg.pixelFormat);\n> > > @@ -390,7 +394,7 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg\n> > >                     nullptr);\n> > >\n> > >   if (stream_cfg.colorSpace) {\n> > > -         GstVideoColorimetry colorimetry = colorimetry_from_colorspace(stream_cfg.colorSpace.value());\n> > > +         GstVideoColorimetry colorimetry =\n> > > + colorimetry_from_colorspace(stream_cfg.colorSpace.value(),\n> > > + transfer);\n> > >           g_autofree gchar *colorimetry_str =\n> > > gst_video_colorimetry_to_string(&colorimetry);\n> > >\n> > >           if (colorimetry_str)\n> > > @@ -405,9 +409,8 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg\n> > >   return caps;\n> > >  }\n> > >\n> > > -void\n> > > -gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> > > -                                  GstCaps *caps)\n> > > +void gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> > > +                                       GstCaps *caps,\n> > > +GstVideoTransferFunction *transfer)\n> > >  {\n> > >   GstVideoFormat gst_format = pixel_format_to_gst_format(stream_cfg.pixelFormat);\n> > >   guint i;\n> > > @@ -495,7 +498,7 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n> > >           if (!gst_video_colorimetry_from_string(&colorimetry, colorimetry_str))\n> > >                   g_critical(\"Invalid colorimetry %s\",\n> > > colorimetry_str);\n> > >\n> > > -         stream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry);\n> > > +         stream_cfg.colorSpace =\n> > > + colorspace_from_colorimetry(colorimetry, transfer);\n> > >   }\n> > >  }\n> > >\n> > > diff --git a/src/gstreamer/gstlibcamera-utils.h\n> > > b/src/gstreamer/gstlibcamera-utils.h\n> > > index cab1c814..4978987c 100644\n> > > --- a/src/gstreamer/gstlibcamera-utils.h\n> > > +++ b/src/gstreamer/gstlibcamera-utils.h\n> > > @@ -16,9 +16,10 @@\n> > >  #include <gst/video/video.h>\n> > >\n> > >  GstCaps *gst_libcamera_stream_formats_to_caps(const\n> > > libcamera::StreamFormats &formats); -GstCaps\n> > > *gst_libcamera_stream_configuration_to_caps(const\n> > > libcamera::StreamConfiguration &stream_cfg);\n> > > +GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg,\n> > > +\n> > > +GstVideoTransferFunction transfer);\n> > >  void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg,\n> > > -                                       GstCaps *caps);\n> > > +                                       GstCaps *caps,\n> > > + GstVideoTransferFunction *transfer);\n> > >  void gst_libcamera_get_framerate_from_caps(GstCaps *caps,\n> > > GstStructure *element_caps);  void gst_libcamera_clamp_and_set_frameduration(libcamera::ControlList &controls,\n> > >                                          const\n> > > libcamera::ControlInfoMap &camera_controls, diff --git\n> > > a/src/gstreamer/gstlibcamerasrc.cpp\n> > > b/src/gstreamer/gstlibcamerasrc.cpp\n> > > index 8efa25f4..0f0d501e 100644\n> > > --- a/src/gstreamer/gstlibcamerasrc.cpp\n> > > +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> > > @@ -433,12 +433,14 @@ static bool\n> > >  gst_libcamera_src_negotiate(GstLibcameraSrc *self)  {\n> > >   GstLibcameraSrcState *state = self->state;\n> > > + GstVideoTransferFunction transfer[state->srcpads_.size()];\n> > >\n> > >   g_autoptr(GstStructure) element_caps = gst_structure_new_empty(\"caps\");\n> > >\n> > >   for (gsize i = 0; i < state->srcpads_.size(); i++) {\n> > >           GstPad *srcpad = state->srcpads_[i];\n> > >           StreamConfiguration &stream_cfg = state->config_->at(i);\n> > > +         transfer[i] = GST_VIDEO_TRANSFER_UNKNOWN;\n> > >\n> > >           /* Retrieve the supported caps. */\n> > >           g_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats());\n> > > @@ -448,7 +450,7 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n> > >\n> > >           /* Fixate caps and configure the stream. */\n> > >           caps = gst_caps_make_writable(caps);\n> > > -         gst_libcamera_configure_stream_from_caps(stream_cfg, caps);\n> > > +         gst_libcamera_configure_stream_from_caps(stream_cfg, caps, &transfer[i]);\n> > >           gst_libcamera_get_framerate_from_caps(caps, element_caps);\n> > >   }\n> > >\n> > > @@ -476,7 +478,7 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n> > >           GstPad *srcpad = state->srcpads_[i];\n> > >           const StreamConfiguration &stream_cfg = state->config_->at(i);\n> > >\n> > > -         g_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg);\n> > > +         g_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg, transfer[i]);\n> > >           gst_libcamera_framerate_to_caps(caps, element_caps);\n> > >\n> > >           if (!gst_pad_push_event(srcpad, gst_event_new_caps(caps)))\n\n--\nRegards,\n\nLaurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B318EC32F9\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 16 Dec 2024 03:16:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DF09867F2E;\n\tMon, 16 Dec 2024 04:16:23 +0100 (CET)","from DB3PR0202CU003.outbound.protection.outlook.com\n\t(mail-northeuropeazlp170110001.outbound.protection.outlook.com\n\t[IPv6:2a01:111:f403:c200::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E6DD262C8A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Dec 2024 04:16:20 +0100 (CET)","from PAXPR04MB8285.eurprd04.prod.outlook.com\n\t(2603:10a6:102:1ca::15)\n\tby DU0PR04MB9493.eurprd04.prod.outlook.com (2603:10a6:10:350::15)\n\twith Microsoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8251.20;\n\tMon, 16 Dec 2024 03:16:19 +0000","from PAXPR04MB8285.eurprd04.prod.outlook.com\n\t([fe80::e003:8fb:64ea:acfd]) by\n\tPAXPR04MB8285.eurprd04.prod.outlook.com\n\t([fe80::e003:8fb:64ea:acfd%6]) with mapi id 15.20.8251.015;\n\tMon, 16 Dec 2024 03:16:19 +0000"],"Authentication-Results":["lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"KxldY2hF\";\n\tdkim-atps=neutral","dkim=none (message not signed)\n\theader.d=none;dmarc=none action=none header.from=nxp.com;"],"ARC-Seal":"i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n\tb=uhU04AubvQ037Sg7A7E0oxdvAARz0HPK+VDG5kaVBhkH1GvjioFBbkSjCdZQOEYUqFHSoNFhk20fobvUDXEmXLrWM/3gPiY/H6Rg1iAHMEdW8HEJrWwqmkedg+HK9XXrqXUW4tfO9bt6LFpFYbLO7XmfxrupEwQCY1h1jsB3+QLXtYynd260i32Vtmx7JDvAcUss8eTlK1OxrhdsUN5ivJMv2vIiKm6du6PDiUX4bqLeV9hs46JjyDrMSjCB+AopFiEcbVlSw/gmRdeKOWaUeUf+w3UgE0Jya7Qkh7GEvhTaGHj0YOb3f3MadqXWXxPMLaAG3lR6xFKc9K04skb1IA==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n\ts=arcselector10001;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n\tbh=QDz+z/80tvs5sQjyj6gf2OIJLPwF69vF93JXeVEKlvM=;\n\tb=L9MnwaYGIxhyqSvk0RJmLIfgOildDMixd8Z1K5A/qQdsmucAd89hu1L7f7mHQvMy4M9nTyDUDMavjbidGzWTu3F5e8boDh8/7vpMLyHPDWcQia09EheVY+JckGjLE7zL3zfjRqJnX4nY/yzo2gokUnTc09zVTnB7338Zqe5kNfQfaW7Q/rCHv2zNN1wAmzHWDRKrHtxLDLSF0BVrEkvcOsQ+46L6yH/vgOKp+B6KL8EaSiMduR3NXtMsrKZpaYRxryabVNBdFh7CijGSZ1KopM2rKWi+YZX+j8nxkLigQhyZ5KfrlBRz1WM9qJfPVC0QZ7ujgAiTYugfrR5Yl8useA==","ARC-Authentication-Results":"i=1; mx.microsoft.com 1; spf=pass\n\tsmtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com;\n\tdkim=pass header.d=nxp.com; arc=none","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=QDz+z/80tvs5sQjyj6gf2OIJLPwF69vF93JXeVEKlvM=;\n\tb=KxldY2hFqru6dGzyPBFoC40JnVZv786KVrPBVRUxEMubbkBWJGBQEiPb4wVTc+bmGx4X6Rw8SRp4dhT7oJD3oZExgljpQAbQGpjNfeIPhWPQsoVmNGfzvJpVk69E6NWerEnqel+ZTAgd8+lSVM+coP7ysUYrBI8jH9SWZcYP531llT9w8D39Q0ShJbqhpXdrgC8I/ScHtCbcXpy+WYAqXKkK1y/fDgusdfyDuOOauOaRwVt0r8L5YDERgyBOC3EcmfoJiQOk+t216ORefIwXWbpoOKZoVxO8U3SwuV25ammg8G9dUGJzUZv9+7qFnyWwrBeAHJhIh4c9Y9jvVvIsQg==","From":"Qi Hou <qi.hou@nxp.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Nicolas Dufresne\n\t<nicolas@ndufresne.ca>","CC":"\"libcamera-devel@lists.libcamera.org\"\n\t<libcamera-devel@lists.libcamera.org>, Jared Hu <jared.hu@nxp.com>,\n\tJulien Vuillaumier <julien.vuillaumier@nxp.com>","Subject":"RE: [EXT] Re: [PATCH v2] gstreamer: keep same transfer with that in\n\tnegotiated caps","Thread-Topic":"[EXT] Re: [PATCH v2] gstreamer: keep same transfer with that in\n\tnegotiated caps","Thread-Index":"AQHbTSTCERhCvxpsGE+Se57FhF/dmbLkfgsAgALcLQCAABIUAIAAyqWA","Date":"Mon, 16 Dec 2024 03:16:19 +0000","Message-ID":"<PAXPR04MB8285D71FA1DA82AAD643E070973B2@PAXPR04MB8285.eurprd04.prod.outlook.com>","References":"<20241213060319.2877936-1-qi.hou@nxp.com>\n\t<9f9100544b024594ee3c9baa5173fc0f9cd912cd.camel@ndufresne.ca>\n\t<20241215140428.GD25852@pendragon.ideasonboard.com>\n\t<20241215150910.GE25852@pendragon.ideasonboard.com>","In-Reply-To":"<20241215150910.GE25852@pendragon.ideasonboard.com>","Accept-Language":"zh-CN, en-US","Content-Language":"en-US","X-MS-Has-Attach":"","X-MS-TNEF-Correlator":"","authentication-results":["lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"KxldY2hF\";\n\tdkim-atps=neutral","dkim=none (message not signed)\n\theader.d=none;dmarc=none action=none header.from=nxp.com;"],"x-ms-publictraffictype":"Email","x-ms-traffictypediagnostic":"PAXPR04MB8285:EE_|DU0PR04MB9493:EE_","x-ms-office365-filtering-correlation-id":"1b4cc510-d078-45a5-c7a0-08dd1d8002a0","x-ld-processed":"686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr","x-ms-exchange-senderadcheck":"1","x-ms-exchange-antispam-relay":"0","x-microsoft-antispam":"BCL:0;\n\tARA:13230040|376014|1800799024|366016|38070700018; ","x-microsoft-antispam-message-info":"=?gb2312?b?YmR1MGtsSllsN1I5RzBEcXpK?=\n\t=?gb2312?b?a2NhWEgwb3AwMFlmL2tXQ2E0QmllSU5tVEczaThFSG1ST0FYSjJw?=\n\t=?gb2312?b?bHEyeUw1WFY4MEl6WnZYT3RVbXljZ2ZSZDVUaDVBTXhvUUUwT0I4?=\n\t=?gb2312?b?dzM5TXRlWktoWXBWZWlOZTFjRVhrRHJ6bThWMU1ySTlzT0dWcTl3?=\n\t=?gb2312?b?a3JUaVhhMkV5M2RHbHlWb21PN0xpaHhNdXJWblZOYS9vZUlZYVcr?=\n\t=?gb2312?b?WVFQOUNVMDczU0FSRHQxRzE0NmdDN08rcnlRZlZjU3JjTlk4TGlK?=\n\t=?gb2312?b?UzhDbmVaTXdtaTJxZkdXWU9DZ1RsQjJsZkd5MzlBZ1dvdXhLWjFQ?=\n\t=?gb2312?b?djA1ZmN4UXo1OWN5d0pOUzdpSlFJU2lMODZCc0hOdWJ3R3dUc3VH?=\n\t=?gb2312?b?dEdpQ093dFUvaU83RmZMUkkxYTNTNTNBVVIzN0dWSURNbnhvMUFR?=\n\t=?gb2312?b?M2Q3elk5WURkR3NraFRUd0VubGVnTHlrR0loWHZ3dXhrSUl6ZXZZ?=\n\t=?gb2312?b?VjE4OGZLNUIxV00za0pYcytUZ044a3JBVTk0UXNoczQrV3ZGTWdn?=\n\t=?gb2312?b?MmdMbXJXOENJRXZaazlZVVpPQzdPZ05hdTdOczcvVERHQ1ZoTHFC?=\n\t=?gb2312?b?a2duMVcyYi8wQ1ZwalRpYlp3V2I1WVp5cExqQXI4b1JlT0pEU0c1?=\n\t=?gb2312?b?NXk4Wk4rYk11N0MwaHhQdExIWUIrZURJQ0RkWktlRmJ2b3FFUWZE?=\n\t=?gb2312?b?a3ZSMmpLNitaYnFPOHVqMVZLOG9lNDJsdkY4Mk5ZRXkrVlJiREU4?=\n\t=?gb2312?b?L2w1SFFrRHFKTWdNcjVnd3ZIbU9PblFVeG1tQ2UwcFM1MDZuZll0?=\n\t=?gb2312?b?M1g4cVUvbVYxNGhpZGtWdFl6NkVVWW5IL28yT1VoNml0ZTZhZEtM?=\n\t=?gb2312?b?N0daS2hHRVRyR2dkbTF3Njhra3AyeWdmRGhyZy9nOGs2clNtOGlO?=\n\t=?gb2312?b?em9zait0Mmc5UU41UHVDTEM1bjFDaXJpZy9vb1N6MDkyYkhWK1Fj?=\n\t=?gb2312?b?MGRmLzdkNm5pT2RlSkJaMWlVR3hmdVh3R1R3WkNPa1Zod1lERk9y?=\n\t=?gb2312?b?SzhqWlk5cmN4TVFNYkVrN2plNnBwRk1Yb2xTL09pb0JSOHh2dDBD?=\n\t=?gb2312?b?c0FkZFhFRmZZOXhqUStXbUlsbEtMUUc1cGM4Q0pDSEZSYTdoYUxB?=\n\t=?gb2312?b?OU5WWjN3Y2MzK3JKa2kxRTYzSm5rZXN2Zm45OStEdERtRjU0dlhX?=\n\t=?gb2312?b?WmJsV2JYVEpENjgxQXRzV3h4MlJSRmVpRlF3SnMralNGQ1pta2VH?=\n\t=?gb2312?b?bmRXRUhHMDJhaG9YMHpyWmcrc0doRWd3SFlFdmE0OTNIdzQzSVhw?=\n\t=?gb2312?b?L0kwd0s2dTF1aG9qVE50elhKRjVPQ2REMXVtMkI5UWc3bngvNzVF?=\n\t=?gb2312?b?Nk9SMlFSbkFNZjU2c2pSUGpGc0xJV2NmeTNCVDlyK1h2c01aM3dR?=\n\t=?gb2312?b?TTQzU1FqRmh5NkVUOU9qaXJmdk8ramtqbTFZMktxUUhKOGxSUVlM?=\n\t=?gb2312?b?ZUxKZnZ6a1MyZEgxZkNQUkRUM3FtamZvRHpwTTFGODNTS3VyempM?=\n\t=?gb2312?b?NnFSS015UHlkZHRxWmlLYnNnV2tFaC9iakVoSXFBdU9MZUc4OS81?=\n\t=?gb2312?b?dUIvZUtxL2huS201cFlvM3pNT05JK1ZweHR4a3NyWXZYekFta1U1?=\n\t=?gb2312?b?THdmOStRd1FWRnF0Tkc0WjhZNG0wQmJtQTV5VzVxWmpTeFVRblJG?=\n\t=?gb2312?b?V0lxUXVCY2FZNGpBN09FQ3pXS0o0ZzYxNiswd1FpSlFnTUtva3lP?=\n\t=?gb2312?b?YjdlTVdEckE3dHoxS1JpQWM5T0VjdjdMSFB0ZkhITGt5ZVFjYXZE?=\n\t=?gb2312?b?UzdBc1lmYUFVcDM2NjJZdXF2dytHZEpraC9WQmVYOW9yY0NxemRV?=\n\t=?gb2312?b?bWZjcG9kYVlucDkxQ2x4bGZxOFRYbFNjeFAyVkhPV0MrK1ZBMSt1?=\n\t=?gb2312?b?dC9zcVAvbjJSSWFZMVNEdXBkRGVCQkxHTQ==?=","x-forefront-antispam-report":"CIP:255.255.255.255; CTRY:; LANG:zh-cn; SCL:1; \n\tSRV:; IPV:NLI; SFV:NSPM;\n\tH:PAXPR04MB8285.eurprd04.prod.outlook.com; PTR:; \n\tCAT:NONE; SFS:(13230040)(376014)(1800799024)(366016)(38070700018);\n\tDIR:OUT; SFP:1101; ","x-ms-exchange-antispam-messagedata-chunkcount":"1","x-ms-exchange-antispam-messagedata-0":"=?gb2312?b?TGV3N0VLekFBTnVMa3ZTQmZV?=\n\t=?gb2312?b?Smt2TklNckxrRng0QWJGNWplMThvdDlLaU5MR1AzdnNxN21JOG9r?=\n\t=?gb2312?b?aCtXOW8xMHJ6NzJmTkRTbmFCOGRYeWF0MEJFVHJpdWRwSVJMRzRj?=\n\t=?gb2312?b?bGsyZVE0SHNRVUk3QTl1aGppd1l6LzVZcjh1bWRCZUM1dktYRURM?=\n\t=?gb2312?b?aHdSTW8xYXhLTnlaczNPelg5YkxZQ1phRStQMVJGQVlnUk9WTWQ0?=\n\t=?gb2312?b?VU1KY21UcktOaVNlNzFVWnVqUW9KV2RGV0R4T29JN1NaekJZTUw2?=\n\t=?gb2312?b?VWpjNEZsSjRZZUIydng0QzhTZmFCd3RveEZUVFFzUm4weUtsZmtT?=\n\t=?gb2312?b?SU9ueCs5VTVacWFQRkMvaFFvczFiUHVSRkU5bUd6OW1hbzZuM29s?=\n\t=?gb2312?b?dW14enpjNnFDYXFuUC9XZnJXSlRqZmUzLzE1YW5iMjRwUWdYOTNs?=\n\t=?gb2312?b?dndiMmFrSjR5Q2E5QXhoYTFSR0hsdjBWMVVidWFpeUxmQWFaVTlX?=\n\t=?gb2312?b?Vkl5YWIyR3p6Rm1RNVVOL1ZXOVF0N1NOSEhjMU84eks3bjdyVUpw?=\n\t=?gb2312?b?RGZZKzNHSjUxWGY1S1FBeklnY2xHRnVKeDFYRUVVWEpCT0s4Rjly?=\n\t=?gb2312?b?cnpCekZYWUZsU0hWNkZNTHQ4ei9YK0VkZEtVRHYwZERvTi85dCtG?=\n\t=?gb2312?b?aVg1OFNvSGVzQmVwNE5pd2c5UXRHQ3VSb08zUEhaVm4wWE83Qk1X?=\n\t=?gb2312?b?UDNUeVF4alBFblRrWU5ya1d3cFNMalp4ajhRUzNXaFZlZXdrQzRx?=\n\t=?gb2312?b?Sk9CSm9JOWhjczEyUzg5dFFXTllRdkRBblk2Zi8wcjlBS3hUNS94?=\n\t=?gb2312?b?bmJ1OGFtZElqK1lvZjZESmRkc2UyYm5ZYTJ3YzAvK2RjdC9mbzd1?=\n\t=?gb2312?b?YlpIODBXK0R3WThlUFlKdnhiZzZqcjE1RXFLYW5PUE1MMzFDZU5i?=\n\t=?gb2312?b?WDdtNGVjRFpsOEYrRnQrU0hYbTNsZGxkeXZjaG1xcEpaSjBoRlpZ?=\n\t=?gb2312?b?NzFVTUVIcTVxMjJ3VE1EaXpaSHZJWEtUNDZMdVpJQnNMZEtkSVF5?=\n\t=?gb2312?b?NFpuQW8wWUFQdEFqMkVPSFgrNTg5VEZuVko3bE5ucEt5YllxYUFZ?=\n\t=?gb2312?b?aUhrVG56L2lROWNNUG9LQU9TWGN2K01nMnp6dTZPYmRRdk1CVDB6?=\n\t=?gb2312?b?bDF0R1ZEa2x0OWNkWURjZFlzeXJxTTN3SkR6RFdUYUpIZ2ZvNlJm?=\n\t=?gb2312?b?MGJaZnVWdGIxYlNEYXBVWkN1aDgvNUszKzM0VW1oTm56Z2lDa0g1?=\n\t=?gb2312?b?c1hpa0lMOTNnRWNzb2EvVkxRVkRvdFI4c3hEbDRGc3pDeUNKWjJR?=\n\t=?gb2312?b?OEZFbzllcFRoM3lubmpmMVI5Wkl1RGhzMGRldUVwWWhDWXpHN1pE?=\n\t=?gb2312?b?NXBib1JiaW5NK0J2QytiTjI0eERON3Nmd1VXdlFuMmlmcG55QWJr?=\n\t=?gb2312?b?dzRnaWNNL3RuWW1tUjZVL3hRM0NCbzFVM1IrQWRXR2pXQTJ4R1hu?=\n\t=?gb2312?b?bkRIdm1wSnN5cHphWjhXR0NKL2t3WHluVDRUZTF6bnJiTGVNNDJN?=\n\t=?gb2312?b?M0tyK3FtTWpZY2JxZnRxKzVnUzRLWTN6QTBPSCtGV216QVhJdUdM?=\n\t=?gb2312?b?Zm5xMi9OU0lwbmJtNXBvNjVzQ1FSQXlCTkJSZTNHN1FlYUhJS1dM?=\n\t=?gb2312?b?OGtyV1BWcWVNeGFueVdxbU91d2hzeVlBRmtsSkdnWTVQN3VrcnFV?=\n\t=?gb2312?b?dUFRdnQ3T3ZEOGpBaXpxS0RRNTNKZ3d1VTd4U0doeTZaYXNLMnh4?=\n\t=?gb2312?b?VjRuRlpaeFZKRkcvL2owSkRXck5CcjIwNDQwZ0JoelIyUjhSam1s?=\n\t=?gb2312?b?YlA1dDFZOElEekJ6anFWV3ZqRkp5UE1WQldDVFlJd29hV1dJSk05?=\n\t=?gb2312?b?QUhPSWdNMkpSMlQzeG1GaERwM2V4N2hnbU9kYk5YNWtORVVXZHFh?=\n\t=?gb2312?b?Y013eHI1bWUzczVCNElVVEhVOHJMdnhxelNPOEF2ZFRPQUs3c2Mv?=\n\t=?gb2312?b?N2w0ZGwxMmRBS1RPZGdYYW03OXBvM2pqTitBdXFDQWwzRE95Mk1X?=\n\t=?gb2312?b?aEpDZk5scWhzUUl5QU5yVFZqZE9weUJBWWI2a0lnMllvd2NPSUJP?=\n\t=?gb2312?b?N3F4RXlBQTdRNFpZSmF1RHAwdmNMSmg2am9VYU9mY1ZtOCtzV3B6?=\n\t=?gb2312?b?T2JIcFBPWDJra3dHdFkrWDd2Y05pNWdtU2dEZzJ3cUhaa3ozSGwr?=\n\t=?gb2312?b?TT0=?=","Content-Type":"text/plain; charset=\"gb2312\"","Content-Transfer-Encoding":"base64","MIME-Version":"1.0","X-OriginatorOrg":"nxp.com","X-MS-Exchange-CrossTenant-AuthAs":"Internal","X-MS-Exchange-CrossTenant-AuthSource":"PAXPR04MB8285.eurprd04.prod.outlook.com","X-MS-Exchange-CrossTenant-Network-Message-Id":"1b4cc510-d078-45a5-c7a0-08dd1d8002a0","X-MS-Exchange-CrossTenant-originalarrivaltime":"16 Dec 2024 03:16:19.3281\n\t(UTC)","X-MS-Exchange-CrossTenant-fromentityheader":"Hosted","X-MS-Exchange-CrossTenant-id":"686ea1d3-bc2b-4c6f-a92c-d99c5c301635","X-MS-Exchange-CrossTenant-mailboxtype":"HOSTED","X-MS-Exchange-CrossTenant-userprincipalname":"01/fXGWKoZg0JXaUBzLATBTjABtFqwiG14pc2kfdtX0zOMarvfS82+C64Srrzv7J","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"DU0PR04MB9493","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]