[{"id":20085,"web_url":"https://patchwork.libcamera.org/comment/20085/","msgid":"<YV0A/jo0SVec/MH1@pendragon.ideasonboard.com>","date":"2021-10-06T01:50:54","subject":"Re: [libcamera-devel] [PATCH v2 14/17] android: capabilties: Fix\n\tANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Tue, Sep 07, 2021 at 09:41:04PM +0200, Jacopo Mondi wrote:\n> As reported by the CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES documentation\n> in the Android developer reference:\n> \n> \"For devices advertising any color filter arrangement other than NIR, or\n> devices not advertising color filter arrangement, this list will always\n> include (min, max) and (max, max) where min <= 15 and max = the maximum\n> output frame rate of the maximum YUV_420_888 output size.\"\n> \n> Collect the higher FPS of the larger YUV stream and use it with the\n> minimum FPS rate the camera can produce to populate the\n> ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES static metadata.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n> ---\n>  src/android/camera_capabilities.cpp | 75 +++++++++++------------------\n>  1 file changed, 28 insertions(+), 47 deletions(-)\n> \n> diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp\n> index 194ede866806..deaec3282fd7 100644\n> --- a/src/android/camera_capabilities.cpp\n> +++ b/src/android/camera_capabilities.cpp\n> @@ -866,53 +866,6 @@ int CameraCapabilities::initializeStaticMetadata()\n>  \tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,\n>  \t\t\t\t  aeAvailableModes);\n>  \n> -\t/* Initialize the AE frame duration limits. */\n> -\tconst auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurationLimits);\n> -\tint64_t minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000;\n> -\tint64_t maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000;\n> -\n> -\t/*\n> -\t * Adjust the minimum frame duration to comply with Android\n> -\t * requirements. The camera service mandates all preview/record\n> -\t * streams to have a minimum frame duration < 33,366 milliseconds\n> -\t * (see MAX_PREVIEW_RECORD_DURATION_NS in the camera service\n> -\t * implementation).\n> -\t *\n> -\t * If we're close enough (+ 500 useconds) to that value, round\n> -\t * the minimum frame duration of the camera to an accepted\n> -\t * value.\n> -\t */\n> -\tstatic constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / 29.97;\n> -\tif (minFrameDurationNsec > MAX_PREVIEW_RECORD_DURATION_NS &&\n> -\t    minFrameDurationNsec < MAX_PREVIEW_RECORD_DURATION_NS + 500000)\n> -\t\tminFrameDurationNsec = MAX_PREVIEW_RECORD_DURATION_NS - 1000;\n\nI really like how we finally drop this.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> -\n> -\t/*\n> -\t * The AE routine frame rate limits are computed using the frame\n> -\t * duration limits, as libcamera clips the AE routine to the\n> -\t * frame durations.\n> -\t */\n> -\tint32_t maxFps = std::round(1e9 / minFrameDurationNsec);\n> -\tint32_t minFps = std::round(1e9 / maxFrameDurationNsec);\n> -\tminFps = std::max(1, minFps);\n> -\n> -\t/*\n> -\t * Force rounding errors so that we have the proper frame\n> -\t * durations for when we reuse these variables later\n> -\t */\n> -\tminFrameDurationNsec = 1e9 / maxFps;\n> -\tmaxFrameDurationNsec = 1e9 / minFps;\n> -\n> -\t/*\n> -\t * Register to the camera service {min, max} and {max, max}\n> -\t * intervals as requested by the metadata documentation.\n> -\t */\n> -\tint32_t availableAeFpsTarget[] = {\n> -\t\tminFps, maxFps, maxFps, maxFps\n> -\t};\n> -\tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,\n> -\t\t\t\t  availableAeFpsTarget);\n> -\n>  \tstd::vector<int32_t> aeCompensationRange = {\n>  \t\t0, 0,\n>  \t};\n> @@ -1258,8 +1211,12 @@ int CameraCapabilities::initializeStaticMetadata()\n>  \n>  \tstd::vector<uint32_t> availableStreamConfigurations;\n>  \tstd::vector<int64_t> minFrameDurations;\n> +\tint maxYUVFps = 0;\n> +\tSize maxYUVSize;\n> +\n>  \tavailableStreamConfigurations.reserve(streamConfigurations_.size() * 4);\n>  \tminFrameDurations.reserve(streamConfigurations_.size() * 4);\n> +\n>  \tfor (const auto &entry : streamConfigurations_) {\n>  \t\t/*\n>  \t\t * Filter out YUV streams not capable of running at 30 FPS.\n> @@ -1276,6 +1233,16 @@ int CameraCapabilities::initializeStaticMetadata()\n>  \t\tif (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB && fps < 30)\n>  \t\t\tcontinue;\n>  \n> +\t\t/*\n> +\t\t * Collect the FPS of the maximum YUV output size to populate\n> +\t\t * AE_AVAILABLE_TARGET_FPS_RANGE\n> +\t\t */\n> +\t\tif (entry.androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888 &&\n> +\t\t    entry.resolution > maxYUVSize) {\n> +\t\t\tmaxYUVSize = entry.resolution;\n> +\t\t\tmaxYUVFps = fps;\n> +\t\t}\n> +\n>  \t\t/* Stream configuration map. */\n>  \t\tavailableStreamConfigurations.push_back(entry.androidFormat);\n>  \t\tavailableStreamConfigurations.push_back(entry.resolution.width);\n> @@ -1303,6 +1270,20 @@ int CameraCapabilities::initializeStaticMetadata()\n>  \tstaticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,\n>  \t\t\t\t  minFrameDurations);\n>  \n> +\t/*\n> +\t * Register to the camera service {min, max} and {max, max} with\n> +\t * 'max' being the larger YUV stream maximum frame rate and 'min' being\n> +\t * the globally minimum frame rate rounded to the next largest integer\n> +\t * as the camera service expects the camera maximum frame duration to be\n> +\t * smaller than 10^9 / minFps.\n> +\t */\n> +\tint32_t minFps = std::ceil(1e9 / maxFrameDuration_);\n> +\tint32_t availableAeFpsTarget[] = {\n> +\t\tminFps, maxYUVFps, maxYUVFps, maxYUVFps,\n> +\t};\n> +\tstaticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,\n> +\t\t\t\t  availableAeFpsTarget);\n> +\n>  \tstd::vector<int64_t> availableStallDurations;\n>  \tfor (const auto &entry : streamConfigurations_) {\n>  \t\tif (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)","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 804AFBDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  6 Oct 2021 01:51:05 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E9071691BC;\n\tWed,  6 Oct 2021 03:51:04 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D588C6012B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  6 Oct 2021 03:51:02 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 50495581;\n\tWed,  6 Oct 2021 03:51:02 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"NGNvxJQ3\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1633485062;\n\tbh=R4Aj2kedpoVaM2QQX1H1yYyEhcrnLi4lsZW2X1YnjBM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=NGNvxJQ3kELM9ekc+OIfxgLpKPD/B3jUj91zEU7QF4yPuhJxMdxU1Whwi6MCETFKE\n\t1tiBXt6ZR/61VXM33RBbs/1ZS3Fq7xyyFenut17do8awJW48Kda8kxumA6O1nbtpIH\n\tDQcwi2fo1787F6v4ZiyuRl8CtkfkJ8nZREnZVitg=","Date":"Wed, 6 Oct 2021 04:50:54 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<YV0A/jo0SVec/MH1@pendragon.ideasonboard.com>","References":"<20210907194107.803730-1-jacopo@jmondi.org>\n\t<20210907194107.803730-15-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210907194107.803730-15-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH v2 14/17] android: capabilties: Fix\n\tANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES","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":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]