[{"id":31920,"web_url":"https://patchwork.libcamera.org/comment/31920/","msgid":"<3vgjqpworr5ubynfli7otkghkf5xcqcugmybljvlvguiielndr@6j7ghkwncy5z>","date":"2024-10-25T09:15:12","subject":"Re: [PATCH v3 1/2] libcamera: Extend u32 control type","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Harvey\n\nOn Fri, Oct 25, 2024 at 05:30:13AM +0000, Harvey Yang wrote:\n> From: Yudhistira Erlandinata <yerlandinata@chromium.org>\n>\n> V4L2 Controls support a wide variety of types not yet supported by the\n> ControlValue type system.\n>\n> Extend the libcamera ControlValue types to support an explicit 32 bit\n> unsigned integer type, and map that to the corresponding\n> V4L2_CTRL_TYPE_U32 type within the v4l2_device support class.\n\nV4L2_CTRL_TYPE_U32 is a control compound type.\n\n\t/* Compound types are >= 0x0100 */\n\tV4L2_CTRL_COMPOUND_TYPES     = 0x0100,\n\tV4L2_CTRL_TYPE_U8\t     = 0x0100,\n\tV4L2_CTRL_TYPE_U16\t     = 0x0101,\n\tV4L2_CTRL_TYPE_U32\t     = 0x0102,\n\tV4L2_CTRL_TYPE_AREA          = 0x0106,\n\nThis means it carries a payload and needs to be handled like\nV4L2_CTRL_TYPE_U8 is, specifcially when it comes to parsing it from\nthe V4L2 interface into a libcamera control.\n\nI'm surprised you don't hit this in V4L2Device::getControls()\n\n\t\tif (info.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {\n\t\t\tControlType type;\n\n\t\t\tswitch (info.type) {\n\t\t\tcase V4L2_CTRL_TYPE_U8:\n\t\t\t\ttype = ControlTypeByte;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG(V4L2, Error)\n\t\t\t\t\t<< \"Unsupported payload control type \"\n\t\t\t\t\t<< info.type;\n\t\t\t\treturn {};\n\t\t\t}\n\n>\n> Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>\n> Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>\n> ---\n>  include/libcamera/controls.h    |  7 ++++++\n>  src/libcamera/controls.cpp      | 12 ++++++++--\n>  src/libcamera/v4l2_device.cpp   | 13 +++++++++++\n>  test/controls/control_value.cpp | 40 +++++++++++++++++++++++++++++++++\n>  4 files changed, 70 insertions(+), 2 deletions(-)\n>\n> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> index ca60bbaca..6da8ad2c3 100644\n> --- a/include/libcamera/controls.h\n> +++ b/include/libcamera/controls.h\n> @@ -29,6 +29,7 @@ enum ControlType {\n>  \tControlTypeNone,\n>  \tControlTypeBool,\n>  \tControlTypeByte,\n> +\tControlTypeUnsigned32,\n>  \tControlTypeInteger32,\n>  \tControlTypeInteger64,\n>  \tControlTypeFloat,\n> @@ -62,6 +63,12 @@ struct control_type<uint8_t> {\n>  \tstatic constexpr std::size_t size = 0;\n>  };\n>\n> +template<>\n> +struct control_type<uint32_t> {\n> +\tstatic constexpr ControlType value = ControlTypeUnsigned32;\n> +\tstatic constexpr std::size_t size = 0;\n> +};\n> +\n>  template<>\n>  struct control_type<int32_t> {\n>  \tstatic constexpr ControlType value = ControlTypeInteger32;\n> diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\n> index 62185d643..8ae295191 100644\n> --- a/src/libcamera/controls.cpp\n> +++ b/src/libcamera/controls.cpp\n> @@ -54,6 +54,7 @@ static constexpr size_t ControlValueSize[] = {\n>  \t[ControlTypeNone]\t\t= 0,\n>  \t[ControlTypeBool]\t\t= sizeof(bool),\n>  \t[ControlTypeByte]\t\t= sizeof(uint8_t),\n> +\t[ControlTypeUnsigned32]\t\t= sizeof(uint32_t),\n>  \t[ControlTypeInteger32]\t\t= sizeof(int32_t),\n>  \t[ControlTypeInteger64]\t\t= sizeof(int64_t),\n>  \t[ControlTypeFloat]\t\t= sizeof(float),\n> @@ -74,10 +75,12 @@ static constexpr size_t ControlValueSize[] = {\n>   * The control stores a boolean value\n>   * \\var ControlTypeByte\n>   * The control stores a byte value as an unsigned 8-bit integer\n> + * \\var ControlTypeUnsigned32\n> + * The control stores an unsigned 32-bit integer value\n>   * \\var ControlTypeInteger32\n> - * The control stores a 32-bit integer value\n> + * The control stores a signed 32-bit integer value\n>   * \\var ControlTypeInteger64\n> - * The control stores a 64-bit integer value\n> + * The control stores a signed 64-bit integer value\n>   * \\var ControlTypeFloat\n>   * The control stores a 32-bit floating point value\n>   * \\var ControlTypeString\n> @@ -230,6 +233,11 @@ std::string ControlValue::toString() const\n>  \t\t\tstr += std::to_string(*value);\n>  \t\t\tbreak;\n>  \t\t}\n> +\t\tcase ControlTypeUnsigned32: {\n> +\t\t\tconst uint32_t *value = reinterpret_cast<const uint32_t *>(data);\n> +\t\t\tstr += std::to_string(*value);\n> +\t\t\tbreak;\n> +\t\t}\n>  \t\tcase ControlTypeInteger32: {\n>  \t\t\tconst int32_t *value = reinterpret_cast<const int32_t *>(data);\n>  \t\t\tstr += std::to_string(*value);\n> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> index 68add4f2e..0ba8dcfa0 100644\n> --- a/src/libcamera/v4l2_device.cpp\n> +++ b/src/libcamera/v4l2_device.cpp\n> @@ -9,6 +9,7 @@\n>\n>  #include <fcntl.h>\n>  #include <map>\n> +#include <stdint.h>\n>  #include <stdlib.h>\n>  #include <string.h>\n>  #include <sys/ioctl.h>\n> @@ -17,11 +18,14 @@\n>  #include <vector>\n>\n>  #include <linux/v4l2-mediabus.h>\n> +#include <linux/videodev2.h>\n\nIncluded by the header file\n\n>\n>  #include <libcamera/base/event_notifier.h>\n>  #include <libcamera/base/log.h>\n>  #include <libcamera/base/utils.h>\n>\n> +#include <libcamera/controls.h>\n> +\n\nThis as well\n\n>  #include \"libcamera/internal/formats.h\"\n>  #include \"libcamera/internal/sysfs.h\"\n>\n> @@ -488,6 +492,9 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType)\n>  \tcase V4L2_CTRL_TYPE_BOOLEAN:\n>  \t\treturn ControlTypeBool;\n>\n> +\tcase V4L2_CTRL_TYPE_U32:\n> +\t\treturn ControlTypeUnsigned32;\n> +\n>  \tcase V4L2_CTRL_TYPE_INTEGER:\n>  \t\treturn ControlTypeInteger32;\n>\n> @@ -536,6 +543,11 @@ std::optional<ControlInfo> V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl\n>  \t\t\t\t   static_cast<uint8_t>(ctrl.maximum),\n>  \t\t\t\t   static_cast<uint8_t>(ctrl.default_value));\n>\n> +\tcase V4L2_CTRL_TYPE_U32:\n> +\t\treturn ControlInfo(static_cast<uint32_t>(ctrl.minimum),\n> +\t\t\t\t   static_cast<uint32_t>(ctrl.maximum),\n> +\t\t\t\t   static_cast<uint32_t>(ctrl.default_value));\n> +\n>  \tcase V4L2_CTRL_TYPE_BOOLEAN:\n>  \t\treturn ControlInfo(static_cast<bool>(ctrl.minimum),\n>  \t\t\t\t   static_cast<bool>(ctrl.maximum),\n> @@ -622,6 +634,7 @@ void V4L2Device::listControls()\n>  \t\tcase V4L2_CTRL_TYPE_BITMASK:\n>  \t\tcase V4L2_CTRL_TYPE_INTEGER_MENU:\n>  \t\tcase V4L2_CTRL_TYPE_U8:\n> +\t\tcase V4L2_CTRL_TYPE_U32:\n>  \t\t\tbreak;\n>  \t\t/* \\todo Support other control types. */\n>  \t\tdefault:\n> diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\n> index 344107fae..6ca85b739 100644\n> --- a/test/controls/control_value.cpp\n> +++ b/test/controls/control_value.cpp\n> @@ -109,6 +109,46 @@ protected:\n>  \t\t\treturn TestFail;\n>  \t\t}\n>\n> +\t\t/*\n> +\t\t * Unsigned Integer32 type.\n> +\t\t */\n> +\t\tvalue.set(static_cast<uint32_t>(42));\n> +\t\tif (value.isNone() || value.isArray() ||\n> +\t\t    value.type() != ControlTypeUnsigned32) {\n> +\t\t\tcerr << \"Control type mismatch after setting to uint32_t\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (value.get<uint32_t>() != 42) {\n> +\t\t\tcerr << \"Control value mismatch after setting to uint32_t\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (value.toString() != \"42\") {\n> +\t\t\tcerr << \"Control string mismatch after setting to uint32_t\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tstd::array<uint32_t, 4> uint32s{ 3, 14, 15, 9 };\n> +\t\tvalue.set(Span<uint32_t>(uint32s));\n> +\t\tif (value.isNone() || !value.isArray() ||\n> +\t\t    value.type() != ControlTypeUnsigned32) {\n> +\t\t\tcerr << \"Control type mismatch after setting to uint32_t array\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tSpan<const uint32_t> uint32sResult = value.get<Span<const uint32_t>>();\n> +\t\tif (uint32s.size() != uint32sResult.size() ||\n> +\t\t    !std::equal(uint32s.begin(), uint32s.end(), uint32sResult.begin())) {\n> +\t\t\tcerr << \"Control value mismatch after setting to uint32_t array\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (value.toString() != \"[ 3, 14, 15, 9 ]\") {\n> +\t\t\tcerr << \"Control string mismatch after setting to uint32_t array\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n>  \t\t/*\n>  \t\t * Integer32 type.\n>  \t\t */\n> --\n> 2.47.0.163.g1226f6d8fa-goog\n>","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 E1D6DC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 25 Oct 2024 09:15:27 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0B72D65394;\n\tFri, 25 Oct 2024 11:15:27 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 75D3D6538A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Oct 2024 11:15:25 +0200 (CEST)","from ideasonboard.com (93-61-96-190.ip145.fastwebnet.it\n\t[93.61.96.190])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B9E79670;\n\tFri, 25 Oct 2024 11:13:32 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"vuPkhglM\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1729847616;\n\tbh=RAdXJcuq0imQ/SdcA7R0XEBoobw5EDot39K0Q9DV6U8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=vuPkhglMYMoi8lL0zPoTMgvNffClwMX38xulBpgwKeyrfsUzApMznwAV8pYqWjZuP\n\tucOA/kr7w5CfFid48eO+D3yV/Gp7uCem9w9NYoKnhY+PeY4XNBaHqHQesjCS4f9t9z\n\thpniC/0qUQjqLKHfbpHxtL7in0Arl9Lrl/ugV5Yg=","Date":"Fri, 25 Oct 2024 11:15:12 +0200","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Harvey Yang <chenghaoyang@chromium.org>","Cc":"libcamera-devel@lists.libcamera.org, \n\tYudhistira Erlandinata <yerlandinata@chromium.org>","Subject":"Re: [PATCH v3 1/2] libcamera: Extend u32 control type","Message-ID":"<3vgjqpworr5ubynfli7otkghkf5xcqcugmybljvlvguiielndr@6j7ghkwncy5z>","References":"<20241025053111.519449-1-chenghaoyang@chromium.org>\n\t<20241025053111.519449-2-chenghaoyang@chromium.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20241025053111.519449-2-chenghaoyang@chromium.org>","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":31922,"web_url":"https://patchwork.libcamera.org/comment/31922/","msgid":"<CAEB1ahsK8RCpRza+MspmhFon1CcLqQeqgFNCxDy3m6Jorf3=qw@mail.gmail.com>","date":"2024-10-25T15:40:02","subject":"Re: [PATCH v3 1/2] libcamera: Extend u32 control type","submitter":{"id":117,"url":"https://patchwork.libcamera.org/api/people/117/","name":"Cheng-Hao Yang","email":"chenghaoyang@chromium.org"},"content":"Hi Jacopo,\n\nOn Fri, Oct 25, 2024 at 5:15 PM Jacopo Mondi\n<jacopo.mondi@ideasonboard.com> wrote:\n>\n> Hi Harvey\n>\n> On Fri, Oct 25, 2024 at 05:30:13AM +0000, Harvey Yang wrote:\n> > From: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> >\n> > V4L2 Controls support a wide variety of types not yet supported by the\n> > ControlValue type system.\n> >\n> > Extend the libcamera ControlValue types to support an explicit 32 bit\n> > unsigned integer type, and map that to the corresponding\n> > V4L2_CTRL_TYPE_U32 type within the v4l2_device support class.\n>\n> V4L2_CTRL_TYPE_U32 is a control compound type.\n>\n>         /* Compound types are >= 0x0100 */\n>         V4L2_CTRL_COMPOUND_TYPES     = 0x0100,\n>         V4L2_CTRL_TYPE_U8            = 0x0100,\n>         V4L2_CTRL_TYPE_U16           = 0x0101,\n>         V4L2_CTRL_TYPE_U32           = 0x0102,\n>         V4L2_CTRL_TYPE_AREA          = 0x0106,\n>\n> This means it carries a payload and needs to be handled like\n> V4L2_CTRL_TYPE_U8 is, specifcially when it comes to parsing it from\n> the V4L2 interface into a libcamera control.\n>\n> I'm surprised you don't hit this in V4L2Device::getControls()\n>\n>                 if (info.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {\n>                         ControlType type;\n>\n>                         switch (info.type) {\n>                         case V4L2_CTRL_TYPE_U8:\n>                                 type = ControlTypeByte;\n>                                 break;\n>\n>                         default:\n>                                 LOG(V4L2, Error)\n>                                         << \"Unsupported payload control type \"\n>                                         << info.type;\n>                                 return {};\n>                         }\n>\n\nThanks! Added for U32 and U16.\n\n> >\n> > Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> > Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>\n> > Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>\n> > ---\n> >  include/libcamera/controls.h    |  7 ++++++\n> >  src/libcamera/controls.cpp      | 12 ++++++++--\n> >  src/libcamera/v4l2_device.cpp   | 13 +++++++++++\n> >  test/controls/control_value.cpp | 40 +++++++++++++++++++++++++++++++++\n> >  4 files changed, 70 insertions(+), 2 deletions(-)\n> >\n> > diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> > index ca60bbaca..6da8ad2c3 100644\n> > --- a/include/libcamera/controls.h\n> > +++ b/include/libcamera/controls.h\n> > @@ -29,6 +29,7 @@ enum ControlType {\n> >       ControlTypeNone,\n> >       ControlTypeBool,\n> >       ControlTypeByte,\n> > +     ControlTypeUnsigned32,\n> >       ControlTypeInteger32,\n> >       ControlTypeInteger64,\n> >       ControlTypeFloat,\n> > @@ -62,6 +63,12 @@ struct control_type<uint8_t> {\n> >       static constexpr std::size_t size = 0;\n> >  };\n> >\n> > +template<>\n> > +struct control_type<uint32_t> {\n> > +     static constexpr ControlType value = ControlTypeUnsigned32;\n> > +     static constexpr std::size_t size = 0;\n> > +};\n> > +\n> >  template<>\n> >  struct control_type<int32_t> {\n> >       static constexpr ControlType value = ControlTypeInteger32;\n> > diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\n> > index 62185d643..8ae295191 100644\n> > --- a/src/libcamera/controls.cpp\n> > +++ b/src/libcamera/controls.cpp\n> > @@ -54,6 +54,7 @@ static constexpr size_t ControlValueSize[] = {\n> >       [ControlTypeNone]               = 0,\n> >       [ControlTypeBool]               = sizeof(bool),\n> >       [ControlTypeByte]               = sizeof(uint8_t),\n> > +     [ControlTypeUnsigned32]         = sizeof(uint32_t),\n> >       [ControlTypeInteger32]          = sizeof(int32_t),\n> >       [ControlTypeInteger64]          = sizeof(int64_t),\n> >       [ControlTypeFloat]              = sizeof(float),\n> > @@ -74,10 +75,12 @@ static constexpr size_t ControlValueSize[] = {\n> >   * The control stores a boolean value\n> >   * \\var ControlTypeByte\n> >   * The control stores a byte value as an unsigned 8-bit integer\n> > + * \\var ControlTypeUnsigned32\n> > + * The control stores an unsigned 32-bit integer value\n> >   * \\var ControlTypeInteger32\n> > - * The control stores a 32-bit integer value\n> > + * The control stores a signed 32-bit integer value\n> >   * \\var ControlTypeInteger64\n> > - * The control stores a 64-bit integer value\n> > + * The control stores a signed 64-bit integer value\n> >   * \\var ControlTypeFloat\n> >   * The control stores a 32-bit floating point value\n> >   * \\var ControlTypeString\n> > @@ -230,6 +233,11 @@ std::string ControlValue::toString() const\n> >                       str += std::to_string(*value);\n> >                       break;\n> >               }\n> > +             case ControlTypeUnsigned32: {\n> > +                     const uint32_t *value = reinterpret_cast<const uint32_t *>(data);\n> > +                     str += std::to_string(*value);\n> > +                     break;\n> > +             }\n> >               case ControlTypeInteger32: {\n> >                       const int32_t *value = reinterpret_cast<const int32_t *>(data);\n> >                       str += std::to_string(*value);\n> > diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> > index 68add4f2e..0ba8dcfa0 100644\n> > --- a/src/libcamera/v4l2_device.cpp\n> > +++ b/src/libcamera/v4l2_device.cpp\n> > @@ -9,6 +9,7 @@\n> >\n> >  #include <fcntl.h>\n> >  #include <map>\n> > +#include <stdint.h>\n> >  #include <stdlib.h>\n> >  #include <string.h>\n> >  #include <sys/ioctl.h>\n> > @@ -17,11 +18,14 @@\n> >  #include <vector>\n> >\n> >  #include <linux/v4l2-mediabus.h>\n> > +#include <linux/videodev2.h>\n>\n> Included by the header file\n\nRemoved.\n\n>\n> >\n> >  #include <libcamera/base/event_notifier.h>\n> >  #include <libcamera/base/log.h>\n> >  #include <libcamera/base/utils.h>\n> >\n> > +#include <libcamera/controls.h>\n> > +\n>\n> This as well\n\nRemoved.\n\nBR,\nHarvey\n\n>\n> >  #include \"libcamera/internal/formats.h\"\n> >  #include \"libcamera/internal/sysfs.h\"\n> >\n> > @@ -488,6 +492,9 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType)\n> >       case V4L2_CTRL_TYPE_BOOLEAN:\n> >               return ControlTypeBool;\n> >\n> > +     case V4L2_CTRL_TYPE_U32:\n> > +             return ControlTypeUnsigned32;\n> > +\n> >       case V4L2_CTRL_TYPE_INTEGER:\n> >               return ControlTypeInteger32;\n> >\n> > @@ -536,6 +543,11 @@ std::optional<ControlInfo> V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl\n> >                                  static_cast<uint8_t>(ctrl.maximum),\n> >                                  static_cast<uint8_t>(ctrl.default_value));\n> >\n> > +     case V4L2_CTRL_TYPE_U32:\n> > +             return ControlInfo(static_cast<uint32_t>(ctrl.minimum),\n> > +                                static_cast<uint32_t>(ctrl.maximum),\n> > +                                static_cast<uint32_t>(ctrl.default_value));\n> > +\n> >       case V4L2_CTRL_TYPE_BOOLEAN:\n> >               return ControlInfo(static_cast<bool>(ctrl.minimum),\n> >                                  static_cast<bool>(ctrl.maximum),\n> > @@ -622,6 +634,7 @@ void V4L2Device::listControls()\n> >               case V4L2_CTRL_TYPE_BITMASK:\n> >               case V4L2_CTRL_TYPE_INTEGER_MENU:\n> >               case V4L2_CTRL_TYPE_U8:\n> > +             case V4L2_CTRL_TYPE_U32:\n> >                       break;\n> >               /* \\todo Support other control types. */\n> >               default:\n> > diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\n> > index 344107fae..6ca85b739 100644\n> > --- a/test/controls/control_value.cpp\n> > +++ b/test/controls/control_value.cpp\n> > @@ -109,6 +109,46 @@ protected:\n> >                       return TestFail;\n> >               }\n> >\n> > +             /*\n> > +              * Unsigned Integer32 type.\n> > +              */\n> > +             value.set(static_cast<uint32_t>(42));\n> > +             if (value.isNone() || value.isArray() ||\n> > +                 value.type() != ControlTypeUnsigned32) {\n> > +                     cerr << \"Control type mismatch after setting to uint32_t\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             if (value.get<uint32_t>() != 42) {\n> > +                     cerr << \"Control value mismatch after setting to uint32_t\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             if (value.toString() != \"42\") {\n> > +                     cerr << \"Control string mismatch after setting to uint32_t\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             std::array<uint32_t, 4> uint32s{ 3, 14, 15, 9 };\n> > +             value.set(Span<uint32_t>(uint32s));\n> > +             if (value.isNone() || !value.isArray() ||\n> > +                 value.type() != ControlTypeUnsigned32) {\n> > +                     cerr << \"Control type mismatch after setting to uint32_t array\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             Span<const uint32_t> uint32sResult = value.get<Span<const uint32_t>>();\n> > +             if (uint32s.size() != uint32sResult.size() ||\n> > +                 !std::equal(uint32s.begin(), uint32s.end(), uint32sResult.begin())) {\n> > +                     cerr << \"Control value mismatch after setting to uint32_t array\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> > +             if (value.toString() != \"[ 3, 14, 15, 9 ]\") {\n> > +                     cerr << \"Control string mismatch after setting to uint32_t array\" << endl;\n> > +                     return TestFail;\n> > +             }\n> > +\n> >               /*\n> >                * Integer32 type.\n> >                */\n> > --\n> > 2.47.0.163.g1226f6d8fa-goog\n> >","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 E9A0AC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 25 Oct 2024 15:40:17 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 93752653A6;\n\tFri, 25 Oct 2024 17:40:17 +0200 (CEST)","from mail-lj1-x234.google.com (mail-lj1-x234.google.com\n\t[IPv6:2a00:1450:4864:20::234])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4A39C6539F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Oct 2024 17:40:15 +0200 (CEST)","by mail-lj1-x234.google.com with SMTP id\n\t38308e7fff4ca-2fb388e64b0so22971081fa.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Oct 2024 08:40:15 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"nrWwFOBX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=chromium.org; s=google; t=1729870814; x=1730475614;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=zD/kyiJpjQAydT3TVWYtQW34CoDl0bkEqSx3iHwrNhI=;\n\tb=nrWwFOBXvPmvtajiwZj8FnitGJeRDTf8XDjrkDinB6uSkOON+M6pR+8j8KUNuiUayw\n\tRhr+JrK2eBpvYD/IJ43zVWxCFcHn1RvpdkfwdZIMETzR/VH5ud2lluHRjad9H4H9TZUS\n\tuuNZRmqdKDcaucMa6grpg/zcnp5S+UhEdHNIw=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1729870814; x=1730475614;\n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=zD/kyiJpjQAydT3TVWYtQW34CoDl0bkEqSx3iHwrNhI=;\n\tb=T0O+dplZdP7bX95YILl4bBPj0vxfxQe6m3JWhrEh4r+A8EFCy6/4Bic6V/btBmhvf1\n\tjpBcIZGJtfdyYPM0DnHsfzfKlWRu+bAkNDd4+2+aMQXLaoDONeya7jIKk6Umlgn9OAP+\n\tURYxDUHZYnP2OwCHWBeiT0v1I3LTln4CdjkN5Tcl9QYTiCaVr5Gwg4MMsUpIcE1PWw9e\n\trXbAOoUqg49On0BMYS1inaMk7UAAgf6NYn1sYeEO9B70jCNSbaHEMQSIWUSCEzEw+4yX\n\tTelpp+kvjYfZiY6nyR8P6HXsMj6qDEwXq53bWq0BMQN07szJX1HVSseXf+9y7ODx7fBu\n\tHoTQ==","X-Gm-Message-State":"AOJu0YyVwyoOtALrzEppY08t3kBJDsQUFbQCskIyOldV8EVHm90Spv4P\n\t4CyG7+an/Z6ABGfo2ZWU+8UcA58KkWgJRHfoLNIZZsXNS7Ieu2AfG2QXnzSf+Trc6qIIJYVo1qf\n\tXGhn9JYSS2Z7FpOk6SBwp/yU1/XVtiugqYn9CD32lIdT//yI=","X-Google-Smtp-Source":"AGHT+IGKMf4LeG79ZaQ997kx6oLYcsjx2vuE6xXdrg1nj/2QVeGLfREiEaRICKQTAq77RimBQst7+/dTmAlTW5uKLVo=","X-Received":"by 2002:a2e:5152:0:b0:2fb:3d86:d930 with SMTP id\n\t38308e7fff4ca-2fc9d614babmr40704431fa.39.1729870814393;\n\tFri, 25 Oct 2024 08:40:14 -0700 (PDT)","MIME-Version":"1.0","References":"<20241025053111.519449-1-chenghaoyang@chromium.org>\n\t<20241025053111.519449-2-chenghaoyang@chromium.org>\n\t<3vgjqpworr5ubynfli7otkghkf5xcqcugmybljvlvguiielndr@6j7ghkwncy5z>","In-Reply-To":"<3vgjqpworr5ubynfli7otkghkf5xcqcugmybljvlvguiielndr@6j7ghkwncy5z>","From":"Cheng-Hao Yang <chenghaoyang@chromium.org>","Date":"Fri, 25 Oct 2024 23:40:02 +0800","Message-ID":"<CAEB1ahsK8RCpRza+MspmhFon1CcLqQeqgFNCxDy3m6Jorf3=qw@mail.gmail.com>","Subject":"Re: [PATCH v3 1/2] libcamera: Extend u32 control type","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, \n\tYudhistira Erlandinata <yerlandinata@chromium.org>","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","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":31923,"web_url":"https://patchwork.libcamera.org/comment/31923/","msgid":"<mdk4ppatn34aehyfbhirgwgw2trnpxeqjgu7rscxfa3ivfmqts@jxa6slntylni>","date":"2024-10-25T16:46:51","subject":"Re: [PATCH v3 1/2] libcamera: Extend u32 control type","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Harvey\n\nOn Fri, Oct 25, 2024 at 11:40:02PM +0800, Cheng-Hao Yang wrote:\n> Hi Jacopo,\n>\n> On Fri, Oct 25, 2024 at 5:15 PM Jacopo Mondi\n> <jacopo.mondi@ideasonboard.com> wrote:\n> >\n> > Hi Harvey\n> >\n> > On Fri, Oct 25, 2024 at 05:30:13AM +0000, Harvey Yang wrote:\n> > > From: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> > >\n> > > V4L2 Controls support a wide variety of types not yet supported by the\n> > > ControlValue type system.\n> > >\n> > > Extend the libcamera ControlValue types to support an explicit 32 bit\n> > > unsigned integer type, and map that to the corresponding\n> > > V4L2_CTRL_TYPE_U32 type within the v4l2_device support class.\n> >\n> > V4L2_CTRL_TYPE_U32 is a control compound type.\n> >\n> >         /* Compound types are >= 0x0100 */\n> >         V4L2_CTRL_COMPOUND_TYPES     = 0x0100,\n> >         V4L2_CTRL_TYPE_U8            = 0x0100,\n> >         V4L2_CTRL_TYPE_U16           = 0x0101,\n> >         V4L2_CTRL_TYPE_U32           = 0x0102,\n> >         V4L2_CTRL_TYPE_AREA          = 0x0106,\n> >\n> > This means it carries a payload and needs to be handled like\n> > V4L2_CTRL_TYPE_U8 is, specifcially when it comes to parsing it from\n> > the V4L2 interface into a libcamera control.\n> >\n> > I'm surprised you don't hit this in V4L2Device::getControls()\n> >\n> >                 if (info.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {\n> >                         ControlType type;\n> >\n> >                         switch (info.type) {\n> >                         case V4L2_CTRL_TYPE_U8:\n> >                                 type = ControlTypeByte;\n> >                                 break;\n> >\n> >                         default:\n> >                                 LOG(V4L2, Error)\n> >                                         << \"Unsupported payload control type \"\n> >                                         << info.type;\n> >                                 return {};\n> >                         }\n> >\n>\n> Thanks! Added for U32 and U16.\n\nThank you.\n\nAny idea why\n\n                 LOG(V4L2, Error)\n                         << \"Unsupported payload control type \"\n                         << info.type;\n                 return {};\n\nwasn't hit ?\n\n>\n> > >\n> > > Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> > > Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>\n> > > Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>\n> > > ---\n> > >  include/libcamera/controls.h    |  7 ++++++\n> > >  src/libcamera/controls.cpp      | 12 ++++++++--\n> > >  src/libcamera/v4l2_device.cpp   | 13 +++++++++++\n> > >  test/controls/control_value.cpp | 40 +++++++++++++++++++++++++++++++++\n> > >  4 files changed, 70 insertions(+), 2 deletions(-)\n> > >\n> > > diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> > > index ca60bbaca..6da8ad2c3 100644\n> > > --- a/include/libcamera/controls.h\n> > > +++ b/include/libcamera/controls.h\n> > > @@ -29,6 +29,7 @@ enum ControlType {\n> > >       ControlTypeNone,\n> > >       ControlTypeBool,\n> > >       ControlTypeByte,\n> > > +     ControlTypeUnsigned32,\n> > >       ControlTypeInteger32,\n> > >       ControlTypeInteger64,\n> > >       ControlTypeFloat,\n> > > @@ -62,6 +63,12 @@ struct control_type<uint8_t> {\n> > >       static constexpr std::size_t size = 0;\n> > >  };\n> > >\n> > > +template<>\n> > > +struct control_type<uint32_t> {\n> > > +     static constexpr ControlType value = ControlTypeUnsigned32;\n> > > +     static constexpr std::size_t size = 0;\n> > > +};\n> > > +\n> > >  template<>\n> > >  struct control_type<int32_t> {\n> > >       static constexpr ControlType value = ControlTypeInteger32;\n> > > diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\n> > > index 62185d643..8ae295191 100644\n> > > --- a/src/libcamera/controls.cpp\n> > > +++ b/src/libcamera/controls.cpp\n> > > @@ -54,6 +54,7 @@ static constexpr size_t ControlValueSize[] = {\n> > >       [ControlTypeNone]               = 0,\n> > >       [ControlTypeBool]               = sizeof(bool),\n> > >       [ControlTypeByte]               = sizeof(uint8_t),\n> > > +     [ControlTypeUnsigned32]         = sizeof(uint32_t),\n> > >       [ControlTypeInteger32]          = sizeof(int32_t),\n> > >       [ControlTypeInteger64]          = sizeof(int64_t),\n> > >       [ControlTypeFloat]              = sizeof(float),\n> > > @@ -74,10 +75,12 @@ static constexpr size_t ControlValueSize[] = {\n> > >   * The control stores a boolean value\n> > >   * \\var ControlTypeByte\n> > >   * The control stores a byte value as an unsigned 8-bit integer\n> > > + * \\var ControlTypeUnsigned32\n> > > + * The control stores an unsigned 32-bit integer value\n> > >   * \\var ControlTypeInteger32\n> > > - * The control stores a 32-bit integer value\n> > > + * The control stores a signed 32-bit integer value\n> > >   * \\var ControlTypeInteger64\n> > > - * The control stores a 64-bit integer value\n> > > + * The control stores a signed 64-bit integer value\n> > >   * \\var ControlTypeFloat\n> > >   * The control stores a 32-bit floating point value\n> > >   * \\var ControlTypeString\n> > > @@ -230,6 +233,11 @@ std::string ControlValue::toString() const\n> > >                       str += std::to_string(*value);\n> > >                       break;\n> > >               }\n> > > +             case ControlTypeUnsigned32: {\n> > > +                     const uint32_t *value = reinterpret_cast<const uint32_t *>(data);\n> > > +                     str += std::to_string(*value);\n> > > +                     break;\n> > > +             }\n> > >               case ControlTypeInteger32: {\n> > >                       const int32_t *value = reinterpret_cast<const int32_t *>(data);\n> > >                       str += std::to_string(*value);\n> > > diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> > > index 68add4f2e..0ba8dcfa0 100644\n> > > --- a/src/libcamera/v4l2_device.cpp\n> > > +++ b/src/libcamera/v4l2_device.cpp\n> > > @@ -9,6 +9,7 @@\n> > >\n> > >  #include <fcntl.h>\n> > >  #include <map>\n> > > +#include <stdint.h>\n> > >  #include <stdlib.h>\n> > >  #include <string.h>\n> > >  #include <sys/ioctl.h>\n> > > @@ -17,11 +18,14 @@\n> > >  #include <vector>\n> > >\n> > >  #include <linux/v4l2-mediabus.h>\n> > > +#include <linux/videodev2.h>\n> >\n> > Included by the header file\n>\n> Removed.\n>\n> >\n> > >\n> > >  #include <libcamera/base/event_notifier.h>\n> > >  #include <libcamera/base/log.h>\n> > >  #include <libcamera/base/utils.h>\n> > >\n> > > +#include <libcamera/controls.h>\n> > > +\n> >\n> > This as well\n>\n> Removed.\n>\n> BR,\n> Harvey\n>\n> >\n> > >  #include \"libcamera/internal/formats.h\"\n> > >  #include \"libcamera/internal/sysfs.h\"\n> > >\n> > > @@ -488,6 +492,9 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType)\n> > >       case V4L2_CTRL_TYPE_BOOLEAN:\n> > >               return ControlTypeBool;\n> > >\n> > > +     case V4L2_CTRL_TYPE_U32:\n> > > +             return ControlTypeUnsigned32;\n> > > +\n> > >       case V4L2_CTRL_TYPE_INTEGER:\n> > >               return ControlTypeInteger32;\n> > >\n> > > @@ -536,6 +543,11 @@ std::optional<ControlInfo> V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl\n> > >                                  static_cast<uint8_t>(ctrl.maximum),\n> > >                                  static_cast<uint8_t>(ctrl.default_value));\n> > >\n> > > +     case V4L2_CTRL_TYPE_U32:\n> > > +             return ControlInfo(static_cast<uint32_t>(ctrl.minimum),\n> > > +                                static_cast<uint32_t>(ctrl.maximum),\n> > > +                                static_cast<uint32_t>(ctrl.default_value));\n> > > +\n> > >       case V4L2_CTRL_TYPE_BOOLEAN:\n> > >               return ControlInfo(static_cast<bool>(ctrl.minimum),\n> > >                                  static_cast<bool>(ctrl.maximum),\n> > > @@ -622,6 +634,7 @@ void V4L2Device::listControls()\n> > >               case V4L2_CTRL_TYPE_BITMASK:\n> > >               case V4L2_CTRL_TYPE_INTEGER_MENU:\n> > >               case V4L2_CTRL_TYPE_U8:\n> > > +             case V4L2_CTRL_TYPE_U32:\n> > >                       break;\n> > >               /* \\todo Support other control types. */\n> > >               default:\n> > > diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\n> > > index 344107fae..6ca85b739 100644\n> > > --- a/test/controls/control_value.cpp\n> > > +++ b/test/controls/control_value.cpp\n> > > @@ -109,6 +109,46 @@ protected:\n> > >                       return TestFail;\n> > >               }\n> > >\n> > > +             /*\n> > > +              * Unsigned Integer32 type.\n> > > +              */\n> > > +             value.set(static_cast<uint32_t>(42));\n> > > +             if (value.isNone() || value.isArray() ||\n> > > +                 value.type() != ControlTypeUnsigned32) {\n> > > +                     cerr << \"Control type mismatch after setting to uint32_t\" << endl;\n> > > +                     return TestFail;\n> > > +             }\n> > > +\n> > > +             if (value.get<uint32_t>() != 42) {\n> > > +                     cerr << \"Control value mismatch after setting to uint32_t\" << endl;\n> > > +                     return TestFail;\n> > > +             }\n> > > +\n> > > +             if (value.toString() != \"42\") {\n> > > +                     cerr << \"Control string mismatch after setting to uint32_t\" << endl;\n> > > +                     return TestFail;\n> > > +             }\n> > > +\n> > > +             std::array<uint32_t, 4> uint32s{ 3, 14, 15, 9 };\n> > > +             value.set(Span<uint32_t>(uint32s));\n> > > +             if (value.isNone() || !value.isArray() ||\n> > > +                 value.type() != ControlTypeUnsigned32) {\n> > > +                     cerr << \"Control type mismatch after setting to uint32_t array\" << endl;\n> > > +                     return TestFail;\n> > > +             }\n> > > +\n> > > +             Span<const uint32_t> uint32sResult = value.get<Span<const uint32_t>>();\n> > > +             if (uint32s.size() != uint32sResult.size() ||\n> > > +                 !std::equal(uint32s.begin(), uint32s.end(), uint32sResult.begin())) {\n> > > +                     cerr << \"Control value mismatch after setting to uint32_t array\" << endl;\n> > > +                     return TestFail;\n> > > +             }\n> > > +\n> > > +             if (value.toString() != \"[ 3, 14, 15, 9 ]\") {\n> > > +                     cerr << \"Control string mismatch after setting to uint32_t array\" << endl;\n> > > +                     return TestFail;\n> > > +             }\n> > > +\n> > >               /*\n> > >                * Integer32 type.\n> > >                */\n> > > --\n> > > 2.47.0.163.g1226f6d8fa-goog\n> > >","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 4B64BC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 25 Oct 2024 16:46:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5D9B265398;\n\tFri, 25 Oct 2024 18:46:57 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B7E946538B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Oct 2024 18:46:55 +0200 (CEST)","from ideasonboard.com (93-61-96-190.ip145.fastwebnet.it\n\t[93.61.96.190])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B76B274C;\n\tFri, 25 Oct 2024 18:45:06 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"cXOFV9YC\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1729874706;\n\tbh=Ffy4DsugfiB0HTLyn6/UyVFDwolErQSqojohSbHzdnM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=cXOFV9YCCN01uL5E+PLAYqsX+zw6mk8YrauFjR43PbtNomAKmADIGhiLVO3H1nWwh\n\tW339Tw5dqnZSa+hTe0piuCXsuOFtKwthu+oXVelR0ZIrrzhCPns1zqN8X/AjKb3n85\n\txUnUvhCZIjInBNFuA6WsKlhufalN6evQj0MJiLXE=","Date":"Fri, 25 Oct 2024 18:46:51 +0200","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Cheng-Hao Yang <chenghaoyang@chromium.org>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org,\n\tYudhistira Erlandinata <yerlandinata@chromium.org>","Subject":"Re: [PATCH v3 1/2] libcamera: Extend u32 control type","Message-ID":"<mdk4ppatn34aehyfbhirgwgw2trnpxeqjgu7rscxfa3ivfmqts@jxa6slntylni>","References":"<20241025053111.519449-1-chenghaoyang@chromium.org>\n\t<20241025053111.519449-2-chenghaoyang@chromium.org>\n\t<3vgjqpworr5ubynfli7otkghkf5xcqcugmybljvlvguiielndr@6j7ghkwncy5z>\n\t<CAEB1ahsK8RCpRza+MspmhFon1CcLqQeqgFNCxDy3m6Jorf3=qw@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<CAEB1ahsK8RCpRza+MspmhFon1CcLqQeqgFNCxDy3m6Jorf3=qw@mail.gmail.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":31924,"web_url":"https://patchwork.libcamera.org/comment/31924/","msgid":"<CAEB1ahud9Y4UHawZ_TQ7s_oRovBS5gpm1AWsSSAUYCEtxk8D+Q@mail.gmail.com>","date":"2024-10-25T17:40:09","subject":"Re: [PATCH v3 1/2] libcamera: Extend u32 control type","submitter":{"id":117,"url":"https://patchwork.libcamera.org/api/people/117/","name":"Cheng-Hao Yang","email":"chenghaoyang@chromium.org"},"content":"Hi Jacopo,\n\nOn Sat, Oct 26, 2024 at 12:46 AM Jacopo Mondi\n<jacopo.mondi@ideasonboard.com> wrote:\n>\n> Hi Harvey\n>\n> On Fri, Oct 25, 2024 at 11:40:02PM +0800, Cheng-Hao Yang wrote:\n> > Hi Jacopo,\n> >\n> > On Fri, Oct 25, 2024 at 5:15 PM Jacopo Mondi\n> > <jacopo.mondi@ideasonboard.com> wrote:\n> > >\n> > > Hi Harvey\n> > >\n> > > On Fri, Oct 25, 2024 at 05:30:13AM +0000, Harvey Yang wrote:\n> > > > From: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> > > >\n> > > > V4L2 Controls support a wide variety of types not yet supported by the\n> > > > ControlValue type system.\n> > > >\n> > > > Extend the libcamera ControlValue types to support an explicit 32 bit\n> > > > unsigned integer type, and map that to the corresponding\n> > > > V4L2_CTRL_TYPE_U32 type within the v4l2_device support class.\n> > >\n> > > V4L2_CTRL_TYPE_U32 is a control compound type.\n> > >\n> > >         /* Compound types are >= 0x0100 */\n> > >         V4L2_CTRL_COMPOUND_TYPES     = 0x0100,\n> > >         V4L2_CTRL_TYPE_U8            = 0x0100,\n> > >         V4L2_CTRL_TYPE_U16           = 0x0101,\n> > >         V4L2_CTRL_TYPE_U32           = 0x0102,\n> > >         V4L2_CTRL_TYPE_AREA          = 0x0106,\n> > >\n> > > This means it carries a payload and needs to be handled like\n> > > V4L2_CTRL_TYPE_U8 is, specifcially when it comes to parsing it from\n> > > the V4L2 interface into a libcamera control.\n> > >\n> > > I'm surprised you don't hit this in V4L2Device::getControls()\n> > >\n> > >                 if (info.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {\n> > >                         ControlType type;\n> > >\n> > >                         switch (info.type) {\n> > >                         case V4L2_CTRL_TYPE_U8:\n> > >                                 type = ControlTypeByte;\n> > >                                 break;\n> > >\n> > >                         default:\n> > >                                 LOG(V4L2, Error)\n> > >                                         << \"Unsupported payload control type \"\n> > >                                         << info.type;\n> > >                                 return {};\n> > >                         }\n> > >\n> >\n> > Thanks! Added for U32 and U16.\n>\n> Thank you.\n>\n> Any idea why\n>\n>                  LOG(V4L2, Error)\n>                          << \"Unsupported payload control type \"\n>                          << info.type;\n>                  return {};\n>\n> wasn't hit ?\n\nI think the original purpose of adding it is not for getControls/setControls:\nhttps://chromium-review.googlesource.com/c/chromiumos/third_party/libcamera/+/5669226/1//COMMIT_MSG#12\n\nBR,\nHarvey\n\n>\n> >\n> > > >\n> > > > Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>\n> > > > Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>\n> > > > Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>\n> > > > ---\n> > > >  include/libcamera/controls.h    |  7 ++++++\n> > > >  src/libcamera/controls.cpp      | 12 ++++++++--\n> > > >  src/libcamera/v4l2_device.cpp   | 13 +++++++++++\n> > > >  test/controls/control_value.cpp | 40 +++++++++++++++++++++++++++++++++\n> > > >  4 files changed, 70 insertions(+), 2 deletions(-)\n> > > >\n> > > > diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\n> > > > index ca60bbaca..6da8ad2c3 100644\n> > > > --- a/include/libcamera/controls.h\n> > > > +++ b/include/libcamera/controls.h\n> > > > @@ -29,6 +29,7 @@ enum ControlType {\n> > > >       ControlTypeNone,\n> > > >       ControlTypeBool,\n> > > >       ControlTypeByte,\n> > > > +     ControlTypeUnsigned32,\n> > > >       ControlTypeInteger32,\n> > > >       ControlTypeInteger64,\n> > > >       ControlTypeFloat,\n> > > > @@ -62,6 +63,12 @@ struct control_type<uint8_t> {\n> > > >       static constexpr std::size_t size = 0;\n> > > >  };\n> > > >\n> > > > +template<>\n> > > > +struct control_type<uint32_t> {\n> > > > +     static constexpr ControlType value = ControlTypeUnsigned32;\n> > > > +     static constexpr std::size_t size = 0;\n> > > > +};\n> > > > +\n> > > >  template<>\n> > > >  struct control_type<int32_t> {\n> > > >       static constexpr ControlType value = ControlTypeInteger32;\n> > > > diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\n> > > > index 62185d643..8ae295191 100644\n> > > > --- a/src/libcamera/controls.cpp\n> > > > +++ b/src/libcamera/controls.cpp\n> > > > @@ -54,6 +54,7 @@ static constexpr size_t ControlValueSize[] = {\n> > > >       [ControlTypeNone]               = 0,\n> > > >       [ControlTypeBool]               = sizeof(bool),\n> > > >       [ControlTypeByte]               = sizeof(uint8_t),\n> > > > +     [ControlTypeUnsigned32]         = sizeof(uint32_t),\n> > > >       [ControlTypeInteger32]          = sizeof(int32_t),\n> > > >       [ControlTypeInteger64]          = sizeof(int64_t),\n> > > >       [ControlTypeFloat]              = sizeof(float),\n> > > > @@ -74,10 +75,12 @@ static constexpr size_t ControlValueSize[] = {\n> > > >   * The control stores a boolean value\n> > > >   * \\var ControlTypeByte\n> > > >   * The control stores a byte value as an unsigned 8-bit integer\n> > > > + * \\var ControlTypeUnsigned32\n> > > > + * The control stores an unsigned 32-bit integer value\n> > > >   * \\var ControlTypeInteger32\n> > > > - * The control stores a 32-bit integer value\n> > > > + * The control stores a signed 32-bit integer value\n> > > >   * \\var ControlTypeInteger64\n> > > > - * The control stores a 64-bit integer value\n> > > > + * The control stores a signed 64-bit integer value\n> > > >   * \\var ControlTypeFloat\n> > > >   * The control stores a 32-bit floating point value\n> > > >   * \\var ControlTypeString\n> > > > @@ -230,6 +233,11 @@ std::string ControlValue::toString() const\n> > > >                       str += std::to_string(*value);\n> > > >                       break;\n> > > >               }\n> > > > +             case ControlTypeUnsigned32: {\n> > > > +                     const uint32_t *value = reinterpret_cast<const uint32_t *>(data);\n> > > > +                     str += std::to_string(*value);\n> > > > +                     break;\n> > > > +             }\n> > > >               case ControlTypeInteger32: {\n> > > >                       const int32_t *value = reinterpret_cast<const int32_t *>(data);\n> > > >                       str += std::to_string(*value);\n> > > > diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> > > > index 68add4f2e..0ba8dcfa0 100644\n> > > > --- a/src/libcamera/v4l2_device.cpp\n> > > > +++ b/src/libcamera/v4l2_device.cpp\n> > > > @@ -9,6 +9,7 @@\n> > > >\n> > > >  #include <fcntl.h>\n> > > >  #include <map>\n> > > > +#include <stdint.h>\n> > > >  #include <stdlib.h>\n> > > >  #include <string.h>\n> > > >  #include <sys/ioctl.h>\n> > > > @@ -17,11 +18,14 @@\n> > > >  #include <vector>\n> > > >\n> > > >  #include <linux/v4l2-mediabus.h>\n> > > > +#include <linux/videodev2.h>\n> > >\n> > > Included by the header file\n> >\n> > Removed.\n> >\n> > >\n> > > >\n> > > >  #include <libcamera/base/event_notifier.h>\n> > > >  #include <libcamera/base/log.h>\n> > > >  #include <libcamera/base/utils.h>\n> > > >\n> > > > +#include <libcamera/controls.h>\n> > > > +\n> > >\n> > > This as well\n> >\n> > Removed.\n> >\n> > BR,\n> > Harvey\n> >\n> > >\n> > > >  #include \"libcamera/internal/formats.h\"\n> > > >  #include \"libcamera/internal/sysfs.h\"\n> > > >\n> > > > @@ -488,6 +492,9 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType)\n> > > >       case V4L2_CTRL_TYPE_BOOLEAN:\n> > > >               return ControlTypeBool;\n> > > >\n> > > > +     case V4L2_CTRL_TYPE_U32:\n> > > > +             return ControlTypeUnsigned32;\n> > > > +\n> > > >       case V4L2_CTRL_TYPE_INTEGER:\n> > > >               return ControlTypeInteger32;\n> > > >\n> > > > @@ -536,6 +543,11 @@ std::optional<ControlInfo> V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl\n> > > >                                  static_cast<uint8_t>(ctrl.maximum),\n> > > >                                  static_cast<uint8_t>(ctrl.default_value));\n> > > >\n> > > > +     case V4L2_CTRL_TYPE_U32:\n> > > > +             return ControlInfo(static_cast<uint32_t>(ctrl.minimum),\n> > > > +                                static_cast<uint32_t>(ctrl.maximum),\n> > > > +                                static_cast<uint32_t>(ctrl.default_value));\n> > > > +\n> > > >       case V4L2_CTRL_TYPE_BOOLEAN:\n> > > >               return ControlInfo(static_cast<bool>(ctrl.minimum),\n> > > >                                  static_cast<bool>(ctrl.maximum),\n> > > > @@ -622,6 +634,7 @@ void V4L2Device::listControls()\n> > > >               case V4L2_CTRL_TYPE_BITMASK:\n> > > >               case V4L2_CTRL_TYPE_INTEGER_MENU:\n> > > >               case V4L2_CTRL_TYPE_U8:\n> > > > +             case V4L2_CTRL_TYPE_U32:\n> > > >                       break;\n> > > >               /* \\todo Support other control types. */\n> > > >               default:\n> > > > diff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\n> > > > index 344107fae..6ca85b739 100644\n> > > > --- a/test/controls/control_value.cpp\n> > > > +++ b/test/controls/control_value.cpp\n> > > > @@ -109,6 +109,46 @@ protected:\n> > > >                       return TestFail;\n> > > >               }\n> > > >\n> > > > +             /*\n> > > > +              * Unsigned Integer32 type.\n> > > > +              */\n> > > > +             value.set(static_cast<uint32_t>(42));\n> > > > +             if (value.isNone() || value.isArray() ||\n> > > > +                 value.type() != ControlTypeUnsigned32) {\n> > > > +                     cerr << \"Control type mismatch after setting to uint32_t\" << endl;\n> > > > +                     return TestFail;\n> > > > +             }\n> > > > +\n> > > > +             if (value.get<uint32_t>() != 42) {\n> > > > +                     cerr << \"Control value mismatch after setting to uint32_t\" << endl;\n> > > > +                     return TestFail;\n> > > > +             }\n> > > > +\n> > > > +             if (value.toString() != \"42\") {\n> > > > +                     cerr << \"Control string mismatch after setting to uint32_t\" << endl;\n> > > > +                     return TestFail;\n> > > > +             }\n> > > > +\n> > > > +             std::array<uint32_t, 4> uint32s{ 3, 14, 15, 9 };\n> > > > +             value.set(Span<uint32_t>(uint32s));\n> > > > +             if (value.isNone() || !value.isArray() ||\n> > > > +                 value.type() != ControlTypeUnsigned32) {\n> > > > +                     cerr << \"Control type mismatch after setting to uint32_t array\" << endl;\n> > > > +                     return TestFail;\n> > > > +             }\n> > > > +\n> > > > +             Span<const uint32_t> uint32sResult = value.get<Span<const uint32_t>>();\n> > > > +             if (uint32s.size() != uint32sResult.size() ||\n> > > > +                 !std::equal(uint32s.begin(), uint32s.end(), uint32sResult.begin())) {\n> > > > +                     cerr << \"Control value mismatch after setting to uint32_t array\" << endl;\n> > > > +                     return TestFail;\n> > > > +             }\n> > > > +\n> > > > +             if (value.toString() != \"[ 3, 14, 15, 9 ]\") {\n> > > > +                     cerr << \"Control string mismatch after setting to uint32_t array\" << endl;\n> > > > +                     return TestFail;\n> > > > +             }\n> > > > +\n> > > >               /*\n> > > >                * Integer32 type.\n> > > >                */\n> > > > --\n> > > > 2.47.0.163.g1226f6d8fa-goog\n> > > >","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 1CB2AC3226\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 25 Oct 2024 17:40:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0DD5565398;\n\tFri, 25 Oct 2024 19:40:23 +0200 (CEST)","from mail-lj1-x22e.google.com (mail-lj1-x22e.google.com\n\t[IPv6:2a00:1450:4864:20::22e])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 90B176538B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Oct 2024 19:40:21 +0200 (CEST)","by mail-lj1-x22e.google.com with SMTP id\n\t38308e7fff4ca-2fb57f97d75so20696081fa.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Oct 2024 10:40:21 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"oCTOgoOe\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=chromium.org; s=google; t=1729878021; x=1730482821;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=Jm0WmsCMbV2vDlsqu+SpDPfWVnN/6Pvn2qRzyObstHo=;\n\tb=oCTOgoOe9uI0uzKMnCJAbzSq/ZgOxB++e/GH26UxfUXzVrm8tel/DYtM3zfrsox+NJ\n\t+Hb2Ky7ullxHcV8oXDeqbRjco18B8iULc5RDdmSNtQ9Cq5n7Ch9RPyzMiUtpL9MufYSX\n\tE/nlVtTfmXHxKzhq5il+bUVhBOf9MLjMOZQH4=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1729878021; x=1730482821;\n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=Jm0WmsCMbV2vDlsqu+SpDPfWVnN/6Pvn2qRzyObstHo=;\n\tb=a2VUeU0TXJPgHEPREnLw/bTJgAgkG0Joym+hdhHrzcDsyWdWIpG6Ea31k01l0rimZA\n\to8LY/WM0OYLBuj7DWjKh+Nftd8n3sBYTEbfSaUoWCD43wSjEJ7ED7AF7LwBshauJGj5V\n\tE6UY4D/ji3gU/gBW0kEbzYUTPoDNLZxXLuXAcaR/P1c9bAoJ9z98G8dLrRw5ieOFiQR1\n\txy0m77dXzUvdExSHKHwjwXDDqyvgiHRJlFPuRKqd0VUIXNdoLpwuIKg+Y8qpU9DMR8LH\n\tWK7sX0FSVLai7sDQJmAp4vEbQAo9kc8ClqkUJ/qk9BbSxqhG+J5MGMqdRs12danHpMO5\n\txFkw==","X-Gm-Message-State":"AOJu0Yza1lIe10K6MDGISWS0nSQiFv4g1vR+1ac9lO7+cpnDbfj2eQu2\n\tXUC5ROP7LiF5frQcnozI/a9v9oZspiqT3YDkaKrjKK3THRYVw+xq64MsAbjprd4Q2no03pWyn37\n\tykoGrx07z+H+MmZ+JrDc19RumdXfPNT/UjYWB","X-Google-Smtp-Source":"AGHT+IGKt9KFh2bmt+w7XRVkn3re8I/QOVm/1eXED8J1NYYDwBtMwbuIECbLmR7txTvs1UQlsTvhAEn/2uaGZP5gQx0=","X-Received":"by 2002:a05:651c:507:b0:2fc:a347:6d90 with SMTP id\n\t38308e7fff4ca-2fcbdfe2dcbmr594231fa.27.1729878020501; Fri, 25 Oct 2024\n\t10:40:20 -0700 (PDT)","MIME-Version":"1.0","References":"<20241025053111.519449-1-chenghaoyang@chromium.org>\n\t<20241025053111.519449-2-chenghaoyang@chromium.org>\n\t<3vgjqpworr5ubynfli7otkghkf5xcqcugmybljvlvguiielndr@6j7ghkwncy5z>\n\t<CAEB1ahsK8RCpRza+MspmhFon1CcLqQeqgFNCxDy3m6Jorf3=qw@mail.gmail.com>\n\t<mdk4ppatn34aehyfbhirgwgw2trnpxeqjgu7rscxfa3ivfmqts@jxa6slntylni>","In-Reply-To":"<mdk4ppatn34aehyfbhirgwgw2trnpxeqjgu7rscxfa3ivfmqts@jxa6slntylni>","From":"Cheng-Hao Yang <chenghaoyang@chromium.org>","Date":"Sat, 26 Oct 2024 01:40:09 +0800","Message-ID":"<CAEB1ahud9Y4UHawZ_TQ7s_oRovBS5gpm1AWsSSAUYCEtxk8D+Q@mail.gmail.com>","Subject":"Re: [PATCH v3 1/2] libcamera: Extend u32 control type","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, \n\tYudhistira Erlandinata <yerlandinata@chromium.org>","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","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>"}}]