[PATCH v3.1] fixup! libcamera: converter_v4l2_m2m: Improve crop bounds support
Jacopo Mondi
jacopo.mondi at ideasonboard.com
Fri Dec 13 12:24:32 CET 2024
Hi Stefan
On Fri, Dec 13, 2024 at 10:26:05AM +0100, Stefan Klug wrote:
> Changes semantics of inputCropBounds to return null bounds if an
> unconfigured stream is provided. Return the device crop bounds if a
> nullptr is provided.
>
> Signed-off-by: Stefan Klug <stefan.klug at ideasonboard.com>
> ---
>
> Hi Jacopo,
>
> I forgot to handle your comment in the v3. Sorry for that. This is my
> proposal. It is somewhere in the middle of your suggestions, but I think
> it makes the intent clearer.
I like isConfigured() as it allows the pipeline to behave accordingly
to the converter configuration.
I like less the three-way behaviour of
Converter::inputCropBounds(Stream *)
1) If called with a configured Stream it returns the input crop bounds
of that stream
2) If called with a nullptr it returns the default crop bounds
3) When called with a Stream it returns an empty Rectangle
To make it less confusing, instead of
virtual std::pair<Rectangle, Rectangle> inputCropBounds(
const Stream *stream = nullptr) = 0;
I would
virtual std::pair<Rectangle, Rectangle> inputCropBounds() = 0;
virtual std::pair<Rectangle, Rectangle> inputCropBounds(const Stream *stream) = 0;
or maybe even just
virtual std::pair<Rectangle, Rectangle> cropBounds() = 0;
So that pipeline handlers could
std::pair<Rectangle, Rectangle> cropLimits;
if (dewarper_->isConfigured(&data->mainPathStream_))
cropLimits = dewarper_->inputCropBounds(&data->mainPathStream_);
else
cropLimits = dewarper_->cropBounds();
Which I find clearer as an API than
const Stream *stream = nullptr;
if (dewarper_->isConfigured(&data->mainPathStream_))
stream = &data->mainPathStream_;
std::pair<Rectangle, Rectangle> cropLimits =
dewarper_->inputCropBounds(stream);
Up to you
>
> I would like to keep the getCropBound() a static function as we
> discussed before.
>
> The commit message will also be updated for v4.
>
> Is this change ok for you?
>
> Best regards,
> Stefan
>
> include/libcamera/internal/converter.h | 4 +++-
> .../internal/converter/converter_v4l2_m2m.h | 1 +
> src/libcamera/converter.cpp | 12 +++++++++++-
> .../converter/converter_v4l2_m2m.cpp | 19 ++++++++++++++++---
> src/libcamera/pipeline/rkisp1/rkisp1.cpp | 6 +++++-
> 5 files changed, 36 insertions(+), 6 deletions(-)
>
> diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h
> index 9213ae5b9c33..465b0b0596d9 100644
> --- a/include/libcamera/internal/converter.h
> +++ b/include/libcamera/internal/converter.h
> @@ -73,6 +73,7 @@ public:
>
> virtual int configure(const StreamConfiguration &inputCfg,
> const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs) = 0;
> + virtual bool isConfigured(const Stream *stream) const = 0;
> virtual int exportBuffers(const Stream *stream, unsigned int count,
> std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;
>
> @@ -83,7 +84,8 @@ public:
> const std::map<const Stream *, FrameBuffer *> &outputs) = 0;
>
> virtual int setInputCrop(const Stream *stream, Rectangle *rect) = 0;
> - virtual std::pair<Rectangle, Rectangle> inputCropBounds(const Stream *stream) = 0;
> + virtual std::pair<Rectangle, Rectangle> inputCropBounds(
> + const Stream *stream = nullptr) = 0;
>
> Signal<FrameBuffer *> inputBufferReady;
> Signal<FrameBuffer *> outputBufferReady;
> diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h
> index 89bd2878b190..175f0e1109a6 100644
> --- a/include/libcamera/internal/converter/converter_v4l2_m2m.h
> +++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h
> @@ -54,6 +54,7 @@ public:
>
> int configure(const StreamConfiguration &inputCfg,
> const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfg);
> + bool isConfigured(const Stream *stream) const override;
> int exportBuffers(const Stream *stream, unsigned int count,
> std::vector<std::unique_ptr<FrameBuffer>> *buffers);
>
> diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp
> index c3da162b7de7..74cea46cc709 100644
> --- a/src/libcamera/converter.cpp
> +++ b/src/libcamera/converter.cpp
> @@ -169,6 +169,13 @@ Converter::~Converter()
> * \return 0 on success or a negative error code otherwise
> */
>
> +/**
> + * \fn Converter::isConfigured()
> + * \brief Check if a given stream is configured
> + * \param[in] stream The output stream
> + * \return True if the \a stream is configured or false otherwise
> + */
> +
> /**
> * \fn Converter::exportBuffers()
> * \brief Export buffers from the converter device
> @@ -238,9 +245,12 @@ Converter::~Converter()
> * this function should be called after the \a stream has been configured using
> * configure().
> *
> - * When called with an invalid \a stream, the function returns the default crop
> + * When called with nullptr \a stream this function returns the default crop
> * bounds of the converter.
> *
> + * When called with an invalid \a stream, this function returns a pair of null
> + * rectangles
> + *
> * \return A pair containing the minimum and maximum crop bound in that order
> */
>
> diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp
> index 6857472b29f2..4df253749feb 100644
> --- a/src/libcamera/converter/converter_v4l2_m2m.cpp
> +++ b/src/libcamera/converter/converter_v4l2_m2m.cpp
> @@ -559,6 +559,14 @@ int V4L2M2MConverter::configure(const StreamConfiguration &inputCfg,
> return 0;
> }
>
> +/**
> + * \copydoc libcamera::Converter::isConfigured
> + */
> +bool V4L2M2MConverter::isConfigured(const Stream *stream) const
> +{
> + return streams_.find(stream) != streams_.end();
> +}
> +
> /**
> * \copydoc libcamera::Converter::exportBuffers
> */
> @@ -595,11 +603,16 @@ int V4L2M2MConverter::setInputCrop(const Stream *stream, Rectangle *rect)
> std::pair<Rectangle, Rectangle>
> V4L2M2MConverter::inputCropBounds(const Stream *stream)
> {
> + if (stream == nullptr)
> + return inputCropBounds_;
> +
> auto iter = streams_.find(stream);
> - if (iter != streams_.end())
> - return iter->second->inputCropBounds();
> + if (iter == streams_.end()) {
> + LOG(Converter, Error) << "Invalid output stream";
> + return {};
> + }
>
> - return inputCropBounds_;
> + return iter->second->inputCropBounds();
> }
>
> /**
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> index 4dcc5a4fa6a1..ad162164df1a 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> @@ -1281,8 +1281,12 @@ int PipelineHandlerRkISP1::updateControls(RkISP1CameraData *data)
> ControlInfoMap::Map controls;
>
> if (dewarper_) {
> + const Stream *stream = nullptr;
> + if (dewarper_->isConfigured(&data->mainPathStream_))
> + stream = &data->mainPathStream_;
> +
> std::pair<Rectangle, Rectangle> cropLimits =
> - dewarper_->inputCropBounds(&data->mainPathStream_);
> + dewarper_->inputCropBounds(stream);
>
> /*
> * ScalerCrop is specified to be in Sensor coordinates.
> --
> 2.43.0
>
More information about the libcamera-devel
mailing list