Patch Detail
Show a patch.
GET /api/1.1/patches/15187/?format=api
{ "id": 15187, "url": "https://patchwork.libcamera.org/api/1.1/patches/15187/?format=api", "web_url": "https://patchwork.libcamera.org/patch/15187/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/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": "<20211221044133.2531278-1-paul.elder@ideasonboard.com>", "date": "2021-12-21T04:41:33", "name": "[libcamera-devel,v2] android: Plumb Sharpness control into EDGE_MODE", "commit_ref": null, "pull_url": null, "state": "not-applicable", "archived": false, "hash": "40f7ea992956a557e555c2d22e502ba2b2b3d30a", "submitter": { "id": 17, "url": "https://patchwork.libcamera.org/api/1.1/people/17/?format=api", "name": "Paul Elder", "email": "paul.elder@ideasonboard.com" }, "delegate": { "id": 17, "url": "https://patchwork.libcamera.org/api/1.1/users/17/?format=api", "username": "epaul", "first_name": "Paul", "last_name": "Elder", "email": "paul.elder@ideasonboard.com" }, "mbox": "https://patchwork.libcamera.org/patch/15187/mbox/", "series": [ { "id": 2850, "url": "https://patchwork.libcamera.org/api/1.1/series/2850/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2850", "date": "2021-12-21T04:41:33", "name": "[libcamera-devel,v2] android: Plumb Sharpness control into EDGE_MODE", "version": 2, "mbox": "https://patchwork.libcamera.org/series/2850/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/15187/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/15187/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 C08C3BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 21 Dec 2021 04:41:50 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0D9BC608E8;\n\tTue, 21 Dec 2021 05:41:50 +0100 (CET)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 25BEF60868\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 21 Dec 2021 05:41:48 +0100 (CET)", "from pyrite.mediacom.info (unknown\n\t[IPv6:2604:2d80:ad90:fb00:96fd:8874:873:6c16])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1215C881;\n\tTue, 21 Dec 2021 05:41:46 +0100 (CET)" ], "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=\"hNoiv0hb\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1640061707;\n\tbh=dF5Ts4fNytawe+OCmosRrIEnz6dEkyhneK4SITwvzg8=;\n\th=From:To:Cc:Subject:Date:From;\n\tb=hNoiv0hbZJwbgdwaQX8RC+JxMGcHLeddJgCp6/cZtf/BD1qK6HJt9xh9ChjmzJWfG\n\tO39pYFAT14dsfQOCWB+0OxkZcQAdkEtvVg7aTIiKMHOB5YchqaaB5Wz6sVJkkaBsgn\n\tMRyM6jeWQ+Y01bv7ZYwDph+OdI0GbYrP3rTFIaso=", "From": "Paul Elder <paul.elder@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Mon, 20 Dec 2021 22:41:33 -0600", "Message-Id": "<20211221044133.2531278-1-paul.elder@ideasonboard.com>", "X-Mailer": "git-send-email 2.27.0", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v2] android: Plumb Sharpness control into\n\tEDGE_MODE", "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": "Plumb the Sharpness control into the HAL for EDGE_MODE and other related\nandroid controls.\n\nlibcamera doesn't distinguish between fast and HQ, but rather with a\nfloating value for how much sharpening to apply. This is thus\nunsufficient information for retaining whether the request was for fast\nor HQ, so save it in the request, and report what was requested.\n\nBug: https://bugs.libcamera.org/show_bug.cgi?id=46\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\n\n---\nThis patch depends on \"android: camera_metadata: Add appendEntry helper\"\n\nChanges in v2:\n- fix the assertions in template creation\n- report the edge mode that was requested, instead of doing conversion\n to and from the floating value and its ControlInfo\n- move edge mode capability check out of manual control (as docs say\n it's not required) and into the top-level FULL hardware level\n validator\n---\n src/android/camera_capabilities.cpp | 44 +++++++++++++++++++++++++++++\n src/android/camera_device.cpp | 28 ++++++++++++++++++\n src/android/camera_request.h | 4 +++\n 3 files changed, 76 insertions(+)", "diff": "diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp\nindex b9a1f6e5..727204b9 100644\n--- a/src/android/camera_capabilities.cpp\n+++ b/src/android/camera_capabilities.cpp\n@@ -401,6 +401,11 @@ void CameraCapabilities::computeHwLevel(\n \tif (!caps.count(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE))\n \t\thwLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;\n \n+\tif (!staticMetadata_->hasEntry(ANDROID_EDGE_AVAILABLE_EDGE_MODES)) {\n+\t\tLOG(HAL, Info) << noFull << \"missing edge modes\";\n+\t\thwLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;\n+\t}\n+\n \tfound = staticMetadata_->getEntry(ANDROID_SYNC_MAX_LATENCY, &entry);\n \tif (!found || *entry.data.i32 != 0) {\n \t\tLOG(HAL, Info) << noFull << \"missing or invalid max sync latency\";\n@@ -1078,6 +1083,21 @@ int CameraCapabilities::initializeStaticMetadata()\n \tstaticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,\n \t\t\t\t availableControlModes);\n \n+\tconst auto &edgeInfo = controlsInfo.find(&controls::Sharpness);\n+\tif (edgeInfo != controlsInfo.end()) {\n+\t\tstd::vector<uint8_t> availableEdgeModes = {\n+\t\t\tANDROID_EDGE_MODE_OFF,\n+\t\t\tANDROID_EDGE_MODE_FAST,\n+\t\t\tANDROID_EDGE_MODE_HIGH_QUALITY,\n+\t\t};\n+\n+\t\tstaticMetadata_->addEntry(ANDROID_EDGE_AVAILABLE_EDGE_MODES,\n+\t\t\t\t\t availableEdgeModes);\n+\t\tavailableCharacteristicsKeys_.insert(ANDROID_EDGE_AVAILABLE_EDGE_MODES);\n+\t\tavailableRequestKeys_.insert(ANDROID_EDGE_MODE);\n+\t\tavailableResultKeys_.insert(ANDROID_EDGE_MODE);\n+\t}\n+\n \t/* JPEG static metadata. */\n \n \t/*\n@@ -1593,6 +1613,12 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateManual() cons\n \t\tmanualTemplate->appendEntry(ANDROID_CONTROL_AE_MODE, aeMode);\n \t}\n \n+\tif (staticMetadata_->entryContains<uint8_t>(ANDROID_EDGE_AVAILABLE_EDGE_MODES,\n+\t\t\t\t\t\t ANDROID_EDGE_MODE_OFF)) {\n+\t\tuint8_t edgeMode = ANDROID_EDGE_MODE_OFF;\n+\t\tmanualTemplate->appendEntry(ANDROID_EDGE_MODE, edgeMode);\n+\t}\n+\n \treturn manualTemplate;\n }\n \n@@ -1675,6 +1701,12 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplatePreview() con\n \tif (availableRequestKeys_.count(ANDROID_SENSOR_SENSITIVITY))\n \t\trequestTemplate->addEntry(ANDROID_SENSOR_SENSITIVITY, minISO_);\n \n+\tif (staticMetadata_->entryContains<uint8_t>(ANDROID_EDGE_AVAILABLE_EDGE_MODES,\n+\t\t\t\t\t\t ANDROID_EDGE_MODE_FAST)) {\n+\t\tuint8_t edgeMode = ANDROID_EDGE_MODE_FAST;\n+\t\trequestTemplate->addEntry(ANDROID_EDGE_MODE, edgeMode);\n+\t}\n+\n \tuint8_t flashMode = ANDROID_FLASH_MODE_OFF;\n \trequestTemplate->addEntry(ANDROID_FLASH_MODE, flashMode);\n \n@@ -1713,6 +1745,12 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateStill() const\n \tif (!stillTemplate)\n \t\treturn nullptr;\n \n+\tif (staticMetadata_->entryContains<uint8_t>(ANDROID_EDGE_AVAILABLE_EDGE_MODES,\n+\t\t\t\t\t\t ANDROID_EDGE_MODE_HIGH_QUALITY)) {\n+\t\tuint8_t edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY;\n+\t\tstillTemplate->appendEntry(ANDROID_EDGE_MODE, edgeMode);\n+\t}\n+\n \treturn stillTemplate;\n }\n \n@@ -1730,6 +1768,12 @@ std::unique_ptr<CameraMetadata> CameraCapabilities::requestTemplateVideo() const\n \tstaticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,\n \t\t\t\t &entry);\n \n+\tif (staticMetadata_->entryContains<uint8_t>(ANDROID_EDGE_AVAILABLE_EDGE_MODES,\n+\t\t\t\t\t\t ANDROID_EDGE_MODE_FAST)) {\n+\t\tuint8_t edgeMode = ANDROID_EDGE_MODE_FAST;\n+\t\tpreviewTemplate->appendEntry(ANDROID_EDGE_MODE, edgeMode);\n+\t}\n+\n \t/*\n \t * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata\n \t * has been assembled as {{min, max} {max, max}}.\ndiff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\nindex 1a508923..0d668ea6 100644\n--- a/src/android/camera_device.cpp\n+++ b/src/android/camera_device.cpp\n@@ -920,6 +920,26 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)\n \t\t\tcontrols.set(controls::DigitalGain, lastDigitalGain_);\n \t}\n \n+\tif (settings.getEntry(ANDROID_EDGE_MODE, &entry)) {\n+\t\tconst auto &info = camera_->controls().find(&controls::Sharpness);\n+\t\tif (info != camera_->controls().end()) {\n+\t\t\tfloat min = info->second.min().get<float>();\n+\t\t\tfloat def = info->second.def().get<float>();\n+\t\t\tfloat max = info->second.max().get<float>();\n+\t\t\t/*\n+\t\t\t * The default value might be unusable since control\n+\t\t\t * serialization ignores it. Alternatively the default\n+\t\t\t * could be simply set to zero or the minimum value.\n+\t\t\t * Use the maximum sharpness value in these cases.\n+\t\t\t */\n+\t\t\tfloat val = (def == 0.0f || def == min) ? max : def;\n+\t\t\tcontrols.set(controls::Sharpness,\n+\t\t\t\t *entry.data.u8 == ANDROID_EDGE_MODE_OFF ? min : val);\n+\n+\t\t\tdescriptor->edgeMode_ = *entry.data.u8;\n+\t\t}\n+\t}\n+\n \treturn 0;\n }\n \n@@ -1602,6 +1622,14 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons\n \t\t\t\t\t duration);\n \t}\n \n+\tif (metadata.contains(controls::Sharpness)) {\n+\t\t/*\n+\t\t * libcamera doesn't distinguish between fast vs HQ sharpening\n+\t\t * modes. Report the mode that was requested.\n+\t\t */\n+\t\tresultMetadata->addEntry(ANDROID_EDGE_MODE, descriptor.edgeMode_);\n+\t}\n+\n \tif (metadata.contains(controls::ScalerCrop)) {\n \t\tRectangle crop = metadata.get(controls::ScalerCrop);\n \t\tint32_t cropRect[] = {\ndiff --git a/src/android/camera_request.h b/src/android/camera_request.h\nindex b2809179..69b6c8fc 100644\n--- a/src/android/camera_request.h\n+++ b/src/android/camera_request.h\n@@ -87,6 +87,10 @@ public:\n \t/* The libcamera internal AE state for this request */\n \tAutoMode aeMode_ = AutoMode::Auto;\n \n+\t/* The android edge mode associated with this request */\n+\t/* \\todo Wrap all such controls? */\n+\tint32_t edgeMode_;\n+\n private:\n \tLIBCAMERA_DISABLE_COPY(Camera3RequestDescriptor)\n };\n", "prefixes": [ "libcamera-devel", "v2" ] }