Message ID | 20210827120757.110615-1-jacopo@jmondi.org |
---|---|
Headers | show |
Series |
|
Related | show |
Hi Jacopo, On Fri, Aug 27, 2021 at 02:07:46PM +0200, Jacopo Mondi wrote: > Now that building the list of supported stream configuration requires > applying a configuration to the Camera, re-initialize the camera > controls by applying a configuration generated for the Viewfinder stream > role before building the list of static metadata. > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Looks good, but I have a question. > --- > src/android/camera_capabilities.cpp | 18 +++++++++++++++--- > 1 file changed, 15 insertions(+), 3 deletions(-) > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > index fdda90379ce2..723a4fd5a880 100644 > --- a/src/android/camera_capabilities.cpp > +++ b/src/android/camera_capabilities.cpp > @@ -394,11 +394,14 @@ int CameraCapabilities::initialize(std::shared_ptr<libcamera::Camera> camera, > } > > ret = initializeStreamConfigurations(); > - camera_->release(); > - if (ret) > + if (ret) { > + camera_->release(); > return ret; > + } > > - return initializeStaticMetadata(); > + ret = initializeStaticMetadata(); > + camera_->release(); > + return ret; > } > > std::vector<Size> > @@ -682,6 +685,15 @@ int CameraCapabilities::initializeStaticMetadata() > return -EINVAL; > } > > + std::unique_ptr<CameraConfiguration> cameraConfig = > + camera_->generateConfiguration({ StreamRole::Viewfinder }); From what I see, initializeStreamConfigurations() generates a configuration for the StillCapture role. Is it fine that this uses a different role? (Or was the other one changed to Viewfinder where I wasn't paying attention?) Paul > + int ret = camera_->configure(cameraConfig.get()); > + if (ret) { > + LOG(HAL, Error) << "Failed to initialize the camera state"; > + staticMetadata_.reset(); > + return ret; > + } > + > const ControlInfoMap &controlsInfo = camera_->controls(); > const ControlList &properties = camera_->properties(); > > -- > 2.32.0 >
Hi Jacopo, On Fri, Aug 27, 2021 at 02:07:47PM +0200, Jacopo Mondi wrote: > As we now collect the per-stream frame durations at > initializeStreamConfigurations() times, the Camera is now guaranteed to > support the controls::FrameDurationLimits control. > > Remove the check for its presence when populating the > ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES static metadata. > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> > --- > src/android/camera_capabilities.cpp | 83 ++++++++++++++--------------- > 1 file changed, 41 insertions(+), 42 deletions(-) > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > index 723a4fd5a880..c45d74189aaa 100644 > --- a/src/android/camera_capabilities.cpp > +++ b/src/android/camera_capabilities.cpp > @@ -858,55 +858,54 @@ int CameraCapabilities::initializeStaticMetadata() > staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES, > aeAvailableModes); > > + /* Initialize the AE frame duration limits. */ > int64_t minFrameDurationNsec = -1; > int64_t maxFrameDurationNsec = -1; > const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurationLimits); > - if (frameDurationsInfo != controlsInfo.end()) { > - minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000; > - maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000; > + minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000; > + maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000; Why not just initialize these directly? Otherwise, looks good. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> > > - /* > - * 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; > + /* > + * 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); > + /* > + * 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; > + /* > + * 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); > - } > + /* > + * 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, > -- > 2.32.0 >
Hi Jacopo, On Fri, Aug 27, 2021 at 02:07:50PM +0200, Jacopo Mondi wrote: > While building the list of supported stream configurations also collet s/collet/collect > the absolute max frame durations to be used to populate the sensor > maximum frame duration. > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Looks good. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> > --- > src/android/camera_capabilities.cpp | 9 ++++++--- > src/android/camera_capabilities.h | 1 + > 2 files changed, 7 insertions(+), 3 deletions(-) > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > index 23a9a3fbec50..388552963c47 100644 > --- a/src/android/camera_capabilities.cpp > +++ b/src/android/camera_capabilities.cpp > @@ -385,6 +385,7 @@ int CameraCapabilities::initialize(std::shared_ptr<libcamera::Camera> camera, > orientation_ = orientation; > facing_ = facing; > rawStreamAvailable_ = false; > + maxFrameDuration_ = 0; > > /* Acquire the camera and initialize available stream configurations. */ > int ret = camera_->acquire(); > @@ -659,6 +660,9 @@ int CameraCapabilities::initializeStreamConfigurations() > }); > maxJpegSize = std::max(maxJpegSize, res); > } > + > + maxFrameDuration_ = std::max(maxFrameDuration_, > + maxFrameDuration); > } > > /* > @@ -1132,9 +1136,8 @@ int CameraCapabilities::initializeStaticMetadata() > staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, > timestampSource); > > - if (maxFrameDurationNsec > 0) > - staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, > - maxFrameDurationNsec); > + staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, > + maxFrameDuration_); > > /* Statistics static metadata. */ > uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; > diff --git a/src/android/camera_capabilities.h b/src/android/camera_capabilities.h > index 6e55ddab445e..2cf97ae80095 100644 > --- a/src/android/camera_capabilities.h > +++ b/src/android/camera_capabilities.h > @@ -71,6 +71,7 @@ private: > int facing_; > int orientation_; > bool rawStreamAvailable_; > + int64_t maxFrameDuration_; > camera_metadata_enum_android_info_supported_hardware_level hwLevel_; > std::set<camera_metadata_enum_android_request_available_capabilities> capabilities_; > > -- > 2.32.0 >
Hi Paul, On Tue, Aug 31, 2021 at 11:21:02AM +0900, Paul Elder wrote: > Hi Jacopo, > > On Fri, Aug 27, 2021 at 02:07:47PM +0200, Jacopo Mondi wrote: > > As we now collect the per-stream frame durations at > > initializeStreamConfigurations() times, the Camera is now guaranteed to > > support the controls::FrameDurationLimits control. > > > > Remove the check for its presence when populating the > > ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES static metadata. > > > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> > > --- > > src/android/camera_capabilities.cpp | 83 ++++++++++++++--------------- > > 1 file changed, 41 insertions(+), 42 deletions(-) > > > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > > index 723a4fd5a880..c45d74189aaa 100644 > > --- a/src/android/camera_capabilities.cpp > > +++ b/src/android/camera_capabilities.cpp > > @@ -858,55 +858,54 @@ int CameraCapabilities::initializeStaticMetadata() > > staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES, > > aeAvailableModes); > > > > + /* Initialize the AE frame duration limits. */ > > int64_t minFrameDurationNsec = -1; > > int64_t maxFrameDurationNsec = -1; > > const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurationLimits); > > - if (frameDurationsInfo != controlsInfo.end()) { > > - minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000; > > - maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000; > > + minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000; > > + maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000; > > Why not just initialize these directly? You're right, I'll do so! Thanks j > > > Otherwise, looks good. > > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> > > > > > - /* > > - * 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; > > + /* > > + * 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); > > + /* > > + * 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; > > + /* > > + * 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); > > - } > > + /* > > + * 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, > > -- > > 2.32.0 > >
Hi Paul, On Tue, Aug 31, 2021 at 11:17:07AM +0900, Paul Elder wrote: > Hi Jacopo, > > On Fri, Aug 27, 2021 at 02:07:46PM +0200, Jacopo Mondi wrote: > > Now that building the list of supported stream configuration requires > > applying a configuration to the Camera, re-initialize the camera > > controls by applying a configuration generated for the Viewfinder stream > > role before building the list of static metadata. > > > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> > > Looks good, but I have a question. > > > --- > > src/android/camera_capabilities.cpp | 18 +++++++++++++++--- > > 1 file changed, 15 insertions(+), 3 deletions(-) > > > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > > index fdda90379ce2..723a4fd5a880 100644 > > --- a/src/android/camera_capabilities.cpp > > +++ b/src/android/camera_capabilities.cpp > > @@ -394,11 +394,14 @@ int CameraCapabilities::initialize(std::shared_ptr<libcamera::Camera> camera, > > } > > > > ret = initializeStreamConfigurations(); > > - camera_->release(); > > - if (ret) > > + if (ret) { > > + camera_->release(); > > return ret; > > + } > > > > - return initializeStaticMetadata(); > > + ret = initializeStaticMetadata(); > > + camera_->release(); > > + return ret; > > } > > > > std::vector<Size> > > @@ -682,6 +685,15 @@ int CameraCapabilities::initializeStaticMetadata() > > return -EINVAL; > > } > > > > + std::unique_ptr<CameraConfiguration> cameraConfig = > > + camera_->generateConfiguration({ StreamRole::Viewfinder }); > > From what I see, initializeStreamConfigurations() generates a > configuration for the StillCapture role. Is it fine that this uses a It does so only to retrieve the maximum resolution. A todo note reminds us that we should get that from a camera property * Get the maximum output resolutions * \todo Get this from the camera properties once defined */ std::unique_ptr<CameraConfiguration> cameraConfig = camera_->generateConfiguration({ StillCapture }); > different role? (Or was the other one changed to Viewfinder where I > wasn't paying attention?) Well, the choice of the Viewfinder role is pretty arbitrary, but we have to define a 'mode' the camera should be set to when initializing the static metadata. We don't have the luxury of assuming much from the underlying camera, and we have to construct the static metadata from the camera properties (static) and the camera controls (change depending on the configuration). Before this series the Camera::controls where static as well, so the Camera didn't get configured at all during the static metadata initialization, and we relied on the PH-initialized ControlInfoMap. As we now need to apply a Configuration to the Camera to collect per-configuration control limits, we need to re-initialize them to a known default before inspecting them. I considered Viewfinder as a good default, but I'm open to other proposals. > > > Paul > > > + int ret = camera_->configure(cameraConfig.get()); > > + if (ret) { > > + LOG(HAL, Error) << "Failed to initialize the camera state"; > > + staticMetadata_.reset(); > > + return ret; > > + } > > + > > const ControlInfoMap &controlsInfo = camera_->controls(); > > const ControlList &properties = camera_->properties(); > > > > -- > > 2.32.0 > >
Hi Jacopo, On Fri, Aug 27, 2021 at 02:07:53PM +0200, Jacopo Mondi wrote: > The ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS and > ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS static metadata are > populated by looping on the streamConfigurations_ vector. > > Unify them in a single loop to avoid repeating it. > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> > --- > src/android/camera_capabilities.cpp | 23 ++++++++++------------- > 1 file changed, 10 insertions(+), 13 deletions(-) > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > index 484242d0ad81..8bde06e824ef 100644 > --- a/src/android/camera_capabilities.cpp > +++ b/src/android/camera_capabilities.cpp > @@ -1255,7 +1255,9 @@ int CameraCapabilities::initializeStaticMetadata() > maxZoom); > > std::vector<uint32_t> availableStreamConfigurations; > + std::vector<int64_t> minFrameDurations; > 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. > @@ -1272,12 +1274,19 @@ int CameraCapabilities::initializeStaticMetadata() > if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB && fps < 30) > continue; > > + /* Stream configuration map. */ > availableStreamConfigurations.push_back(entry.androidFormat); > availableStreamConfigurations.push_back(entry.resolution.width); > availableStreamConfigurations.push_back(entry.resolution.height); > availableStreamConfigurations.push_back( > ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT); > > + /* Per-stream durations. */ > + minFrameDurations.push_back(entry.androidFormat); > + minFrameDurations.push_back(entry.resolution.width); > + minFrameDurations.push_back(entry.resolution.height); > + minFrameDurations.push_back(entry.minFrameDurationNsec); > + > LOG(HAL, Debug) > << "Output Stream:" << utils::hex(entry.androidFormat) > << "(" << entry.resolution.width << "x" > @@ -1285,22 +1294,10 @@ int CameraCapabilities::initializeStaticMetadata() > << entry.minFrameDurationNsec << "]" > << "@" << fps; > } > + > staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, > availableStreamConfigurations); > > - std::vector<int64_t> minFrameDurations; > - minFrameDurations.reserve(streamConfigurations_.size() * 4); > - for (const auto &entry : streamConfigurations_) { > - unsigned int fps = static_cast<unsigned int> > - (floor(1e9 / entry.minFrameDurationNsec + 0.05f)); > - if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB && fps < 30) > - continue; > - > - minFrameDurations.push_back(entry.androidFormat); > - minFrameDurations.push_back(entry.resolution.width); > - minFrameDurations.push_back(entry.resolution.height); > - minFrameDurations.push_back(entry.minFrameDurationNsec); > - } > staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, > minFrameDurations); > > -- > 2.32.0 >
Hi Jacopo, On 8/31/21 3:27 PM, Jacopo Mondi wrote: > Hi Paul, > > On Tue, Aug 31, 2021 at 11:17:07AM +0900, Paul Elder wrote: >> Hi Jacopo, >> >> On Fri, Aug 27, 2021 at 02:07:46PM +0200, Jacopo Mondi wrote: >>> Now that building the list of supported stream configuration requires >>> applying a configuration to the Camera, re-initialize the camera >>> controls by applying a configuration generated for the Viewfinder stream >>> role before building the list of static metadata. >>> >>> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> >> Looks good, but I have a question. >> >>> --- >>> src/android/camera_capabilities.cpp | 18 +++++++++++++++--- >>> 1 file changed, 15 insertions(+), 3 deletions(-) >>> >>> diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp >>> index fdda90379ce2..723a4fd5a880 100644 >>> --- a/src/android/camera_capabilities.cpp >>> +++ b/src/android/camera_capabilities.cpp >>> @@ -394,11 +394,14 @@ int CameraCapabilities::initialize(std::shared_ptr<libcamera::Camera> camera, >>> } >>> >>> ret = initializeStreamConfigurations(); >>> - camera_->release(); >>> - if (ret) >>> + if (ret) { >>> + camera_->release(); >>> return ret; >>> + } >>> >>> - return initializeStaticMetadata(); >>> + ret = initializeStaticMetadata(); >>> + camera_->release(); >>> + return ret; >>> } >>> >>> std::vector<Size> >>> @@ -682,6 +685,15 @@ int CameraCapabilities::initializeStaticMetadata() >>> return -EINVAL; >>> } >>> >>> + std::unique_ptr<CameraConfiguration> cameraConfig = >>> + camera_->generateConfiguration({ StreamRole::Viewfinder }); >> From what I see, initializeStreamConfigurations() generates a >> configuration for the StillCapture role. Is it fine that this uses a > It does so only to retrieve the maximum resolution. > A todo note reminds us that we should get that from a camera property > > * Get the maximum output resolutions > * \todo Get this from the camera properties once defined > */ > std::unique_ptr<CameraConfiguration> cameraConfig = > camera_->generateConfiguration({ StillCapture }); > >> different role? (Or was the other one changed to Viewfinder where I >> wasn't paying attention?) > Well, the choice of the Viewfinder role is pretty arbitrary, but we > have to define a 'mode' the camera should be set to when initializing > the static metadata. We don't have the luxury of assuming much from > the underlying camera, and we have to construct the static metadata > from the camera properties (static) and the camera controls (change > depending on the configuration). > > Before this series the Camera::controls where static as well, so the > Camera didn't get configured at all during the static metadata > initialization, and we relied on the PH-initialized ControlInfoMap. > > As we now need to apply a Configuration to the Camera to collect > per-configuration control limits, we need to re-initialize them to a > known default before inspecting them. > > I considered Viewfinder as a good default, but I'm open to other > proposals. I agree with the reasoning but also feels to me that there should be comment placed in the file to address this. Up to you. Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> > >> >> Paul >> >>> + int ret = camera_->configure(cameraConfig.get()); >>> + if (ret) { >>> + LOG(HAL, Error) << "Failed to initialize the camera state"; >>> + staticMetadata_.reset(); >>> + return ret; >>> + } >>> + >>> const ControlInfoMap &controlsInfo = camera_->controls(); >>> const ControlList &properties = camera_->properties(); >>> >>> -- >>> 2.32.0 >>>
Hi Jacopo Thanks for the patch. On 8/27/21 5:37 PM, Jacopo Mondi wrote: > As we now collect the per-stream frame durations at > initializeStreamConfigurations() times, the Camera is now guaranteed to > support the controls::FrameDurationLimits control. > > Remove the check for its presence when populating the > ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES static metadata. > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> > --- > src/android/camera_capabilities.cpp | 83 ++++++++++++++--------------- > 1 file changed, 41 insertions(+), 42 deletions(-) > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > index 723a4fd5a880..c45d74189aaa 100644 > --- a/src/android/camera_capabilities.cpp > +++ b/src/android/camera_capabilities.cpp > @@ -858,55 +858,54 @@ int CameraCapabilities::initializeStaticMetadata() > staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES, > aeAvailableModes); > > + /* Initialize the AE frame duration limits. */ > int64_t minFrameDurationNsec = -1; > int64_t maxFrameDurationNsec = -1; > const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurationLimits); > - if (frameDurationsInfo != controlsInfo.end()) { > - minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000; > - maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000; > + minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000; > + 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; > + /* > + * 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); > + /* > + * 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; > + /* > + * 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); > - } > + /* > + * 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,
Hi Jacopo, Thank you for the patch On 8/27/21 5:37 PM, Jacopo Mondi wrote: > While building the list of supported stream configurations also collet > the absolute max frame durations to be used to populate the sensor > maximum frame duration. > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> > --- > src/android/camera_capabilities.cpp | 9 ++++++--- > src/android/camera_capabilities.h | 1 + > 2 files changed, 7 insertions(+), 3 deletions(-) > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > index 23a9a3fbec50..388552963c47 100644 > --- a/src/android/camera_capabilities.cpp > +++ b/src/android/camera_capabilities.cpp > @@ -385,6 +385,7 @@ int CameraCapabilities::initialize(std::shared_ptr<libcamera::Camera> camera, > orientation_ = orientation; > facing_ = facing; > rawStreamAvailable_ = false; > + maxFrameDuration_ = 0; > > /* Acquire the camera and initialize available stream configurations. */ > int ret = camera_->acquire(); > @@ -659,6 +660,9 @@ int CameraCapabilities::initializeStreamConfigurations() > }); > maxJpegSize = std::max(maxJpegSize, res); > } > + > + maxFrameDuration_ = std::max(maxFrameDuration_, > + maxFrameDuration); > } > > /* > @@ -1132,9 +1136,8 @@ int CameraCapabilities::initializeStaticMetadata() > staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, > timestampSource); > > - if (maxFrameDurationNsec > 0) > - staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, > - maxFrameDurationNsec); > + staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, > + maxFrameDuration_); > > /* Statistics static metadata. */ > uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; > diff --git a/src/android/camera_capabilities.h b/src/android/camera_capabilities.h > index 6e55ddab445e..2cf97ae80095 100644 > --- a/src/android/camera_capabilities.h > +++ b/src/android/camera_capabilities.h > @@ -71,6 +71,7 @@ private: > int facing_; > int orientation_; > bool rawStreamAvailable_; > + int64_t maxFrameDuration_; > camera_metadata_enum_android_info_supported_hardware_level hwLevel_; > std::set<camera_metadata_enum_android_request_available_capabilities> capabilities_; >
Hi Jacopo, On Tue, Aug 31, 2021 at 11:57:50AM +0200, Jacopo Mondi wrote: > Hi Paul, > > On Tue, Aug 31, 2021 at 11:17:07AM +0900, Paul Elder wrote: > > Hi Jacopo, > > > > On Fri, Aug 27, 2021 at 02:07:46PM +0200, Jacopo Mondi wrote: > > > Now that building the list of supported stream configuration requires > > > applying a configuration to the Camera, re-initialize the camera > > > controls by applying a configuration generated for the Viewfinder stream > > > role before building the list of static metadata. > > > > > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> > > > > Looks good, but I have a question. > > > > > --- > > > src/android/camera_capabilities.cpp | 18 +++++++++++++++--- > > > 1 file changed, 15 insertions(+), 3 deletions(-) > > > > > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > > > index fdda90379ce2..723a4fd5a880 100644 > > > --- a/src/android/camera_capabilities.cpp > > > +++ b/src/android/camera_capabilities.cpp > > > @@ -394,11 +394,14 @@ int CameraCapabilities::initialize(std::shared_ptr<libcamera::Camera> camera, > > > } > > > > > > ret = initializeStreamConfigurations(); > > > - camera_->release(); > > > - if (ret) > > > + if (ret) { > > > + camera_->release(); > > > return ret; > > > + } > > > > > > - return initializeStaticMetadata(); > > > + ret = initializeStaticMetadata(); > > > + camera_->release(); > > > + return ret; > > > } > > > > > > std::vector<Size> > > > @@ -682,6 +685,15 @@ int CameraCapabilities::initializeStaticMetadata() > > > return -EINVAL; > > > } > > > > > > + std::unique_ptr<CameraConfiguration> cameraConfig = > > > + camera_->generateConfiguration({ StreamRole::Viewfinder }); > > > > From what I see, initializeStreamConfigurations() generates a > > configuration for the StillCapture role. Is it fine that this uses a > > It does so only to retrieve the maximum resolution. > A todo note reminds us that we should get that from a camera property > > * Get the maximum output resolutions > * \todo Get this from the camera properties once defined > */ > std::unique_ptr<CameraConfiguration> cameraConfig = > camera_->generateConfiguration({ StillCapture }); > > > different role? (Or was the other one changed to Viewfinder where I > > wasn't paying attention?) > > Well, the choice of the Viewfinder role is pretty arbitrary, but we > have to define a 'mode' the camera should be set to when initializing > the static metadata. We don't have the luxury of assuming much from > the underlying camera, and we have to construct the static metadata > from the camera properties (static) and the camera controls (change > depending on the configuration). > > Before this series the Camera::controls where static as well, so the > Camera didn't get configured at all during the static metadata > initialization, and we relied on the PH-initialized ControlInfoMap. > > As we now need to apply a Configuration to the Camera to collect > per-configuration control limits, we need to re-initialize them to a > known default before inspecting them. > > I considered Viewfinder as a good default, but I'm open to other > proposals. Ah, okay, I see. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> > > > > > > + int ret = camera_->configure(cameraConfig.get()); > > > + if (ret) { > > > + LOG(HAL, Error) << "Failed to initialize the camera state"; > > > + staticMetadata_.reset(); > > > + return ret; > > > + } > > > + > > > const ControlInfoMap &controlsInfo = camera_->controls(); > > > const ControlList &properties = camera_->properties(); > > > > > > -- > > > 2.32.0 > > >
Hi Jacopo, On 8/27/21 5:37 PM, Jacopo Mondi wrote: > The ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS and > ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS static metadata are > populated by looping on the streamConfigurations_ vector. > > Unify them in a single loop to avoid repeating it. > > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> > --- > src/android/camera_capabilities.cpp | 23 ++++++++++------------- > 1 file changed, 10 insertions(+), 13 deletions(-) > > diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp > index 484242d0ad81..8bde06e824ef 100644 > --- a/src/android/camera_capabilities.cpp > +++ b/src/android/camera_capabilities.cpp > @@ -1255,7 +1255,9 @@ int CameraCapabilities::initializeStaticMetadata() > maxZoom); > > std::vector<uint32_t> availableStreamConfigurations; > + std::vector<int64_t> minFrameDurations; > 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. > @@ -1272,12 +1274,19 @@ int CameraCapabilities::initializeStaticMetadata() > if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB && fps < 30) > continue; > > + /* Stream configuration map. */ > availableStreamConfigurations.push_back(entry.androidFormat); > availableStreamConfigurations.push_back(entry.resolution.width); > availableStreamConfigurations.push_back(entry.resolution.height); > availableStreamConfigurations.push_back( > ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT); > > + /* Per-stream durations. */ > + minFrameDurations.push_back(entry.androidFormat); > + minFrameDurations.push_back(entry.resolution.width); > + minFrameDurations.push_back(entry.resolution.height); > + minFrameDurations.push_back(entry.minFrameDurationNsec); > + > LOG(HAL, Debug) > << "Output Stream:" << utils::hex(entry.androidFormat) > << "(" << entry.resolution.width << "x" > @@ -1285,22 +1294,10 @@ int CameraCapabilities::initializeStaticMetadata() > << entry.minFrameDurationNsec << "]" > << "@" << fps; > } > + > staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, > availableStreamConfigurations); > > - std::vector<int64_t> minFrameDurations; > - minFrameDurations.reserve(streamConfigurations_.size() * 4); > - for (const auto &entry : streamConfigurations_) { > - unsigned int fps = static_cast<unsigned int> > - (floor(1e9 / entry.minFrameDurationNsec + 0.05f)); > - if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB && fps < 30) > - continue; > - > - minFrameDurations.push_back(entry.androidFormat); > - minFrameDurations.push_back(entry.resolution.width); > - minFrameDurations.push_back(entry.resolution.height); > - minFrameDurations.push_back(entry.minFrameDurationNsec); > - } > staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, > minFrameDurations); >