mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-24 00:55:07 +03:00
android: capabilties: Fix ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES
As reported by the CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES documentation in the Android developer reference: "For devices advertising any color filter arrangement other than NIR, or devices not advertising color filter arrangement, this list will always include (min, max) and (max, max) where min <= 15 and max = the maximum output frame rate of the maximum YUV_420_888 output size." Collect the higher FPS of the larger YUV stream and use it with the minimum FPS rate the camera can produce to populate the ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES static metadata. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
c7bd730e1b
commit
d810227c48
1 changed files with 28 additions and 47 deletions
|
@ -886,53 +886,6 @@ int CameraCapabilities::initializeStaticMetadata()
|
||||||
staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
|
staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
|
||||||
aeAvailableModes);
|
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 = {
|
std::vector<int32_t> aeCompensationRange = {
|
||||||
0, 0,
|
0, 0,
|
||||||
};
|
};
|
||||||
|
@ -1278,8 +1231,12 @@ int CameraCapabilities::initializeStaticMetadata()
|
||||||
|
|
||||||
std::vector<uint32_t> availableStreamConfigurations;
|
std::vector<uint32_t> availableStreamConfigurations;
|
||||||
std::vector<int64_t> minFrameDurations;
|
std::vector<int64_t> minFrameDurations;
|
||||||
|
int maxYUVFps = 0;
|
||||||
|
Size maxYUVSize;
|
||||||
|
|
||||||
availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
|
availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
|
||||||
minFrameDurations.reserve(streamConfigurations_.size() * 4);
|
minFrameDurations.reserve(streamConfigurations_.size() * 4);
|
||||||
|
|
||||||
for (const auto &entry : streamConfigurations_) {
|
for (const auto &entry : streamConfigurations_) {
|
||||||
/*
|
/*
|
||||||
* Filter out YUV streams not capable of running at 30 FPS.
|
* 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)
|
if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB && fps < 30)
|
||||||
continue;
|
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. */
|
/* Stream configuration map. */
|
||||||
availableStreamConfigurations.push_back(entry.androidFormat);
|
availableStreamConfigurations.push_back(entry.androidFormat);
|
||||||
availableStreamConfigurations.push_back(entry.resolution.width);
|
availableStreamConfigurations.push_back(entry.resolution.width);
|
||||||
|
@ -1323,6 +1290,20 @@ int CameraCapabilities::initializeStaticMetadata()
|
||||||
staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
|
staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
|
||||||
minFrameDurations);
|
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;
|
std::vector<int64_t> availableStallDurations;
|
||||||
for (const auto &entry : streamConfigurations_) {
|
for (const auto &entry : streamConfigurations_) {
|
||||||
if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
|
if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue