[{"id":10865,"web_url":"https://patchwork.libcamera.org/comment/10865/","msgid":"<20200626004105.GM5865@pendragon.ideasonboard.com>","date":"2020-06-26T00:41:05","subject":"Re: [libcamera-devel] [PATCH v4 6/9] libcamera: ipu3: cio2: Add\n\tfunction to generate configuration","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Niklas,\n\nThank you for the patch.\n\nOn Fri, Jun 26, 2020 at 12:38:57AM +0200, Niklas Söderlund wrote:\n> Collect the code used to generate configurations for the CIO2 block in\n> the CIO2Device class. This allows simplifying the code and allow further\n> changes to only happen at one code location.\n> \n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n> * Changes since v3\n> - Remove struct MbusInfo and use PixelFormatInfo::info() to find V4L2 fourcc.\n> - Pass size argument by value to generateConfiguration()\n> - Make use of Size::isNull()\n\nEither you've forgotten to use it, or you've forgotten to remove this\nline from the changelog.\n\n> \n> * Changes since v2\n> - Remove unneeded code to pick sensor FourCC.\n> - Remove desiredPixelFormat from generateConfiguration() as it's not\n>   needed.\n> - Rename sensorFormat_ cio2Configuration_\n> - Consolidate all format information in a single table.\n> \n> * Changes since v1\n> - Use anonymous namespace instead of static for sensorMbusToPixel map.\n> - Handle case where the requested mbus code is not supported by the sensor.\n> - Update commit message.\n> ---\n>  src/libcamera/pipeline/ipu3/cio2.cpp | 45 +++++++++++++++++++---\n>  src/libcamera/pipeline/ipu3/cio2.h   |  3 ++\n>  src/libcamera/pipeline/ipu3/ipu3.cpp | 56 +++++++---------------------\n>  3 files changed, 56 insertions(+), 48 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\n> index 31eddbc3c7745a32..cf5ccd6013c64d4d 100644\n> --- a/src/libcamera/pipeline/ipu3/cio2.cpp\n> +++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n> @@ -9,6 +9,9 @@\n>  \n>  #include <linux/media-bus-format.h>\n>  \n> +#include <libcamera/formats.h>\n> +#include <libcamera/stream.h>\n> +\n>  #include \"libcamera/internal/camera_sensor.h\"\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/v4l2_subdevice.h\"\n> @@ -20,11 +23,11 @@ LOG_DECLARE_CATEGORY(IPU3)\n>  \n>  namespace {\n>  \n> -static const std::map<uint32_t, V4L2PixelFormat> mbusCodesToInfo = {\n> -\t{ MEDIA_BUS_FMT_SBGGR10_1X10, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10) },\n> -\t{ MEDIA_BUS_FMT_SGBRG10_1X10, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10) },\n> -\t{ MEDIA_BUS_FMT_SGRBG10_1X10, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10) },\n> -\t{ MEDIA_BUS_FMT_SRGGB10_1X10, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10) },\n> +static const std::map<uint32_t, PixelFormat> mbusCodesToInfo = {\n> +\t{ MEDIA_BUS_FMT_SBGGR10_1X10, formats::SBGGR10_IPU3 },\n> +\t{ MEDIA_BUS_FMT_SGBRG10_1X10, formats::SGBRG10_IPU3 },\n> +\t{ MEDIA_BUS_FMT_SGRBG10_1X10, formats::SGRBG10_IPU3 },\n> +\t{ MEDIA_BUS_FMT_SRGGB10_1X10, formats::SRGGB10_IPU3 },\n>  };\n>  \n>  } /* namespace */\n> @@ -159,7 +162,9 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n>  \tif (itInfo == mbusCodesToInfo.end())\n>  \t\treturn -EINVAL;\n>  \n> -\toutputFormat->fourcc = itInfo->second;\n> +\tconst PixelFormatInfo &info = PixelFormatInfo::info(itInfo->second);\n> +\n> +\toutputFormat->fourcc = info.v4l2Format;\n>  \toutputFormat->size = sensorFormat.size;\n>  \toutputFormat->planesCount = 1;\n>  \n> @@ -172,6 +177,34 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n>  \treturn 0;\n>  }\n>  \n> +StreamConfiguration\n> +CIO2Device::generateConfiguration(Size size) const\n> +{\n> +\tStreamConfiguration cfg;\n> +\n> +\t/* If no desired size use the sensor resolution. */\n> +\tif (!size.width && !size.height)\n> +\t\tsize = sensor_->resolution();\n> +\n> +\t/* Query the sensor static information for closest match. */\n> +\tstd::vector<unsigned int> mbusCodes;\n> +\tstd::transform(mbusCodesToInfo.begin(), mbusCodesToInfo.end(),\n> +\t\t       std::back_inserter(mbusCodes),\n> +\t\t       [](auto &pair) { return pair.first; });\n> +\n> +\tV4L2SubdeviceFormat sensorFormat = sensor_->getFormat(mbusCodes, size);\n> +\tif (!sensorFormat.mbus_code) {\n> +\t\tLOG(IPU3, Error) << \"Sensor does not support mbus code\";\n> +\t\treturn {};\n> +\t}\n> +\n> +\tcfg.size = sensorFormat.size;\n> +\tcfg.pixelFormat = mbusCodesToInfo.at(sensorFormat.mbus_code);\n> +\tcfg.bufferCount = CIO2_BUFFER_COUNT;\n> +\n> +\treturn cfg;\n> +}\n> +\n>  /**\n>   * \\brief Allocate frame buffers for the CIO2 output\n>   *\n> diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\n> index b2c4f89d682d6cfb..5825433246c7fb89 100644\n> --- a/src/libcamera/pipeline/ipu3/cio2.h\n> +++ b/src/libcamera/pipeline/ipu3/cio2.h\n> @@ -20,6 +20,7 @@ class V4L2DeviceFormat;\n>  class V4L2Subdevice;\n>  class V4L2VideoDevice;\n>  struct Size;\n> +struct StreamConfiguration;\n>  \n>  class CIO2Device\n>  {\n> @@ -32,6 +33,8 @@ public:\n>  \tint init(const MediaDevice *media, unsigned int index);\n>  \tint configure(const Size &size, V4L2DeviceFormat *outputFormat);\n>  \n> +\tStreamConfiguration generateConfiguration(Size size) const;\n> +\n>  \tint allocateBuffers();\n>  \tvoid freeBuffers();\n>  \n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index 6e5eb5609a3c2388..c0e727e592f46883 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -36,13 +36,6 @@ LOG_DEFINE_CATEGORY(IPU3)\n>  \n>  class IPU3CameraData;\n>  \n> -static const std::map<uint32_t, PixelFormat> sensorMbusToPixel = {\n> -\t{ MEDIA_BUS_FMT_SBGGR10_1X10, formats::SBGGR10_IPU3 },\n> -\t{ MEDIA_BUS_FMT_SGBRG10_1X10, formats::SGBRG10_IPU3 },\n> -\t{ MEDIA_BUS_FMT_SGRBG10_1X10, formats::SGRBG10_IPU3 },\n> -\t{ MEDIA_BUS_FMT_SRGGB10_1X10, formats::SRGGB10_IPU3 },\n> -};\n> -\n>  class ImgUDevice\n>  {\n>  public:\n> @@ -147,7 +140,7 @@ public:\n>  \n>  \tStatus validate() override;\n>  \n> -\tconst V4L2SubdeviceFormat &sensorFormat() { return sensorFormat_; }\n> +\tconst StreamConfiguration &cio2Format() const { return cio2Configuration_; };\n>  \tconst std::vector<const IPU3Stream *> &streams() { return streams_; }\n>  \n>  private:\n> @@ -165,7 +158,7 @@ private:\n>  \tstd::shared_ptr<Camera> camera_;\n>  \tconst IPU3CameraData *data_;\n>  \n> -\tV4L2SubdeviceFormat sensorFormat_;\n> +\tStreamConfiguration cio2Configuration_;\n>  \tstd::vector<const IPU3Stream *> streams_;\n>  };\n>  \n> @@ -252,7 +245,7 @@ void IPU3CameraConfiguration::assignStreams()\n>  \n>  \t\tif (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)\n>  \t\t\tstream = &data_->rawStream_;\n> -\t\telse if (cfg.size == sensorFormat_.size)\n> +\t\telse if (cfg.size == cio2Configuration_.size)\n>  \t\t\tstream = &data_->outStream_;\n>  \t\telse\n>  \t\t\tstream = &data_->vfStream_;\n> @@ -277,8 +270,8 @@ void IPU3CameraConfiguration::adjustStream(StreamConfiguration &cfg, bool scale)\n>  \t\t */\n>  \t\tif (!cfg.size.width || !cfg.size.height) {\n>  \t\t\tcfg.size.width = 1280;\n> -\t\t\tcfg.size.height = 1280 * sensorFormat_.size.height\n> -\t\t\t\t\t/ sensorFormat_.size.width;\n> +\t\t\tcfg.size.height = 1280 * cio2Configuration_.size.height\n> +\t\t\t\t\t/ cio2Configuration_.size.width;\n>  \t\t}\n>  \n>  \t\t/*\n> @@ -297,7 +290,7 @@ void IPU3CameraConfiguration::adjustStream(StreamConfiguration &cfg, bool scale)\n>  \t\t * \\todo: Properly support cropping when the ImgU driver\n>  \t\t * interface will be cleaned up.\n>  \t\t */\n> -\t\tcfg.size = sensorFormat_.size;\n> +\t\tcfg.size = cio2Configuration_.size;\n>  \t}\n>  \n>  \t/*\n> @@ -313,7 +306,6 @@ void IPU3CameraConfiguration::adjustStream(StreamConfiguration &cfg, bool scale)\n>  \n>  CameraConfiguration::Status IPU3CameraConfiguration::validate()\n>  {\n> -\tconst CameraSensor *sensor = data_->cio2_.sensor_;\n>  \tStatus status = Valid;\n>  \n>  \tif (config_.empty())\n> @@ -340,16 +332,10 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n>  \t\t\tsize.height = cfg.size.height;\n>  \t}\n>  \n> -\tif (!size.width || !size.height)\n> -\t\tsize = sensor->resolution();\n> -\n> -\tsensorFormat_ = sensor->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SGBRG10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SGRBG10_1X10,\n> -\t\t\t\t\t    MEDIA_BUS_FMT_SRGGB10_1X10 },\n> -\t\t\t\t\t  size);\n> -\tif (!sensorFormat_.size.width || !sensorFormat_.size.height)\n> -\t\tsensorFormat_.size = sensor->resolution();\n> +\t/* Generate raw configuration from CIO2. */\n> +\tcio2Configuration_ = data_->cio2_.generateConfiguration(size);\n> +\tif (!cio2Configuration_.pixelFormat.isValid())\n> +\t\treturn Invalid;\n>  \n>  \t/* Assign streams to each configuration entry. */\n>  \tassignStreams();\n> @@ -361,20 +347,13 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n>  \t\tconst IPU3Stream *stream = streams_[i];\n>  \n>  \t\tif (stream->raw_) {\n> -\t\t\tconst auto &itFormat =\n> -\t\t\t\tsensorMbusToPixel.find(sensorFormat_.mbus_code);\n> -\t\t\tif (itFormat == sensorMbusToPixel.end())\n> -\t\t\t\treturn Invalid;\n> -\n> -\t\t\tcfg.pixelFormat = itFormat->second;\n> -\t\t\tcfg.size = sensorFormat_.size;\n> +\t\t\tcfg = cio2Configuration_;\n>  \t\t} else {\n>  \t\t\tbool scale = stream == &data_->vfStream_;\n>  \t\t\tadjustStream(config_[i], scale);\n> +\t\t\tcfg.bufferCount = IPU3_BUFFER_COUNT;\n>  \t\t}\n>  \n> -\t\tcfg.bufferCount = IPU3_BUFFER_COUNT;\n> -\n>  \t\tif (cfg.pixelFormat != oldCfg.pixelFormat ||\n>  \t\t    cfg.size != oldCfg.size) {\n>  \t\t\tLOG(IPU3, Debug)\n> @@ -454,14 +433,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n>  \n>  \t\t\tcfg.size = data->cio2_.sensor_->resolution();\n>  \n> -\t\t\tV4L2SubdeviceFormat sensorFormat =\n> -\t\t\t\tdata->cio2_.sensor_->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10,\n> -\t\t\t\t\t\t\t\t MEDIA_BUS_FMT_SGBRG10_1X10,\n> -\t\t\t\t\t\t\t\t MEDIA_BUS_FMT_SGRBG10_1X10,\n> -\t\t\t\t\t\t\t\t MEDIA_BUS_FMT_SRGGB10_1X10 },\n> -\t\t\t\t\t\t\t       cfg.size);\n> -\t\t\tcfg.pixelFormat =\n> -\t\t\t\tsensorMbusToPixel.at(sensorFormat.mbus_code);\n> +\t\t\tcfg = data->cio2_.generateConfiguration(cfg.size);\n>  \t\t\tbreak;\n>  \t\t}\n>  \n> @@ -575,7 +547,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n>  \t * Pass the requested stream size to the CIO2 unit and get back the\n>  \t * adjusted format to be propagated to the ImgU output devices.\n>  \t */\n> -\tconst Size &sensorSize = config->sensorFormat().size;\n> +\tconst Size &sensorSize = config->cio2Format().size;\n>  \tV4L2DeviceFormat cio2Format = {};\n>  \tret = cio2->configure(sensorSize, &cio2Format);\n>  \tif (ret)","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 A93CAC0109\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 26 Jun 2020 00:41:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1AE05609C5;\n\tFri, 26 Jun 2020 02:41:09 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3782B603BA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 26 Jun 2020 02:41:07 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8D3EA72E;\n\tFri, 26 Jun 2020 02:41:06 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"N4Hn5oH0\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1593132066;\n\tbh=RL/2WRLEmSdCqlA5VrOlfQy52Fv0Lc5DPLOvjj245Ig=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=N4Hn5oH06gskzVwtZQwc5AmidDuMyuP/8O+ezal0kjxf8xKEkTjfBTUrYIi1bNcNm\n\t4HPQEUAmTQARS34VSSDpkRE2xW+Xsil9L0Lal8ZLpUEbCYbMQNUmzP1l6KA/mWWBFu\n\toAIhEiQAPsESEUqHWFQ0PYHs6PS+FiUfW+Z0r73Q=","Date":"Fri, 26 Jun 2020 03:41:05 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Message-ID":"<20200626004105.GM5865@pendragon.ideasonboard.com>","References":"<20200625223900.1282164-1-niklas.soderlund@ragnatech.se>\n\t<20200625223900.1282164-7-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200625223900.1282164-7-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH v4 6/9] libcamera: ipu3: cio2: Add\n\tfunction to generate configuration","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","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":10867,"web_url":"https://patchwork.libcamera.org/comment/10867/","msgid":"<20200626005503.GA477866@oden.dyn.berto.se>","date":"2020-06-26T00:55:03","subject":"Re: [libcamera-devel] [PATCH v4 6/9] libcamera: ipu3: cio2: Add\n\tfunction to generate configuration","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nOn 2020-06-26 03:41:05 +0300, Laurent Pinchart wrote:\n> Hi Niklas,\n> \n> Thank you for the patch.\n> \n> On Fri, Jun 26, 2020 at 12:38:57AM +0200, Niklas Söderlund wrote:\n> > Collect the code used to generate configurations for the CIO2 block in\n> > the CIO2Device class. This allows simplifying the code and allow further\n> > changes to only happen at one code location.\n> > \n> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> > * Changes since v3\n> > - Remove struct MbusInfo and use PixelFormatInfo::info() to find V4L2 fourcc.\n> > - Pass size argument by value to generateConfiguration()\n> > - Make use of Size::isNull()\n> \n> Either you've forgotten to use it, or you've forgotten to remove this\n> line from the changelog.\n\nI added it to the code and then removed it again and forgot it in the \nchangelog. I think isNull() shall be used here but since the name is \nstill debated I wanted this series to be applicable on master so \nreverted back. If isNull() is merged before this series I will switch to \nit. Same goes for the map_keys() helper a bit further in this series.\n\n> \n> > \n> > * Changes since v2\n> > - Remove unneeded code to pick sensor FourCC.\n> > - Remove desiredPixelFormat from generateConfiguration() as it's not\n> >   needed.\n> > - Rename sensorFormat_ cio2Configuration_\n> > - Consolidate all format information in a single table.\n> > \n> > * Changes since v1\n> > - Use anonymous namespace instead of static for sensorMbusToPixel map.\n> > - Handle case where the requested mbus code is not supported by the sensor.\n> > - Update commit message.\n> > ---\n> >  src/libcamera/pipeline/ipu3/cio2.cpp | 45 +++++++++++++++++++---\n> >  src/libcamera/pipeline/ipu3/cio2.h   |  3 ++\n> >  src/libcamera/pipeline/ipu3/ipu3.cpp | 56 +++++++---------------------\n> >  3 files changed, 56 insertions(+), 48 deletions(-)\n> > \n> > diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\n> > index 31eddbc3c7745a32..cf5ccd6013c64d4d 100644\n> > --- a/src/libcamera/pipeline/ipu3/cio2.cpp\n> > +++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n> > @@ -9,6 +9,9 @@\n> >  \n> >  #include <linux/media-bus-format.h>\n> >  \n> > +#include <libcamera/formats.h>\n> > +#include <libcamera/stream.h>\n> > +\n> >  #include \"libcamera/internal/camera_sensor.h\"\n> >  #include \"libcamera/internal/media_device.h\"\n> >  #include \"libcamera/internal/v4l2_subdevice.h\"\n> > @@ -20,11 +23,11 @@ LOG_DECLARE_CATEGORY(IPU3)\n> >  \n> >  namespace {\n> >  \n> > -static const std::map<uint32_t, V4L2PixelFormat> mbusCodesToInfo = {\n> > -\t{ MEDIA_BUS_FMT_SBGGR10_1X10, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10) },\n> > -\t{ MEDIA_BUS_FMT_SGBRG10_1X10, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10) },\n> > -\t{ MEDIA_BUS_FMT_SGRBG10_1X10, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10) },\n> > -\t{ MEDIA_BUS_FMT_SRGGB10_1X10, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10) },\n> > +static const std::map<uint32_t, PixelFormat> mbusCodesToInfo = {\n> > +\t{ MEDIA_BUS_FMT_SBGGR10_1X10, formats::SBGGR10_IPU3 },\n> > +\t{ MEDIA_BUS_FMT_SGBRG10_1X10, formats::SGBRG10_IPU3 },\n> > +\t{ MEDIA_BUS_FMT_SGRBG10_1X10, formats::SGRBG10_IPU3 },\n> > +\t{ MEDIA_BUS_FMT_SRGGB10_1X10, formats::SRGGB10_IPU3 },\n> >  };\n> >  \n> >  } /* namespace */\n> > @@ -159,7 +162,9 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n> >  \tif (itInfo == mbusCodesToInfo.end())\n> >  \t\treturn -EINVAL;\n> >  \n> > -\toutputFormat->fourcc = itInfo->second;\n> > +\tconst PixelFormatInfo &info = PixelFormatInfo::info(itInfo->second);\n> > +\n> > +\toutputFormat->fourcc = info.v4l2Format;\n> >  \toutputFormat->size = sensorFormat.size;\n> >  \toutputFormat->planesCount = 1;\n> >  \n> > @@ -172,6 +177,34 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n> >  \treturn 0;\n> >  }\n> >  \n> > +StreamConfiguration\n> > +CIO2Device::generateConfiguration(Size size) const\n> > +{\n> > +\tStreamConfiguration cfg;\n> > +\n> > +\t/* If no desired size use the sensor resolution. */\n> > +\tif (!size.width && !size.height)\n> > +\t\tsize = sensor_->resolution();\n> > +\n> > +\t/* Query the sensor static information for closest match. */\n> > +\tstd::vector<unsigned int> mbusCodes;\n> > +\tstd::transform(mbusCodesToInfo.begin(), mbusCodesToInfo.end(),\n> > +\t\t       std::back_inserter(mbusCodes),\n> > +\t\t       [](auto &pair) { return pair.first; });\n> > +\n> > +\tV4L2SubdeviceFormat sensorFormat = sensor_->getFormat(mbusCodes, size);\n> > +\tif (!sensorFormat.mbus_code) {\n> > +\t\tLOG(IPU3, Error) << \"Sensor does not support mbus code\";\n> > +\t\treturn {};\n> > +\t}\n> > +\n> > +\tcfg.size = sensorFormat.size;\n> > +\tcfg.pixelFormat = mbusCodesToInfo.at(sensorFormat.mbus_code);\n> > +\tcfg.bufferCount = CIO2_BUFFER_COUNT;\n> > +\n> > +\treturn cfg;\n> > +}\n> > +\n> >  /**\n> >   * \\brief Allocate frame buffers for the CIO2 output\n> >   *\n> > diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\n> > index b2c4f89d682d6cfb..5825433246c7fb89 100644\n> > --- a/src/libcamera/pipeline/ipu3/cio2.h\n> > +++ b/src/libcamera/pipeline/ipu3/cio2.h\n> > @@ -20,6 +20,7 @@ class V4L2DeviceFormat;\n> >  class V4L2Subdevice;\n> >  class V4L2VideoDevice;\n> >  struct Size;\n> > +struct StreamConfiguration;\n> >  \n> >  class CIO2Device\n> >  {\n> > @@ -32,6 +33,8 @@ public:\n> >  \tint init(const MediaDevice *media, unsigned int index);\n> >  \tint configure(const Size &size, V4L2DeviceFormat *outputFormat);\n> >  \n> > +\tStreamConfiguration generateConfiguration(Size size) const;\n> > +\n> >  \tint allocateBuffers();\n> >  \tvoid freeBuffers();\n> >  \n> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > index 6e5eb5609a3c2388..c0e727e592f46883 100644\n> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > @@ -36,13 +36,6 @@ LOG_DEFINE_CATEGORY(IPU3)\n> >  \n> >  class IPU3CameraData;\n> >  \n> > -static const std::map<uint32_t, PixelFormat> sensorMbusToPixel = {\n> > -\t{ MEDIA_BUS_FMT_SBGGR10_1X10, formats::SBGGR10_IPU3 },\n> > -\t{ MEDIA_BUS_FMT_SGBRG10_1X10, formats::SGBRG10_IPU3 },\n> > -\t{ MEDIA_BUS_FMT_SGRBG10_1X10, formats::SGRBG10_IPU3 },\n> > -\t{ MEDIA_BUS_FMT_SRGGB10_1X10, formats::SRGGB10_IPU3 },\n> > -};\n> > -\n> >  class ImgUDevice\n> >  {\n> >  public:\n> > @@ -147,7 +140,7 @@ public:\n> >  \n> >  \tStatus validate() override;\n> >  \n> > -\tconst V4L2SubdeviceFormat &sensorFormat() { return sensorFormat_; }\n> > +\tconst StreamConfiguration &cio2Format() const { return cio2Configuration_; };\n> >  \tconst std::vector<const IPU3Stream *> &streams() { return streams_; }\n> >  \n> >  private:\n> > @@ -165,7 +158,7 @@ private:\n> >  \tstd::shared_ptr<Camera> camera_;\n> >  \tconst IPU3CameraData *data_;\n> >  \n> > -\tV4L2SubdeviceFormat sensorFormat_;\n> > +\tStreamConfiguration cio2Configuration_;\n> >  \tstd::vector<const IPU3Stream *> streams_;\n> >  };\n> >  \n> > @@ -252,7 +245,7 @@ void IPU3CameraConfiguration::assignStreams()\n> >  \n> >  \t\tif (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)\n> >  \t\t\tstream = &data_->rawStream_;\n> > -\t\telse if (cfg.size == sensorFormat_.size)\n> > +\t\telse if (cfg.size == cio2Configuration_.size)\n> >  \t\t\tstream = &data_->outStream_;\n> >  \t\telse\n> >  \t\t\tstream = &data_->vfStream_;\n> > @@ -277,8 +270,8 @@ void IPU3CameraConfiguration::adjustStream(StreamConfiguration &cfg, bool scale)\n> >  \t\t */\n> >  \t\tif (!cfg.size.width || !cfg.size.height) {\n> >  \t\t\tcfg.size.width = 1280;\n> > -\t\t\tcfg.size.height = 1280 * sensorFormat_.size.height\n> > -\t\t\t\t\t/ sensorFormat_.size.width;\n> > +\t\t\tcfg.size.height = 1280 * cio2Configuration_.size.height\n> > +\t\t\t\t\t/ cio2Configuration_.size.width;\n> >  \t\t}\n> >  \n> >  \t\t/*\n> > @@ -297,7 +290,7 @@ void IPU3CameraConfiguration::adjustStream(StreamConfiguration &cfg, bool scale)\n> >  \t\t * \\todo: Properly support cropping when the ImgU driver\n> >  \t\t * interface will be cleaned up.\n> >  \t\t */\n> > -\t\tcfg.size = sensorFormat_.size;\n> > +\t\tcfg.size = cio2Configuration_.size;\n> >  \t}\n> >  \n> >  \t/*\n> > @@ -313,7 +306,6 @@ void IPU3CameraConfiguration::adjustStream(StreamConfiguration &cfg, bool scale)\n> >  \n> >  CameraConfiguration::Status IPU3CameraConfiguration::validate()\n> >  {\n> > -\tconst CameraSensor *sensor = data_->cio2_.sensor_;\n> >  \tStatus status = Valid;\n> >  \n> >  \tif (config_.empty())\n> > @@ -340,16 +332,10 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n> >  \t\t\tsize.height = cfg.size.height;\n> >  \t}\n> >  \n> > -\tif (!size.width || !size.height)\n> > -\t\tsize = sensor->resolution();\n> > -\n> > -\tsensorFormat_ = sensor->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10,\n> > -\t\t\t\t\t    MEDIA_BUS_FMT_SGBRG10_1X10,\n> > -\t\t\t\t\t    MEDIA_BUS_FMT_SGRBG10_1X10,\n> > -\t\t\t\t\t    MEDIA_BUS_FMT_SRGGB10_1X10 },\n> > -\t\t\t\t\t  size);\n> > -\tif (!sensorFormat_.size.width || !sensorFormat_.size.height)\n> > -\t\tsensorFormat_.size = sensor->resolution();\n> > +\t/* Generate raw configuration from CIO2. */\n> > +\tcio2Configuration_ = data_->cio2_.generateConfiguration(size);\n> > +\tif (!cio2Configuration_.pixelFormat.isValid())\n> > +\t\treturn Invalid;\n> >  \n> >  \t/* Assign streams to each configuration entry. */\n> >  \tassignStreams();\n> > @@ -361,20 +347,13 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n> >  \t\tconst IPU3Stream *stream = streams_[i];\n> >  \n> >  \t\tif (stream->raw_) {\n> > -\t\t\tconst auto &itFormat =\n> > -\t\t\t\tsensorMbusToPixel.find(sensorFormat_.mbus_code);\n> > -\t\t\tif (itFormat == sensorMbusToPixel.end())\n> > -\t\t\t\treturn Invalid;\n> > -\n> > -\t\t\tcfg.pixelFormat = itFormat->second;\n> > -\t\t\tcfg.size = sensorFormat_.size;\n> > +\t\t\tcfg = cio2Configuration_;\n> >  \t\t} else {\n> >  \t\t\tbool scale = stream == &data_->vfStream_;\n> >  \t\t\tadjustStream(config_[i], scale);\n> > +\t\t\tcfg.bufferCount = IPU3_BUFFER_COUNT;\n> >  \t\t}\n> >  \n> > -\t\tcfg.bufferCount = IPU3_BUFFER_COUNT;\n> > -\n> >  \t\tif (cfg.pixelFormat != oldCfg.pixelFormat ||\n> >  \t\t    cfg.size != oldCfg.size) {\n> >  \t\t\tLOG(IPU3, Debug)\n> > @@ -454,14 +433,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n> >  \n> >  \t\t\tcfg.size = data->cio2_.sensor_->resolution();\n> >  \n> > -\t\t\tV4L2SubdeviceFormat sensorFormat =\n> > -\t\t\t\tdata->cio2_.sensor_->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10,\n> > -\t\t\t\t\t\t\t\t MEDIA_BUS_FMT_SGBRG10_1X10,\n> > -\t\t\t\t\t\t\t\t MEDIA_BUS_FMT_SGRBG10_1X10,\n> > -\t\t\t\t\t\t\t\t MEDIA_BUS_FMT_SRGGB10_1X10 },\n> > -\t\t\t\t\t\t\t       cfg.size);\n> > -\t\t\tcfg.pixelFormat =\n> > -\t\t\t\tsensorMbusToPixel.at(sensorFormat.mbus_code);\n> > +\t\t\tcfg = data->cio2_.generateConfiguration(cfg.size);\n> >  \t\t\tbreak;\n> >  \t\t}\n> >  \n> > @@ -575,7 +547,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)\n> >  \t * Pass the requested stream size to the CIO2 unit and get back the\n> >  \t * adjusted format to be propagated to the ImgU output devices.\n> >  \t */\n> > -\tconst Size &sensorSize = config->sensorFormat().size;\n> > +\tconst Size &sensorSize = config->cio2Format().size;\n> >  \tV4L2DeviceFormat cio2Format = {};\n> >  \tret = cio2->configure(sensorSize, &cio2Format);\n> >  \tif (ret)\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 0FB4FC2E65\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 26 Jun 2020 00:55:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8F084609C5;\n\tFri, 26 Jun 2020 02:55:07 +0200 (CEST)","from mail-lj1-x241.google.com (mail-lj1-x241.google.com\n\t[IPv6:2a00:1450:4864:20::241])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 425E0603BA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 26 Jun 2020 02:55:06 +0200 (CEST)","by mail-lj1-x241.google.com with SMTP id 9so8536191ljc.8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 25 Jun 2020 17:55:06 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\te29sm5200663lfc.51.2020.06.25.17.55.04\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 25 Jun 2020 17:55:04 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"L4m/CHgA\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=iVo3Ac/1q/SXrzrVvm2CjuwXT5+3S6XksfDriOGNiWc=;\n\tb=L4m/CHgAKcE9kiFwJfY9Wp1B09WbHN6i4VFl8tVaa07O9bK8YzIKw1jKUC6Kka/kcB\n\tJYg5kJGe4+fTErWEOCBRuQfrdsdxHmjQoXqD6vwmyhNiexHCAg7uGV92eBEPV7wJCsPr\n\tigpSf8GDxuAvCq1oAmThI7Jy4+HwV7zUn+HVWb17PO5Z0EBtD2pu8rLv9W7x3HhB0is+\n\tK6RrRnCEOGUYqZzoziYpHySXDqrLjVJcT+pW+iM57Vm8gIv10t22eyecZqeoApvtV6Xe\n\tJ6r8n5UGGW9DzNxdpF0ws925VgeBr02DRq7c7CRa0mDCmUcG2FxxYjBrvylSpMP4iHiK\n\tYY4A==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=iVo3Ac/1q/SXrzrVvm2CjuwXT5+3S6XksfDriOGNiWc=;\n\tb=bAS75RU7bxcQdIJz7kKkdHgE348MpkgNiiIG0ZkdjxyNBicWzNRYPrTZHtwkqjRAR+\n\tFNvCRbI4NjoaAM89nzfrYpWYVB2qF1Fnd7DkdAvW39jzgIzyQxgP/ZcRn4MrhaiU9Woh\n\tBmzMllBedCQTdHK3QaRc2kC46UKCl9V4BkTfYbAkZw26PdR4Pvvmu0176xiFcCgImMpa\n\tn0pj+a2K6H7b7pwOnTXpFeDd3lBnXO39spfCEe/fRpRhqShWx1yYsUmd0Zex+YlixY94\n\tnBtoOrNC+EklqW/ecUrrMM7QD9yUu3Wi6ZRsfTU2ygPH/TQKpW1NCcOOFDvSHjLhiNiG\n\tDQtw==","X-Gm-Message-State":"AOAM531hdHmRxyEpu5gYBwynl1hwX+Pz45+ceWHUFSz9x4mAXkqLP5EQ\n\t9TKwnaTSEJktdeKJ6+s3SfgWMLKX0eA=","X-Google-Smtp-Source":"ABdhPJyui7dMY1VSc3eqdKb+shc3qk4PH9z7VHxFnfmkPQXFQcZeRZBg4kC+he9Ps8DntWL2+lHrdQ==","X-Received":"by 2002:a2e:984b:: with SMTP id e11mr155726ljj.358.1593132905200;\n\tThu, 25 Jun 2020 17:55:05 -0700 (PDT)","Date":"Fri, 26 Jun 2020 02:55:03 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20200626005503.GA477866@oden.dyn.berto.se>","References":"<20200625223900.1282164-1-niklas.soderlund@ragnatech.se>\n\t<20200625223900.1282164-7-niklas.soderlund@ragnatech.se>\n\t<20200626004105.GM5865@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200626004105.GM5865@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v4 6/9] libcamera: ipu3: cio2: Add\n\tfunction to generate configuration","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","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]