{"id":8920,"url":"https://patchwork.libcamera.org/api/patches/8920/?format=json","web_url":"https://patchwork.libcamera.org/patch/8920/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/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":"<20200722133009.26528-4-kgupta@es.iitr.ac.in>","date":"2020-07-22T13:30:05","name":"[libcamera-devel,3/7] libcamera: pipeline: vimc: Generate and Validate stream configurations","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"0ce928145a4ef06b63892003e0ea0edfcc117846","submitter":{"id":39,"url":"https://patchwork.libcamera.org/api/people/39/?format=json","name":"Kaaira Gupta","email":"kgupta@es.iitr.ac.in"},"delegate":{"id":11,"url":"https://patchwork.libcamera.org/api/users/11/?format=json","username":"kbingham","first_name":"Kieran","last_name":"Bingham","email":"kieran.bingham@ideasonboard.com"},"mbox":"https://patchwork.libcamera.org/patch/8920/mbox/","series":[{"id":1127,"url":"https://patchwork.libcamera.org/api/series/1127/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=1127","date":"2020-07-22T13:30:02","name":"vimc: Introduce multiple streaming","version":1,"mbox":"https://patchwork.libcamera.org/series/1127/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/8920/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/8920/checks/","tags":{},"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 63061BDB1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 22 Jul 2020 13:30:30 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1B81B609C5;\n\tWed, 22 Jul 2020 15:30:30 +0200 (CEST)","from mail-pl1-x636.google.com (mail-pl1-x636.google.com\n\t[IPv6:2607:f8b0:4864:20::636])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5EB1960540\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jul 2020 15:30:29 +0200 (CEST)","by mail-pl1-x636.google.com with SMTP id w17so987799ply.11\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jul 2020 06:30:29 -0700 (PDT)","from kaaira-HP-Pavilion-Notebook ([103.113.213.178])\n\tby smtp.gmail.com with ESMTPSA id\n\tn14sm21791703pgd.78.2020.07.22.06.30.26\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 22 Jul 2020 06:30:26 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=es-iitr-ac-in.20150623.gappssmtp.com\n\theader.i=@es-iitr-ac-in.20150623.gappssmtp.com\n\theader.b=\"1FyqB4Kf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=es-iitr-ac-in.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=KSv3HNYWyvKZjLaLjbxU0Va1M99Ttw6+yOqTeHiqQqo=;\n\tb=1FyqB4KfD+VMyvTbYFuYpK2+MrsgenBgtBYa4rATVdo9F7zoEWcBuDIs66/uvtJhYY\n\t6iwZnoe6P/CgsP4t44t8RgPipFY+ASk04PuDIVPuTr4nNnSTpzOXQSZq1uQXnLy4xejN\n\tFUkBD+yInOIhitkrg4tq2biMwqdfGadMH6WhMz0/EPtxRlvo8+VDgBq1xbz/7o9/+8YL\n\tcap34UVvfA5h2WKfv953nVWciaRBq3tuzGYAromrZ2IU4C1anISgavneUzsF/km62ltm\n\tKY28iT6/QNv92cTrglf4TW0HIB3Q4u4rHrTjQKFyXKQ7/A3zPin7L5m8mq6+QIOYWyyc\n\t6jUg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=KSv3HNYWyvKZjLaLjbxU0Va1M99Ttw6+yOqTeHiqQqo=;\n\tb=BdUeUVMpuSsp78envmQucfdABp+ogNJIOfpB7qlPAuyrtqiTcHtnXXuSlOUDee9QC7\n\tu/x/YqoqOizTsO7ilVERToNIMiB9Vr01vHtCuQ+eC2Uv2IyeXLUinO4n5shytAkqKFro\n\t2q+ROw1iU7wGLpGLClbsGOqIti8NjqlvETLQdXwN+nq8U1QSXJbyP//LR769cUe7mIDT\n\tqHVK1GiH5SpnJOve/zFzALEhUYMuR2Tc/m0/SiSooQdfZXX3TfSkfa0k/GZUoZmNB+YW\n\tWRqrL3HpkzhDtkYLRX7ip6OwyEwJ3fhTC/TGZnlXsxvslKv3uDEoFVbMMTZNMES5s9ka\n\tmyOQ==","X-Gm-Message-State":"AOAM533Bd6pKHT3ANxDOGifZb0koK2qj8Lu2xEyTY4znSrTxZyCJixQR\n\tzAAgexBX5huTQo/MlrIP6qRgvw==","X-Google-Smtp-Source":"ABdhPJwDrLd74zaSCY7s1Ud818sW9nlNgq1A31DmqYA3nYEZQ8WmAsBKsKlK57cj9/+k2GuSJ2tLqA==","X-Received":"by 2002:a17:90a:d998:: with SMTP id\n\td24mr9718553pjv.43.1595424627318; \n\tWed, 22 Jul 2020 06:30:27 -0700 (PDT)","From":"Kaaira Gupta <kgupta@es.iitr.ac.in>","To":"libcamera-devel@lists.libcamera.org,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>","Date":"Wed, 22 Jul 2020 19:00:05 +0530","Message-Id":"<20200722133009.26528-4-kgupta@es.iitr.ac.in>","X-Mailer":"git-send-email 2.17.1","In-Reply-To":"<20200722133009.26528-1-kgupta@es.iitr.ac.in>","References":"<20200722133009.26528-1-kgupta@es.iitr.ac.in>","Subject":"[libcamera-devel] [PATCH 3/7] libcamera: pipeline: vimc: Generate\n\tand Validate stream configurations","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":"Kaaira Gupta <kgupta@es.iitr.ac.in>","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"Implement generating configurations for StillCaptureRaw role. Also\nvalidate them.\n\nDeclare a bool which takes note of the configuration which is raw (if\nany).\nIf two configurations are asked for, we consider one of them to be asking\nfor a raw stream.\nIf no role is provided, consider the configuration with least with to\nbe associated wth raw stream.\nIf both the pixelformat and size are provided, give preferance to pixelformat\nin determining the configuration with raw stream.\n\nSigned-off-by: Kaaira Gupta <kgupta@es.iitr.ac.in>\n---\n src/libcamera/pipeline/vimc/vimc.cpp | 180 ++++++++++++++++++---------\n 1 file changed, 122 insertions(+), 58 deletions(-)","diff":"diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp\nindex bd6ddde..83dd541 100644\n--- a/src/libcamera/pipeline/vimc/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc/vimc.cpp\n@@ -117,6 +117,17 @@ static const std::map<PixelFormat, uint32_t> pixelformats{\n \t{ formats::BGR888, MEDIA_BUS_FMT_RGB888_1X24 },\n };\n \n+static const std::map<PixelFormat, uint32_t> pixelFormatsRaw{\n+\t{ formats::SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8 },\n+\t{ formats::SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8 },\n+\t{ formats::SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8 },\n+\t{ formats::SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8 },\n+\t{ formats::SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10 },\n+\t{ formats::SGBRG10, MEDIA_BUS_FMT_SGBRG10_1X10 },\n+\t{ formats::SGRBG10, MEDIA_BUS_FMT_SGRBG10_1X10 },\n+\t{ formats::SRGGB10, MEDIA_BUS_FMT_SRGGB10_1X10 }\n+};\n+\n } /* namespace */\n \n VimcCameraConfiguration::VimcCameraConfiguration(VimcCameraData *data)\n@@ -127,53 +138,90 @@ VimcCameraConfiguration::VimcCameraConfiguration(VimcCameraData *data)\n CameraConfiguration::Status VimcCameraConfiguration::validate()\n {\n \tStatus status = Valid;\n+\tbool hasRaw = false;\n+\tunsigned rindex = 2;\n+\tint ret;\n \n \tif (config_.empty())\n \t\treturn Invalid;\n \n \t/* Cap the number of entries to the available streams. */\n-\tif (config_.size() > 1) {\n-\t\tconfig_.resize(1);\n+\tif (config_.size() > 2) {\n+\t\tconfig_.resize(2);\n \t\tstatus = Adjusted;\n \t}\n \n-\tStreamConfiguration &cfg = config_[0];\n-\n-\t/* Adjust the pixel format. */\n-\tconst std::vector<libcamera::PixelFormat> formats = cfg.formats().pixelformats();\n-\tif (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == formats.end()) {\n-\t\tLOG(VIMC, Debug) << \"Adjusting format to BGR888\";\n-\t\tcfg.pixelFormat = formats::BGR888;\n-\t\tstatus = Adjusted;\n+\tif (config_.size() > 1) {\n+\t\tif (config_[0].size.width < config_[1].size.width) {\n+\t\t\trindex = 0;\n+\t\t} else {\n+\t\t\trindex = 1;\n+\t\t}\n+\t\thasRaw = true;\n \t}\n \n-\t/* Clamp the size based on the device limits. */\n-\tconst Size size = cfg.size;\n-\n-\t/* The scaler hardcodes a x3 scale-up ratio. */\n-\tcfg.size.width = std::max(48U, std::min(4096U, cfg.size.width));\n-\tcfg.size.height = std::max(48U, std::min(2160U, cfg.size.height));\n-\tcfg.size.width -= cfg.size.width % 3;\n-\tcfg.size.height -= cfg.size.height % 3;\n-\n-\tif (cfg.size != size) {\n-\t\tLOG(VIMC, Debug)\n-\t\t\t<< \"Adjusting size to \" << cfg.size.toString();\n-\t\tstatus = Adjusted;\n+\tfor (unsigned i = 0; i < config_.size(); i++) {\n+\t\tconst PixelFormatInfo &info = PixelFormatInfo::info(config_[i].pixelFormat);\n+\t\tif (info.isRaw(config_[i].pixelFormat)) {\n+\t\t\trindex = i;\n+\t\t\thasRaw = true;\n+\t\t}\n \t}\n \n-\tcfg.bufferCount = 4;\n+\tfor (unsigned i = 0; i < config_.size(); i++) {\n+\t\tStreamConfiguration &cfg = config_[i];\n+\t\tV4L2DeviceFormat format = {};\n+\t\tconst Size size = cfg.size;\n+\t\tif (i == rindex) {\n+\t\t\t/* Clamp the size based on the device limits. */\n+\t\t\tcfg.size.width = std::max(16U, std::min(1365U, cfg.size.width));\n+\t\t\tcfg.size.height = std::max(16U, std::min(720U, cfg.size.height));\n+\t\t\t/* Adjust the pixel format. */\n+\t\t\tif (pixelFormatsRaw.find(cfg.pixelFormat) == pixelFormatsRaw.end()) {\n+\t\t\t\tLOG(VIMC, Debug) << \"Adjusting format to SGRBG8\";\n+\t\t\t\tcfg.pixelFormat = formats::SGRBG8;\n+\t\t\t\tstatus = Adjusted;\n+\t\t\t}\n+\t\t\tformat.fourcc = data_->raw_->toV4L2PixelFormat(cfg.pixelFormat);\n+\t\t\tformat.size = cfg.size;\n+\t\t\tret = data_->raw_->tryFormat(&format);\n+\t\t} else {\n+\t\t\tconst std::vector<libcamera::PixelFormat> formats = cfg.formats().pixelformats();\n+\t\t\tif (hasRaw) {\n+\t\t\t\tcfg.size.width = config_[(i + 1) % 2].size.width * 3;\n+\t\t\t\tcfg.size.height = config_[(i + 1) % 2].size.height * 3;\n+\t\t\t} else {\n+\t\t\t\t/* Clamp the size based on the device limits. */\n+\t\t\t\tcfg.size.width = std::max(48U, std::min(4096U, cfg.size.width));\n+\t\t\t\tcfg.size.height = std::max(48U, std::min(2160U, cfg.size.height));\n+\t\t\t\t/* The scaler hardcodes a x3 scale-up ratio. */\n+\t\t\t\tcfg.size.width -= cfg.size.width % 3;\n+\t\t\t\tcfg.size.height -= cfg.size.height % 3;\n+\t\t\t}\n \n-\tV4L2DeviceFormat format = {};\n-\tformat.fourcc = data_->video_->toV4L2PixelFormat(cfg.pixelFormat);\n-\tformat.size = cfg.size;\n+\t\t\t/* Adjust the pixel format. */\n+\t\t\tif (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == formats.end()) {\n+\t\t\t\tLOG(VIMC, Debug) << \"Adjusting format to BGR888\";\n+\t\t\t\tcfg.pixelFormat = formats::BGR888;\n+\t\t\t\tstatus = Adjusted;\n+\t\t\t}\n+\t\t\tformat.fourcc = data_->video_->toV4L2PixelFormat(cfg.pixelFormat);\n+\t\t\tformat.size = cfg.size;\n+\t\t\tret = data_->video_->tryFormat(&format);\n+\t\t}\n \n-\tint ret = data_->video_->tryFormat(&format);\n-\tif (ret)\n-\t\treturn Invalid;\n+\t\tif (ret)\n+\t\t\treturn Invalid;\n+\t\tif (cfg.size != size) {\n+\t\t\tLOG(VIMC, Debug)\n+\t\t\t\t<< \"Adjusting size to \" << cfg.size.toString();\n+\t\t\tstatus = Adjusted;\n+\t\t}\n \n-\tcfg.stride = format.planes[0].bpl;\n-\tcfg.frameSize = format.planes[0].size;\n+\t\tcfg.bufferCount = 4;\n+\t\tcfg.stride = format.planes[0].bpl;\n+\t\tcfg.frameSize = format.planes[0].size;\n+\t}\n \n \treturn status;\n }\n@@ -194,35 +242,51 @@ CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera,\n \n \tstd::map<PixelFormat, std::vector<SizeRange>> formats;\n \n-\tfor (const auto &pixelformat : pixelformats) {\n-\t\t/*\n-\t\t * Kernels prior to v5.7 incorrectly report support for RGB888,\n-\t\t * but it isn't functional within the pipeline.\n-\t\t */\n-\t\tif (data->media_->version() < KERNEL_VERSION(5, 7, 0)) {\n-\t\t\tif (pixelformat.first != formats::BGR888) {\n-\t\t\t\tLOG(VIMC, Info)\n-\t\t\t\t\t<< \"Skipping unsupported pixel format \"\n-\t\t\t\t\t<< pixelformat.first.toString();\n-\t\t\t\tcontinue;\n+\tfor (const StreamRole role : roles) {\n+\t\tswitch (role) {\n+\t\tcase StreamRole::StillCaptureRaw: {\n+\t\t\tfor (const auto &pixelformat : pixelFormatsRaw) {\n+\t\t\t\tstd::vector<SizeRange> sizes{\n+\t\t\t\t\tSizeRange{ { 16, 16 }, { 1365, 720 } }\n+\t\t\t\t};\n+\t\t\t\tformats[pixelformat.first] = sizes;\n+\t\t\t}\n+\t\t\tStreamConfiguration cfg(formats);\n+\t\t\tcfg.pixelFormat = formats::SGRBG8;\n+\t\t\tcfg.size = { 640, 360 };\n+\t\t\tcfg.bufferCount = 4;\n+\t\t\tconfig->addConfiguration(cfg);\n+\t\t\tbreak;\n+\t\t}\n+\t\tdefault:\n+\t\t\tfor (const auto &pixelformat : pixelformats) {\n+\t\t\t\t/*\n+\t\t\t\t * Kernels prior to v5.7 incorrectly report support for RGB888,\n+\t\t\t\t * but it isn't functional within the pipeline.\n+\t\t\t\t */\n+\t\t\t\tif (data->media_->version() < KERNEL_VERSION(5, 7, 0)) {\n+\t\t\t\t\tif (pixelformat.first != formats::BGR888) {\n+\t\t\t\t\t\tLOG(VIMC, Info)\n+\t\t\t\t\t\t\t<< \"Skipping unsupported pixel format \"\n+\t\t\t\t\t\t\t<< pixelformat.first.toString();\n+\t\t\t\t\t\tcontinue;\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\n+\t\t\t\t/* The scaler hardcodes a x3 scale-up ratio. */\n+\t\t\t\tstd::vector<SizeRange> sizes{\n+\t\t\t\t\tSizeRange{ { 48, 48 }, { 4096, 2160 } }\n+\t\t\t\t};\n+\t\t\t\tformats[pixelformat.first] = sizes;\n \t\t\t}\n+\t\t\tStreamConfiguration cfg(formats);\n+\t\t\tcfg.pixelFormat = formats::BGR888;\n+\t\t\tcfg.size = { 1920, 1080 };\n+\t\t\tcfg.bufferCount = 4;\n+\t\t\tconfig->addConfiguration(cfg);\n+\t\t\tbreak;\n \t\t}\n-\n-\t\t/* The scaler hardcodes a x3 scale-up ratio. */\n-\t\tstd::vector<SizeRange> sizes{\n-\t\t\tSizeRange{ { 48, 48 }, { 4096, 2160 } }\n-\t\t};\n-\t\tformats[pixelformat.first] = sizes;\n \t}\n-\n-\tStreamConfiguration cfg(formats);\n-\n-\tcfg.pixelFormat = formats::BGR888;\n-\tcfg.size = { 1920, 1080 };\n-\tcfg.bufferCount = 4;\n-\n-\tconfig->addConfiguration(cfg);\n-\n \tconfig->validate();\n \n \treturn config;\n","prefixes":["libcamera-devel","3/7"]}