[{"id":17737,"web_url":"https://patchwork.libcamera.org/comment/17737/","msgid":"<YNR9DRSY7S73hGAt@pendragon.ideasonboard.com>","date":"2021-06-24T12:39:41","subject":"Re: [libcamera-devel] [RFC PATCH v2 1/3] android: Add helpers for\n\tsetting android metadata from libcamera controls","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Paul,\n\nThank you for the patch.\n\nOn Thu, Jun 24, 2021 at 07:50:52PM +0900, Paul Elder wrote:\n> Add helpers for setting android metadata from libcamera controls.\n> \n> There are two versions, for scalars and collections, both of which take\n> a default value to fill in the android control if the libcamera control\n> is not found. A version for scalars exists for no default, to not set\n> the android control at all if it is not found in libcamera. The last one\n> requires the type to be specified, but the other two do not.\n> \n> The versions that take a default value return the value that was set in\n> the android metadata.\n> \n> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> \n> ---\n> New in v2\n> \n> TODO: make ControlList versions so that we can use them in result\n> metadata\n> ---\n>  src/android/camera_capabilities.cpp | 81 +++++++++++++++++++++++++++++\n>  1 file changed, 81 insertions(+)\n> \n> diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp\n> index 00224a6d..7d795bf5 100644\n> --- a/src/android/camera_capabilities.cpp\n> +++ b/src/android/camera_capabilities.cpp\n> @@ -113,6 +113,87 @@ const std::map<int, const Camera3Format> camera3FormatsMap = {\n>  \t},\n>  };\n>  \n> +enum ControlRange {\n> +\tMin,\n> +\tDef,\n> +\tMax,\n> +};\n> +\n> +template<typename T,\n> +\t std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>\n> +void setMetadata(CameraMetadata *metadata, uint32_t tag,\n> +\t\t const ControlInfoMap &controlsInfo, const ControlId *control,\n> +\t\t enum ControlRange controlRange)\n> +{\n> +\tconst auto &info = controlsInfo.find(control);\n> +\tif (info == controlsInfo.end())\n> +\t\treturn;\n> +\n> +\tT ret;\n> +\tswitch (controlRange) {\n> +\tcase Min:\n> +\t\tret = info->second.min().get<T>();\n> +\t\tbreak;\n> +\tcase Def:\n> +\t\tret = info->second.def().get<T>();\n> +\t\tbreak;\n> +\tcase Max:\n> +\t\tret = info->second.max().get<T>();\n> +\t\tbreak;\n> +\t}\n> +\n> +\tmetadata->addEntry(tag, ret);\n> +\treturn;\n> +}\n> +\n> +template<typename T,\n> +\t std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>\n> +T setMetadata(CameraMetadata *metadata, uint32_t tag,\n> +\t      const ControlInfoMap &controlsInfo, const ControlId *control,\n> +\t      const T defaultValue, enum ControlRange controlRange)\n> +{\n> +\tT ret = defaultValue;\n> +\n> +\tconst auto &info = controlsInfo.find(control);\n> +\tif (info != controlsInfo.end()) {\n> +\t\tswitch (controlRange) {\n> +\t\tcase Min:\n> +\t\t\tret = info->second.min().get<T>();\n> +\t\t\tbreak;\n> +\t\tcase Def:\n> +\t\t\tret = info->second.def().get<T>();\n> +\t\t\tbreak;\n> +\t\tcase Max:\n> +\t\t\tret = info->second.max().get<T>();\n> +\t\t\tbreak;\n> +\t\t}\n> +\t}\n> +\n> +\tmetadata->addEntry(tag, ret);\n> +\treturn ret;\n> +}\n> +\n> +template<typename S,\n> +\t typename T = typename S::value_type>\n> +S setMetadata(CameraMetadata *metadata, uint32_t tag,\n> +\t      const ControlInfoMap &controlsInfo, const ControlId *control,\n> +\t      const S &defaultVector)\n\nIf S is required to be a vector, could this be\n\ntemplate<typename T>,\nstd::vector<T> setMetadata(CameraMetadata *metadata, uint32_t tag,\n\t\t\t   const ControlInfoMap &controlsInfo,\n\t\t\t   const ControlId *control,\n\t\t\t   const std::vector<T> &defaultVector)\n\n> +{\n> +\tstd::vector<T> ret = {};\n> +\n> +\tconst auto &info = controlsInfo.find(control);\n> +\tif (info != controlsInfo.end()) {\n> +\t\tret.reserve(info->second.values().size());\n> +\t\tfor (const auto &value : info->second.values())\n> +\t\t\tret.push_back(value.get<T>());\n> +\t} else {\n> +\t\tret = defaultVector;\n> +\t}\n> +\n> +\tmetadata->addEntry(tag, ret);\n> +\treturn ret;\n> +}\n> +\n>  } /* namespace */\n>  \n>  int CameraCapabilities::initialize(std::shared_ptr<libcamera::Camera> camera,","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 9F554C321B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 24 Jun 2021 12:40:14 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EAD8868447;\n\tThu, 24 Jun 2021 14:40:13 +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 72E476050B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 24 Jun 2021 14:40:12 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id DA9D5532;\n\tThu, 24 Jun 2021 14:40:11 +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=\"VhtKZkfq\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1624538412;\n\tbh=cOYxtHMLPKRnrFTAMlXQroZw+TgC4YPdgBCg5NGflaU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=VhtKZkfqCiAFZCzbTEy6/oQyeA35EETC18YmQ1mM1ggRL2wBsbMRlNW8MirvIBxQb\n\ttbISt+Jspll+rzCXim+9AKHe5AVXffmZgUad7TsxQbsTLnmfy0LnXzjxRRIvimIDe/\n\tMYoEtqMxK0TCNSWkpz7BH27BDO+0iYYiZ8x8BMIo=","Date":"Thu, 24 Jun 2021 15:39:41 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Paul Elder <paul.elder@ideasonboard.com>","Message-ID":"<YNR9DRSY7S73hGAt@pendragon.ideasonboard.com>","References":"<20210624105054.51700-1-paul.elder@ideasonboard.com>\n\t<20210624105054.51700-2-paul.elder@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210624105054.51700-2-paul.elder@ideasonboard.com>","Subject":"Re: [libcamera-devel] [RFC PATCH v2 1/3] android: Add helpers for\n\tsetting android metadata from libcamera controls","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":17771,"web_url":"https://patchwork.libcamera.org/comment/17771/","msgid":"<CAO5uPHOv=MJ7AP+QKqoFEpnhVFHse1N4-6uLYDrd6hEZDrjOwQ@mail.gmail.com>","date":"2021-06-25T04:43:39","subject":"Re: [libcamera-devel] [RFC PATCH v2 1/3] android: Add helpers for\n\tsetting android metadata from libcamera controls","submitter":{"id":63,"url":"https://patchwork.libcamera.org/api/people/63/","name":"Hirokazu Honda","email":"hiroh@chromium.org"},"content":"Hi Paul,\n\nOn Thu, Jun 24, 2021 at 9:40 PM Laurent Pinchart\n<laurent.pinchart@ideasonboard.com> wrote:\n>\n> Hi Paul,\n>\n> Thank you for the patch.\n>\n> On Thu, Jun 24, 2021 at 07:50:52PM +0900, Paul Elder wrote:\n> > Add helpers for setting android metadata from libcamera controls.\n> >\n> > There are two versions, for scalars and collections, both of which take\n> > a default value to fill in the android control if the libcamera control\n> > is not found. A version for scalars exists for no default, to not set\n> > the android control at all if it is not found in libcamera. The last one\n> > requires the type to be specified, but the other two do not.\n> >\n> > The versions that take a default value return the value that was set in\n> > the android metadata.\n> >\n> > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>\n> >\n> > ---\n> > New in v2\n> >\n> > TODO: make ControlList versions so that we can use them in result\n> > metadata\n> > ---\n> >  src/android/camera_capabilities.cpp | 81 +++++++++++++++++++++++++++++\n> >  1 file changed, 81 insertions(+)\n> >\n> > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp\n> > index 00224a6d..7d795bf5 100644\n> > --- a/src/android/camera_capabilities.cpp\n> > +++ b/src/android/camera_capabilities.cpp\n> > @@ -113,6 +113,87 @@ const std::map<int, const Camera3Format> camera3FormatsMap = {\n> >       },\n> >  };\n> >\n> > +enum ControlRange {\nnit: enum class\n\n> > +     Min,\n> > +     Def,\n> > +     Max,\n> > +};\n> > +\n> > +template<typename T,\n> > +      std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>\n\nPerhaps std::enable_if_t<std::is_arithmetic_v<T>::value, bool> = true?\n\n> > +void setMetadata(CameraMetadata *metadata, uint32_t tag,\n> > +              const ControlInfoMap &controlsInfo, const ControlId *control,\n> > +              enum ControlRange controlRange)\n> > +{\n> > +     const auto &info = controlsInfo.find(control);\n> > +     if (info == controlsInfo.end())\n> > +             return;\n> > +\n> > +     T ret;\n> > +     switch (controlRange) {\n> > +     case Min:\n> > +             ret = info->second.min().get<T>();\n> > +             break;\n> > +     case Def:\n> > +             ret = info->second.def().get<T>();\n> > +             break;\n> > +     case Max:\n> > +             ret = info->second.max().get<T>();\n> > +             break;\n> > +     }\n> > +\n> > +     metadata->addEntry(tag, ret);\n> > +     return;\n> > +}\n> > +\n> > +template<typename T,\n> > +      std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>\n> > +T setMetadata(CameraMetadata *metadata, uint32_t tag,\n> > +           const ControlInfoMap &controlsInfo, const ControlId *control,\n> > +           const T defaultValue, enum ControlRange controlRange)\n\nnit: I would put defaultValue to the last argument.\n\n> > +{\n> > +     T ret = defaultValue;\n> > +\n> > +     const auto &info = controlsInfo.find(control);\n> > +     if (info != controlsInfo.end()) {\n> > +             switch (controlRange) {\n> > +             case Min:\n> > +                     ret = info->second.min().get<T>();\n> > +                     break;\n> > +             case Def:\n> > +                     ret = info->second.def().get<T>();\n> > +                     break;\n> > +             case Max:\n> > +                     ret = info->second.max().get<T>();\n> > +                     break;\n> > +             }\n> > +     }\n> > +\n> > +     metadata->addEntry(tag, ret);\n> > +     return ret;\n> > +}\n> > +\n> > +template<typename S,\n> > +      typename T = typename S::value_type>\n> > +S setMetadata(CameraMetadata *metadata, uint32_t tag,\n> > +           const ControlInfoMap &controlsInfo, const ControlId *control,\n> > +           const S &defaultVector)\n>\n> If S is required to be a vector, could this be\n>\n> template<typename T>,\n> std::vector<T> setMetadata(CameraMetadata *metadata, uint32_t tag,\n>                            const ControlInfoMap &controlsInfo,\n>                            const ControlId *control,\n>                            const std::vector<T> &defaultVector)\n>\n> > +{\n> > +     std::vector<T> ret = {};\n> > +\n> > +     const auto &info = controlsInfo.find(control);\n> > +     if (info != controlsInfo.end()) {\n> > +             ret.reserve(info->second.values().size());\n> > +             for (const auto &value : info->second.values())\n> > +                     ret.push_back(value.get<T>());\n> > +     } else {\n> > +             ret = defaultVector;\n> > +     }\n> > +\n> > +     metadata->addEntry(tag, ret);\n> > +     return ret;\n> > +}\n> > +\n> >  } /* namespace */\n> >\n> >  int CameraCapabilities::initialize(std::shared_ptr<libcamera::Camera> camera,\n>\n> --\n> Regards,\n>\n> Laurent 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 37061C321A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 25 Jun 2021 04:43:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9F82E684CE;\n\tFri, 25 Jun 2021 06:43:50 +0200 (CEST)","from mail-ej1-x629.google.com (mail-ej1-x629.google.com\n\t[IPv6:2a00:1450:4864:20::629])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B69B684C9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Jun 2021 06:43:50 +0200 (CEST)","by mail-ej1-x629.google.com with SMTP id hc16so12917646ejc.12\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 24 Jun 2021 21:43:50 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"NoseHwBD\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=y2rfdAEdBLcsoiKBdZz2C1AxLCZ584HY6KOlzZJJ0sM=;\n\tb=NoseHwBDXfqFKo1XrcuvTFK8crxN/Jhye5jzz0+2qPwsf6JV4IJBazZKlpaLFtNSN0\n\tt175YwecCqrWs4fLgtpBwVhUk0/RU5cINsWJaGp6sw5ueAYwYyaHMMz8+ztO7sc1iRPC\n\tFR3yPvPF6HmVFMVt+tmy9lylD7dps+bLBcsaM=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=y2rfdAEdBLcsoiKBdZz2C1AxLCZ584HY6KOlzZJJ0sM=;\n\tb=C53ZUBqY6amXrTGgdQX1fGstADQ+j836sQsOz8OkzhIqGQJo87ZgbqvU5f7SamL9YF\n\tmYT97gQ9mRPgt6SlQcpj5wbx/BhgAJ4jjA+zthE1sCX8z+8BvBwBB9gOAsRN9oQM5DUP\n\tYEL2PJfy4GYxnwYytJgpHM5foa1r81vXBfX1+cYIhe3vSbQA6YEiaqjf0K42h6zuTZvj\n\tjMdgl8COUhEiH/yUDGjVvaT1R63zy4uYAg+rJuUYJK7lwjuj8ldN4sZnwfGLsdDM7Jg6\n\tA5lR3b6yu7TsZDcMTwqe9vwgb1M8C6pqBW1TQN3PWe3YXXKp0O6bMWO8eAHC2NzMKRFE\n\tzLZg==","X-Gm-Message-State":"AOAM532Rk2WBdkuTHMqfeu/odw3d7rje2AdBOLqMVB6AqjcVvqAX2m04\n\tSZuExpUxf5KBeZgiMFKYJMvn7q36OhmEnRTy4i1nFtOG23GIBQ==","X-Google-Smtp-Source":"ABdhPJz0cZC9ECvSFZMJA1YiO4p8ypT0qseycSMuFOADWTsyEe5xdt4HpOzI6+BR1ygUBijxBKBA/FGY7kxiUiGSZWU=","X-Received":"by 2002:a17:906:a20b:: with SMTP id\n\tr11mr8673147ejy.221.1624596229731; \n\tThu, 24 Jun 2021 21:43:49 -0700 (PDT)","MIME-Version":"1.0","References":"<20210624105054.51700-1-paul.elder@ideasonboard.com>\n\t<20210624105054.51700-2-paul.elder@ideasonboard.com>\n\t<YNR9DRSY7S73hGAt@pendragon.ideasonboard.com>","In-Reply-To":"<YNR9DRSY7S73hGAt@pendragon.ideasonboard.com>","From":"Hirokazu Honda <hiroh@chromium.org>","Date":"Fri, 25 Jun 2021 13:43:39 +0900","Message-ID":"<CAO5uPHOv=MJ7AP+QKqoFEpnhVFHse1N4-6uLYDrd6hEZDrjOwQ@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [RFC PATCH v2 1/3] android: Add helpers for\n\tsetting android metadata from libcamera controls","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>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]