Patch Detail
Show a patch.
GET /api/patches/15112/?format=api
{ "id": 15112, "url": "https://patchwork.libcamera.org/api/patches/15112/?format=api", "web_url": "https://patchwork.libcamera.org/patch/15112/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20211210112142.18441-9-david.plowman@raspberrypi.com>", "date": "2021-12-10T11:21:42", "name": "[libcamera-devel,v11,8/8] libcamera: pipeline: raspberrypi: Support color spaces", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "a9936057a9cc176f396302eb8a95f911907c1b91", "submitter": { "id": 42, "url": "https://patchwork.libcamera.org/api/people/42/?format=api", "name": "David Plowman", "email": "david.plowman@raspberrypi.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/15112/mbox/", "series": [ { "id": 2834, "url": "https://patchwork.libcamera.org/api/series/2834/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2834", "date": "2021-12-10T11:21:34", "name": "Colour spaces", "version": 11, "mbox": "https://patchwork.libcamera.org/series/2834/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/15112/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/15112/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 86419C324B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 10 Dec 2021 11:22:13 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3C4BF608E8;\n\tFri, 10 Dec 2021 12:22:13 +0100 (CET)", "from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com\n\t[IPv6:2a00:1450:4864:20::32c])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4CC2D6088E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Dec 2021 12:22:09 +0100 (CET)", "by mail-wm1-x32c.google.com with SMTP id y196so6545193wmc.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Dec 2021 03:22:09 -0800 (PST)", "from pi4-davidp.pitowers.org\n\t([2a00:1098:3142:14:e4a2:3070:eea4:e434])\n\tby smtp.gmail.com with ESMTPSA id\n\tz18sm2198469wrq.11.2021.12.10.03.22.08\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 10 Dec 2021 03:22:08 -0800 (PST)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"kP9r44re\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=Iw1oXJ4y6qHk5Vh9ACkUHIhW6uieykJz0tu6MkgxSbg=;\n\tb=kP9r44rexQ2r71m2z9pSpOWMlBQ/SpakNxn9udNZR8c+RpbGW8U5MiJ+sFnJvjCBka\n\tOkljS+XtSAPjLkz0ZXcGCu+/pXvO/mewzlJ+rIWpTVOdJxuXK7QCCzpV5jWW9FUHdc1Z\n\taUNOShaZ4ikyL/Ovdl4YR5FLPJW10t/r2Yu/mfY6XfgsgsshHsQj9BPC4sWefQDxG2xq\n\t1dNGuxi5fKq1IZrE3vZoDzgmQveTFIaEkCHdaJTgqMbeuO2peHgehmsHSeIwwoF3QfyI\n\t6z358j1DWtnH0wcLBvX0w0vKzauhfM8Khc773+lj8cmiSL76UaZI5Iya4zOMrmZxziDp\n\twgXw==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=Iw1oXJ4y6qHk5Vh9ACkUHIhW6uieykJz0tu6MkgxSbg=;\n\tb=u5mi7RZLKH2PXpUyjPWRZwD4jxCpVQtSpoiIhIzm4YL7bLMWIq5ZkWyjGCF6K3HZ7I\n\tfxEni+G4cH8d5nh2AWBdt6Vcb099/gFGiRVqEm5deDUXVnZ/0Y6I5Jx2CHOmt6AhBTA1\n\tMIkGZoYDSN3BzfCaBxiFM69w/lly3l8ZcZXQeL4LYL3YPIBTh8/SVeMPJN9AAAyii6zu\n\tvQImStKCITrV6UVqGAFUduY15+98LagY1WF1kuR0p0n3sYkuM2eCkq/0vynZcBiU+cXm\n\tV9wafu49NULRydqGrfQuDOm8sY91EdrMkNn6ntaDuMEchPAVTPanJZ6WaKdPPVKOhtSO\n\tXJyw==", "X-Gm-Message-State": "AOAM531UUJOrk4ZlSHpfrAKxPMsR5D5nLNqk7rBeEb190s/7rf9V7gjr\n\tFlkXe0oUvOJ3dZQ4gSiuXNeLO80mSc+0+A==", "X-Google-Smtp-Source": "ABdhPJyGCaGpfkL82qLEopPdhkhwmi4enN0raSRbBX+PXkXdOhmjzx4x2XfaQ1DaR6I5f335mDvnyA==", "X-Received": "by 2002:a7b:ce8c:: with SMTP id\n\tq12mr16007978wmj.91.1639135328970; \n\tFri, 10 Dec 2021 03:22:08 -0800 (PST)", "From": "David Plowman <david.plowman@raspberrypi.com>", "To": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tHans Verkuil <hverkuil-cisco@xs4all.nl>, Tomasz Figa <tfiga@google.com>, \n\tJacopo Mondi <jacopo@jmondi.org>,\n\tNaushir Patuck <naush@raspberrypi.com>, \n\tlibcamera-devel@lists.libcamera.org", "Date": "Fri, 10 Dec 2021 11:21:42 +0000", "Message-Id": "<20211210112142.18441-9-david.plowman@raspberrypi.com>", "X-Mailer": "git-send-email 2.30.2", "In-Reply-To": "<20211210112142.18441-1-david.plowman@raspberrypi.com>", "References": "<20211210112142.18441-1-david.plowman@raspberrypi.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v11 8/8] libcamera: pipeline: raspberrypi:\n\tSupport color spaces", "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>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "The Raspberry Pi pipeline handler now sets color spaces correctly.\n\nIn generateConfiguration() it sets them to reasonable default values\nbased on the stream role.\n\nvalidate() now calls validateColorSpaces() to ensure that the\nrequested color spaces are sensible, before proceeding to check what\nthe hardware can deliver.\n\nSigned-off-by: David Plowman <david.plowman@raspberrypi.com>\n---\n .../pipeline/raspberrypi/raspberrypi.cpp | 40 +++++++++++++++++++\n 1 file changed, 40 insertions(+)", "diff": "diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\nindex 86851ac4..eb74d96c 100644\n--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n@@ -96,6 +96,7 @@ V4L2DeviceFormat toV4L2DeviceFormat(const V4L2SubdeviceFormat &format,\n \n \tdeviceFormat.fourcc = V4L2PixelFormat::fromPixelFormat(pix);\n \tdeviceFormat.size = format.size;\n+\tdeviceFormat.colorSpace = format.colorSpace;\n \treturn deviceFormat;\n }\n \n@@ -132,6 +133,7 @@ V4L2SubdeviceFormat findBestFormat(const SensorFormats &formatsMap, const Size &\n {\n \tdouble bestScore = std::numeric_limits<double>::max(), score;\n \tV4L2SubdeviceFormat bestFormat;\n+\tbestFormat.colorSpace = ColorSpace::Raw;\n \n \tconstexpr float penaltyAr = 1500.0;\n \tconstexpr float penaltyBitDepth = 500.0;\n@@ -329,6 +331,8 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()\n \tif (config_.empty())\n \t\treturn Invalid;\n \n+\tstatus = validateColorSpaces(ColorSpaceFlag::StreamsShareColorSpace);\n+\n \t/*\n \t * What if the platform has a non-90 degree rotation? We can't even\n \t * \"adjust\" the configuration and carry on. Alternatively, raising an\n@@ -496,11 +500,25 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()\n \t\tV4L2DeviceFormat format;\n \t\tformat.fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat);\n \t\tformat.size = cfg.size;\n+\t\tformat.colorSpace = cfg.colorSpace;\n+\n+\t\tLOG(RPI, Debug)\n+\t\t\t<< \"Try color space \" << ColorSpace::toString(cfg.colorSpace);\n \n \t\tint ret = dev->tryFormat(&format);\n \t\tif (ret)\n \t\t\treturn Invalid;\n \n+\t\tif (!format.colorSpace || cfg.colorSpace != format.colorSpace) {\n+\t\t\tstatus = Adjusted;\n+\t\t\tLOG(RPI, Debug)\n+\t\t\t\t<< \"Color space changed from \"\n+\t\t\t\t<< ColorSpace::toString(cfg.colorSpace) << \" to \"\n+\t\t\t\t<< ColorSpace::toString(format.colorSpace);\n+\t\t}\n+\n+\t\tcfg.colorSpace = format.colorSpace;\n+\n \t\tcfg.stride = format.planes[0].bpl;\n \t\tcfg.frameSize = format.planes[0].size;\n \n@@ -524,6 +542,7 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,\n \tPixelFormat pixelFormat;\n \tV4L2VideoDevice::Formats fmts;\n \tSize size;\n+\tstd::optional<ColorSpace> colorSpace;\n \n \tif (roles.empty())\n \t\treturn config;\n@@ -539,6 +558,7 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,\n \t\t\tpixelFormat = mbusCodeToPixelFormat(sensorFormat.mbus_code,\n \t\t\t\t\t\t\t BayerFormat::Packing::CSI2);\n \t\t\tASSERT(pixelFormat.isValid());\n+\t\t\tcolorSpace = ColorSpace::Raw;\n \t\t\tbufferCount = 2;\n \t\t\trawCount++;\n \t\t\tbreak;\n@@ -546,6 +566,12 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,\n \t\tcase StreamRole::StillCapture:\n \t\t\tfmts = data->isp_[Isp::Output0].dev()->formats();\n \t\t\tpixelFormat = formats::NV12;\n+\t\t\t/*\n+\t\t\t * Still image codecs usually expect the JPEG color space.\n+\t\t\t * Even RGB codecs will be fine as the RGB we get with the\n+\t\t\t * JPEG color space is the same as sRGB.\n+\t\t\t */\n+\t\t\tcolorSpace = ColorSpace::Jpeg;\n \t\t\t/* Return the largest sensor resolution. */\n \t\t\tsize = sensorSize;\n \t\t\tbufferCount = 1;\n@@ -563,6 +589,11 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,\n \t\t\t */\n \t\t\tfmts = data->isp_[Isp::Output0].dev()->formats();\n \t\t\tpixelFormat = formats::YUV420;\n+\t\t\t/*\n+\t\t\t * Choose a color space appropriate for video recording.\n+\t\t\t * Rec.709 will be a good default for HD resolutions.\n+\t\t\t */\n+\t\t\tcolorSpace = ColorSpace::Rec709;\n \t\t\tsize = { 1920, 1080 };\n \t\t\tbufferCount = 4;\n \t\t\toutCount++;\n@@ -571,6 +602,7 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,\n \t\tcase StreamRole::Viewfinder:\n \t\t\tfmts = data->isp_[Isp::Output0].dev()->formats();\n \t\t\tpixelFormat = formats::ARGB8888;\n+\t\t\tcolorSpace = ColorSpace::Jpeg;\n \t\t\tsize = { 800, 600 };\n \t\t\tbufferCount = 4;\n \t\t\toutCount++;\n@@ -617,6 +649,7 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,\n \t\tStreamConfiguration cfg(formats);\n \t\tcfg.size = size;\n \t\tcfg.pixelFormat = pixelFormat;\n+\t\tcfg.colorSpace = colorSpace;\n \t\tcfg.bufferCount = bufferCount;\n \t\tconfig->addConfiguration(cfg);\n \t}\n@@ -724,6 +757,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n \t\tV4L2PixelFormat fourcc = V4L2PixelFormat::fromPixelFormat(cfg.pixelFormat);\n \t\tformat.size = cfg.size;\n \t\tformat.fourcc = fourcc;\n+\t\tformat.colorSpace = cfg.colorSpace;\n \n \t\tLOG(RPI, Debug) << \"Setting \" << stream->name() << \" to \"\n \t\t\t\t<< format.toString();\n@@ -739,6 +773,10 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n \t\t\treturn -EINVAL;\n \t\t}\n \n+\t\tLOG(RPI, Debug)\n+\t\t\t<< \"Stream \" << stream->name() << \" has color space \"\n+\t\t\t<< ColorSpace::toString(cfg.colorSpace);\n+\n \t\tcfg.setStream(stream);\n \t\tstream->setExternal(true);\n \n@@ -763,6 +801,8 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n \t\tformat = {};\n \t\tformat.size = maxSize;\n \t\tformat.fourcc = V4L2PixelFormat::fromPixelFormat(formats::YUV420);\n+\t\t/* No one asked for output, so the color space doesn't matter. */\n+\t\tformat.colorSpace = ColorSpace::Jpeg;\n \t\tret = data->isp_[Isp::Output0].dev()->setFormat(&format);\n \t\tif (ret) {\n \t\t\tLOG(RPI, Error)\n", "prefixes": [ "libcamera-devel", "v11", "8/8" ] }