{"id":3896,"url":"https://patchwork.libcamera.org/api/1.1/patches/3896/?format=json","web_url":"https://patchwork.libcamera.org/patch/3896/","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":"<20200602013909.3170593-8-niklas.soderlund@ragnatech.se>","date":"2020-06-02T01:39:06","name":"[libcamera-devel,07/10] libcamera: ipu3: cio2: Add function to generate configuration","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"61abb55bbe1953367baa907bf23a405ff43e14d1","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/3896/mbox/","series":[{"id":943,"url":"https://patchwork.libcamera.org/api/1.1/series/943/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=943","date":"2020-06-02T01:38:59","name":"libcamera: ipu3: Allow zero-copy RAW stream","version":1,"mbox":"https://patchwork.libcamera.org/series/943/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/3896/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/3896/checks/","tags":{},"headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net\n\t[195.74.38.227])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4971061130\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  2 Jun 2020 03:39:32 +0200 (CEST)","from bismarck.berto.se (p4fca2392.dip0.t-ipconnect.de\n\t[79.202.35.146]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA\n\tid d690d55f-a471-11ea-a73e-0050569116f7;\n\tTue, 02 Jun 2020 03:39:02 +0200 (CEST)"],"X-Halon-ID":"d690d55f-a471-11ea-a73e-0050569116f7","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,  2 Jun 2020 03:39:06 +0200","Message-Id":"<20200602013909.3170593-8-niklas.soderlund@ragnatech.se>","X-Mailer":"git-send-email 2.26.2","In-Reply-To":"<20200602013909.3170593-1-niklas.soderlund@ragnatech.se>","References":"<20200602013909.3170593-1-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH 07/10] libcamera: ipu3: cio2: Add function\n\tto 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, 02 Jun 2020 01:39:33 -0000"},"content":"Collect the code used to generate configurations for the CIO2 block in\nthe CIO2Device class. This allows for both simplifying the code while\nextending it's functionality. With this change applications can now\nswitch which Bayer format pattern are used instead being more or less\nforced to use SBGGR10.\n\nSigned-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n---\n src/libcamera/pipeline/ipu3/cio2.cpp | 44 +++++++++++++++++++++\n src/libcamera/pipeline/ipu3/cio2.h   |  5 +++\n src/libcamera/pipeline/ipu3/ipu3.cpp | 57 ++++++----------------------\n 3 files changed, 60 insertions(+), 46 deletions(-)","diff":"diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\nindex 113486e3e3d0f2f1..2263d6530ec6b672 100644\n--- a/src/libcamera/pipeline/ipu3/cio2.cpp\n+++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n@@ -11,6 +11,13 @@ namespace libcamera {\n \n LOG_DECLARE_CATEGORY(IPU3)\n \n+static const std::map<uint32_t, PixelFormat> sensorMbusToPixel = {\n+\t{ MEDIA_BUS_FMT_SBGGR10_1X10, PixelFormat(DRM_FORMAT_SBGGR10, IPU3_FORMAT_MOD_PACKED) },\n+\t{ MEDIA_BUS_FMT_SGBRG10_1X10, PixelFormat(DRM_FORMAT_SGBRG10, IPU3_FORMAT_MOD_PACKED) },\n+\t{ MEDIA_BUS_FMT_SGRBG10_1X10, PixelFormat(DRM_FORMAT_SGRBG10, IPU3_FORMAT_MOD_PACKED) },\n+\t{ MEDIA_BUS_FMT_SRGGB10_1X10, PixelFormat(DRM_FORMAT_SRGGB10, IPU3_FORMAT_MOD_PACKED) },\n+};\n+\n /**\n  * \\brief Initialize components of the CIO2 device with \\a index\n  * \\param[in] media The CIO2 media device\n@@ -153,6 +160,43 @@ int CIO2Device::configure(const Size &size, V4L2DeviceFormat *outputFormat)\n \treturn 0;\n }\n \n+StreamConfiguration\n+CIO2Device::generateConfiguration(const PixelFormat desiredPixelFormat,\n+\t\t\t\t  const Size desiredSize) const\n+{\n+\tStreamConfiguration cfg;\n+\n+\t/* If no desired pixelformat allow all supported.*/\n+\tstd::vector<unsigned int> mbusCodes = {\n+\t\tMEDIA_BUS_FMT_SBGGR10_1X10,\n+\t\tMEDIA_BUS_FMT_SGBRG10_1X10,\n+\t\tMEDIA_BUS_FMT_SGRBG10_1X10,\n+\t\tMEDIA_BUS_FMT_SRGGB10_1X10\n+\t};\n+\tif (desiredPixelFormat.isValid()) {\n+\t\tfor (const auto &iter : sensorMbusToPixel) {\n+\t\t\tif (iter.second == desiredPixelFormat) {\n+\t\t\t\tmbusCodes = { iter.first };\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\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+\tV4L2SubdeviceFormat sensorFormat = sensor_->getFormat(mbusCodes, size);\n+\n+\tcfg.size = sensorFormat.size;\n+\tcfg.pixelFormat = sensorMbusToPixel.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  *\ndiff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\nindex d923038bb4ba356f..2e268a7154b2d241 100644\n--- a/src/libcamera/pipeline/ipu3/cio2.h\n+++ b/src/libcamera/pipeline/ipu3/cio2.h\n@@ -12,6 +12,8 @@\n \n #include <linux/media-bus-format.h>\n \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@@ -39,6 +41,9 @@ public:\n \tint init(const MediaDevice *media, unsigned int index);\n \tint configure(const Size &size, V4L2DeviceFormat *outputFormat);\n \n+\tStreamConfiguration generateConfiguration(const PixelFormat desiredPixelFormat = {},\n+\t\t\t\t\t\t  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 2047deac299dbf75..56cc3ca10414f0d2 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -35,13 +35,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, PixelFormat(DRM_FORMAT_SBGGR10, IPU3_FORMAT_MOD_PACKED) },\n-\t{ MEDIA_BUS_FMT_SGBRG10_1X10, PixelFormat(DRM_FORMAT_SGBRG10, IPU3_FORMAT_MOD_PACKED) },\n-\t{ MEDIA_BUS_FMT_SGRBG10_1X10, PixelFormat(DRM_FORMAT_SGRBG10, IPU3_FORMAT_MOD_PACKED) },\n-\t{ MEDIA_BUS_FMT_SRGGB10_1X10, PixelFormat(DRM_FORMAT_SRGGB10, IPU3_FORMAT_MOD_PACKED) },\n-};\n-\n class ImgUDevice\n {\n public:\n@@ -146,7 +139,7 @@ public:\n \n \tStatus validate() override;\n \n-\tconst V4L2SubdeviceFormat &sensorFormat() { return sensorFormat_; }\n+\tconst StreamConfiguration &sensorFormat() const { return sensorFormat_; };\n \tconst std::vector<const IPU3Stream *> &streams() { return streams_; }\n \n private:\n@@ -164,7 +157,7 @@ private:\n \tstd::shared_ptr<Camera> camera_;\n \tconst IPU3CameraData *data_;\n \n-\tV4L2SubdeviceFormat sensorFormat_;\n+\tStreamConfiguration sensorFormat_;\n \tstd::vector<const IPU3Stream *> streams_;\n };\n \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@@ -325,32 +317,21 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()\n \t\tstatus = Adjusted;\n \t}\n \n-\t/*\n-\t * Select the sensor format by collecting the maximum width and height\n-\t * and picking the closest larger match, as the IPU3 can downscale\n-\t * only. If no resolution is requested for any stream, or if no sensor\n-\t * resolution is large enough, pick the largest one.\n-\t */\n+\t/* Find largets size and raw format (if any) in the configuration. */\n \tSize size = {};\n-\n+\tPixelFormat pixelFormat = {};\n \tfor (const StreamConfiguration &cfg : config_) {\n \t\tif (cfg.size.width > size.width)\n \t\t\tsize.width = cfg.size.width;\n \t\tif (cfg.size.height > size.height)\n \t\t\tsize.height = cfg.size.height;\n+\n+\t\tif (cfg.pixelFormat.modifier() == IPU3_FORMAT_MOD_PACKED)\n+\t\t\tpixelFormat = cfg.pixelFormat;\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-\n+\t/* Generate raw configuration from CIO2. */\n+\tsensorFormat_ = data_->cio2_.generateConfiguration(pixelFormat, size);\n \n \t/* Assign streams to each configuration entry. */\n \tif (updateStreams())\n@@ -363,13 +344,7 @@ 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 = sensorFormat_;\n \t\t} else {\n \t\t\tbool scale = stream == &data_->vfStream_;\n \t\t\tadjustStream(config_[i], scale);\n@@ -452,17 +427,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n \t\t\t}\n \n \t\t\tstream = &data->rawStream_;\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();\n \t\t\tbreak;\n \t\t}\n \n","prefixes":["libcamera-devel","07/10"]}