@@ -886,53 +886,6 @@ int CameraCapabilities::initializeStaticMetadata()
staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
aeAvailableModes);
- /* Initialize the AE frame duration limits. */
- const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurationLimits);
- int64_t minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000;
- int64_t maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000;
-
- /*
- * Adjust the minimum frame duration to comply with Android
- * requirements. The camera service mandates all preview/record
- * streams to have a minimum frame duration < 33,366 milliseconds
- * (see MAX_PREVIEW_RECORD_DURATION_NS in the camera service
- * implementation).
- *
- * If we're close enough (+ 500 useconds) to that value, round
- * the minimum frame duration of the camera to an accepted
- * value.
- */
- static constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / 29.97;
- if (minFrameDurationNsec > MAX_PREVIEW_RECORD_DURATION_NS &&
- minFrameDurationNsec < MAX_PREVIEW_RECORD_DURATION_NS + 500000)
- minFrameDurationNsec = MAX_PREVIEW_RECORD_DURATION_NS - 1000;
-
- /*
- * The AE routine frame rate limits are computed using the frame
- * duration limits, as libcamera clips the AE routine to the
- * frame durations.
- */
- int32_t maxFps = std::round(1e9 / minFrameDurationNsec);
- int32_t minFps = std::round(1e9 / maxFrameDurationNsec);
- minFps = std::max(1, minFps);
-
- /*
- * Force rounding errors so that we have the proper frame
- * durations for when we reuse these variables later
- */
- minFrameDurationNsec = 1e9 / maxFps;
- maxFrameDurationNsec = 1e9 / minFps;
-
- /*
- * Register to the camera service {min, max} and {max, max}
- * intervals as requested by the metadata documentation.
- */
- int32_t availableAeFpsTarget[] = {
- minFps, maxFps, maxFps, maxFps
- };
- staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
- availableAeFpsTarget);
-
std::vector<int32_t> aeCompensationRange = {
0, 0,
};
@@ -1278,8 +1231,12 @@ int CameraCapabilities::initializeStaticMetadata()
std::vector<uint32_t> availableStreamConfigurations;
std::vector<int64_t> minFrameDurations;
+ int maxYUVFps = 0;
+ Size maxYUVSize;
+
availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
minFrameDurations.reserve(streamConfigurations_.size() * 4);
+
for (const auto &entry : streamConfigurations_) {
/*
* Filter out YUV streams not capable of running at 30 FPS.
@@ -1298,6 +1255,16 @@ int CameraCapabilities::initializeStaticMetadata()
if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB && fps < 30)
continue;
+ /*
+ * Collect the FPS of the maximum YUV output size to populate
+ * AE_AVAILABLE_TARGET_FPS_RANGE
+ */
+ if (entry.androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888 &&
+ entry.resolution > maxYUVSize) {
+ maxYUVSize = entry.resolution;
+ maxYUVFps = fps;
+ }
+
/* Stream configuration map. */
availableStreamConfigurations.push_back(entry.androidFormat);
availableStreamConfigurations.push_back(entry.resolution.width);
@@ -1323,6 +1290,20 @@ int CameraCapabilities::initializeStaticMetadata()
staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
minFrameDurations);
+ /*
+ * Register to the camera service {min, max} and {max, max} with
+ * 'max' being the larger YUV stream maximum frame rate and 'min' being
+ * the globally minimum frame rate rounded to the next largest integer
+ * as the camera service expects the camera maximum frame duration to be
+ * smaller than 10^9 / minFps.
+ */
+ int32_t minFps = std::ceil(1e9 / maxFrameDuration_);
+ int32_t availableAeFpsTarget[] = {
+ minFps, maxYUVFps, maxYUVFps, maxYUVFps,
+ };
+ staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
+ availableAeFpsTarget);
+
std::vector<int64_t> availableStallDurations;
for (const auto &entry : streamConfigurations_) {
if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)