[RFC] Per-stream controls
Naushir Patuck
naush at raspberrypi.com
Wed Sep 11 10:01:52 CEST 2024
Hi,
This RFC introduces the idea of libcamera controls that can be applied
to one or more specific streams that have been configured via
camera::configure(). One typical use case would be for applying
different ScalerCrop controls for individual streams.
To start with, each StreamConfiguration created from
camera::generateConfiguration() will have a unique id field
(StreamConfiguration::id_) populated by the pipeline handler. This id
will be used to associate a control with a specific stream.
Next, for setting controls ControlValue::set(const T &value) has a new
overload which accepts a vector of controls and matching vector of
stream ids:
template<typename T>
struct StreamValue {
unsigned int streamId;
T value;
};
template<typename T>
void ControlValue::set(const std::vector<StreamValue<T>> &values);
The ControlValue class will need to be updated appropriately to store
the array of values from the above, including ControlValue::reserve().
The existing ControlValue::set(const T &value) implies this control is
set for all streams, exactly the same behavior as we have today.
Similarly, ControlList::set() will have a new prototype:
template<typename T, typename V>
void set(const Control<T> &ctrl, const std::vector<StreamValue <V>> &values)
and ditto for the other set() variant:
template<typename T, typename V, size_t Size>
void set(const Control<Span<T, Size>> &ctrl, const
std::initializer_list<StreamValue<V>> &values)
There should probably be a helper to test if the ControlValue has been
set with one of the new prototypes above:
bool ControlValue::isStreamValue();
Next, on the getting controls T ControlValue::get() is updated with a
new prototype:
template<typename T>
T ControlValue::get(unsigned int streamId = 0)
[maybe this should return std::optional<T> in case streamId is not valid?]
or we could also have
std::StreamValue<T> ControlValue::getSreamValues() that the caller
would have to use if ControlValue::isStreamValue() == true.
The advantage of liking stream ids into the ControlValue directly is
that it propagates nicely into ControlInfo, and we can get
min()/max()/def() values per-stream if the pipeline handler were to
report in such a way.
There are still some questions that I don't have any answers to:
- Should we tag specific controls as having a per-stream value in the
yaml file? The ControlInfo should hopefully inform the application if
a control is per-stream, but do we need to be more explicit?
- Error handling, what if the user sets a control on an invalid
stream. How is the error propagated?
There's still quite a bit of implementation detail that is missing
from this proposal, but I think it's a good start for some
discussions. Let me know your thoughts.
Regards,
Naush
More information about the libcamera-devel
mailing list