[libcamera-devel] [PATCH] Remove limitation that camera and display must match

Eric Curtin ecurtin at redhat.com
Fri Feb 4 12:43:32 CET 2022


On Fri, 4 Feb 2022 at 11:13, Eric Curtin <ecurtin at redhat.com> wrote:
>
> There is a limitation that requires input and output
> to be pixel for pixel identical in terms of height
> and width. Remove this limitation to enable more
> hardware that doesn't match. Centralize the image.
>
> Signed-off-by: Eric Curtin <ecurtin at redhat.com>
> ---
>  src/cam/kms_sink.cpp | 27 +++++++++------------------
>  src/cam/kms_sink.h   |  2 ++
>  2 files changed, 11 insertions(+), 18 deletions(-)
>
> diff --git a/src/cam/kms_sink.cpp b/src/cam/kms_sink.cpp
> index 973cd370..159b9355 100644
> --- a/src/cam/kms_sink.cpp
> +++ b/src/cam/kms_sink.cpp
> @@ -113,24 +113,15 @@ int KMSSink::configure(const libcamera::CameraConfiguration &config)
>         const libcamera::StreamConfiguration &cfg = config.at(0);
>
>         const std::vector<DRM::Mode> &modes = connector_->modes();
> -       const auto iter = std::find_if(modes.begin(), modes.end(),
> -                                      [&](const DRM::Mode &mode) {
> -                                              return mode.hdisplay == cfg.size.width &&
> -                                                     mode.vdisplay == cfg.size.height;
> -                                      });
> -       if (iter == modes.end()) {
> -               std::cerr
> -                       << "No mode matching " << cfg.size.toString()
> -                       << std::endl;
> -               return -EINVAL;
> -       }
>
>         int ret = configurePipeline(cfg.pixelFormat);
>         if (ret < 0)
>                 return ret;
>
> -       mode_ = &*iter;
> +       mode_ = &modes[0];
>         size_ = cfg.size;
> +       x_ = (mode_->hdisplay - size_.width) / 2;
> +       y_ = (mode_->vdisplay - size_.height) / 2;
>         stride_ = cfg.stride;
>
>         return 0;
> @@ -297,12 +288,12 @@ bool KMSSink::processRequest(libcamera::Request *camRequest)
>                 drmRequest->addProperty(plane_, "CRTC_ID", crtc_->id());
>                 drmRequest->addProperty(plane_, "SRC_X", 0 << 16);
>                 drmRequest->addProperty(plane_, "SRC_Y", 0 << 16);
> -               drmRequest->addProperty(plane_, "SRC_W", mode_->hdisplay << 16);
> -               drmRequest->addProperty(plane_, "SRC_H", mode_->vdisplay << 16);
> -               drmRequest->addProperty(plane_, "CRTC_X", 0);
> -               drmRequest->addProperty(plane_, "CRTC_Y", 0);
> -               drmRequest->addProperty(plane_, "CRTC_W", mode_->hdisplay);
> -               drmRequest->addProperty(plane_, "CRTC_H", mode_->vdisplay);
> +               drmRequest->addProperty(plane_, "SRC_W", size_.width << 16);
> +               drmRequest->addProperty(plane_, "SRC_H", size_.height << 16);
> +               drmRequest->addProperty(plane_, "CRTC_X", x_);
> +               drmRequest->addProperty(plane_, "CRTC_Y", y_);
> +               drmRequest->addProperty(plane_, "CRTC_W", size_.width);
> +               drmRequest->addProperty(plane_, "CRTC_H", size_.height);
>
>                 flags |= DRM::AtomicRequest::FlagAllowModeset;
>         }
> diff --git a/src/cam/kms_sink.h b/src/cam/kms_sink.h
> index 4a0a872c..1b08e887 100644
> --- a/src/cam/kms_sink.h
> +++ b/src/cam/kms_sink.h
> @@ -61,6 +61,8 @@ private:
>         libcamera::PixelFormat format_;
>         libcamera::Size size_;
>         unsigned int stride_;
> +       unsigned int x_;  // Where to start drawing camera output
> +       unsigned int y_;  // Where to start drawing camera output
>
>         std::map<libcamera::FrameBuffer *, std::unique_ptr<DRM::FrameBuffer>> buffers_;
>
> --
> 2.34.1
>

Might require a follow on commit for the larger camera resolution on
smaller display case, if DRM allows you to write to negative pixels,
it might just work to change those unsigned ints to signed ints. Not a
scenario I come across on my hardware.



More information about the libcamera-devel mailing list