{"id":4134,"url":"https://patchwork.libcamera.org/api/1.1/patches/4134/?format=json","web_url":"https://patchwork.libcamera.org/patch/4134/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20200623020930.1781469-8-niklas.soderlund@ragnatech.se>","date":"2020-06-23T02:09:27","name":"[libcamera-devel,v3,07/10] libcamera: ipu3: cio2: Add function to generate configuration","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"29dbbeb34f516ba7a0ebbc027269c34b98e719a3","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/1.1/people/5/?format=json","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/4134/mbox/","series":[{"id":1027,"url":"https://patchwork.libcamera.org/api/1.1/series/1027/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=1027","date":"2020-06-23T02:09:20","name":"libcamera: ipu3: Allow zero-copy RAW stream","version":3,"mbox":"https://patchwork.libcamera.org/series/1027/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/4134/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/4134/checks/","tags":{},"headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net\n\t[195.74.38.228])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 26170609C2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 23 Jun 2020 04:09:48 +0200 (CEST)","from bismarck.berto.se (p4fca2eca.dip0.t-ipconnect.de\n\t[79.202.46.202]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA\n\tid 9c80c80f-b4f6-11ea-933e-005056917a89;\n\tTue, 23 Jun 2020 04:09:47 +0200 (CEST)"],"X-Halon-ID":"9c80c80f-b4f6-11ea-933e-005056917a89","Authorized-sender":"niklas@soderlund.pp.se","From":"=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","To":"libcamera-devel@lists.libcamera.org","Date":"Tue, 23 Jun 2020 04:09:27 +0200","Message-Id":"<20200623020930.1781469-8-niklas.soderlund@ragnatech.se>","X-Mailer":"git-send-email 2.27.0","In-Reply-To":"<20200623020930.1781469-1-niklas.soderlund@ragnatech.se>","References":"<20200623020930.1781469-1-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH v3 07/10] 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>","X-List-Received-Date":"Tue, 23 Jun 2020 02:09:48 -0000"},"content":"Collect the code used to generate configurations for the CIO2 block in\nthe CIO2Device class. This allows simplifying the code and allow further\nchanges to only  happen at one code location.\n\nSigned-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\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 | 54 +++++++++++++++++++++++----\n src/libcamera/pipeline/ipu3/cio2.h   |  3 ++\n src/libcamera/pipeline/ipu3/ipu3.cpp | 56 +++++++---------------------\n 3 files changed, 63 insertions(+), 50 deletions(-)","diff":"diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\nindex f23128d412e6b1a5..d6bab896706dd60e 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,16 @@ 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+struct MbusInfo {\n+\tPixelFormat pixelFormat;\n+\tV4L2PixelFormat fourcc;\n+};\n+\n+static const std::map<uint32_t, MbusInfo> mbusCodesToInfo = {\n+\t{ MEDIA_BUS_FMT_SBGGR10_1X10, { formats::SBGGR10_IPU3, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10) } },\n+\t{ MEDIA_BUS_FMT_SGBRG10_1X10, { formats::SGBRG10_IPU3, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10) } },\n+\t{ MEDIA_BUS_FMT_SGRBG10_1X10, { formats::SGRBG10_IPU3, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10) } },\n+\t{ MEDIA_BUS_FMT_SRGGB10_1X10, { formats::SRGGB10_IPU3, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10) } },\n };\n \n } /* namespace */\n@@ -92,7 +100,7 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index)\n \tstd::set<unsigned int> cio2Codes;\n \tstd::transform(mbusCodesToInfo.begin(), mbusCodesToInfo.end(),\n \t\tstd::inserter(cio2Codes, cio2Codes.begin()),\n-\t\t[](const std::map<uint32_t, V4L2PixelFormat>::value_type &pair){ return pair.first; });\n+\t\t[](const std::map<uint32_t, MbusInfo>::value_type &pair){ return pair.first; });\n \tconst std::set<unsigned int> &sensorCodes = sensor_->mbusCodes();\n \tif (!utils::set_overlap(sensorCodes.begin(), sensorCodes.end(),\n \t\t\t\tcio2Codes.begin(), cio2Codes.end())) {\n@@ -139,7 +147,7 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n \tstd::vector<unsigned int> mbusCodes;\n \tstd::transform(mbusCodesToInfo.begin(), mbusCodesToInfo.end(),\n \t\tstd::back_inserter(mbusCodes),\n-\t\t[](const std::map<uint32_t, V4L2PixelFormat>::value_type &pair){ return pair.first; });\n+\t\t[](const std::map<uint32_t, MbusInfo>::value_type &pair){ return pair.first; });\n \n \tsensorFormat = sensor_->getFormat(mbusCodes, size);\n \tret = sensor_->setFormat(&sensorFormat);\n@@ -154,7 +162,7 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n \tif (itInfo == mbusCodesToInfo.end())\n \t\treturn -EINVAL;\n \n-\toutputFormat->fourcc = itInfo->second;\n+\toutputFormat->fourcc = itInfo->second.fourcc;\n \toutputFormat->size = sensorFormat.size;\n \toutputFormat->planesCount = 1;\n \n@@ -167,6 +175,36 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n \treturn 0;\n }\n \n+StreamConfiguration\n+CIO2Device::generateConfiguration(const Size &desiredSize) const\n+{\n+\tStreamConfiguration cfg;\n+\n+\t/* If no desired size use the sensor resolution. */\n+\tSize size = sensor_->resolution();\n+\tif (desiredSize.width && desiredSize.height)\n+\t\tsize = desiredSize;\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\tstd::back_inserter(mbusCodes),\n+\t\t[](const std::map<uint32_t, MbusInfo>::value_type &pair){ return pair.first; });\n+\n+\tV4L2SubdeviceFormat sensorFormat = sensor_->getFormat(mbusCodes, size);\n+\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).pixelFormat;\n+\tcfg.bufferCount = CIO2_BUFFER_COUNT;\n+\n+\treturn cfg;\n+}\n+\n /**\n  * \\brief Allocate frame buffers for the CIO2 output\n  *\ndiff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\nindex b2c4f89d682d6cfb..6276573f2b585b25 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(const Size &desiredSize) const;\n+\n \tint allocateBuffers();\n \tvoid freeBuffers();\n \ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex 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","prefixes":["libcamera-devel","v3","07/10"]}