[libcamera-devel] [PATCH 1/2] libcamera: pipeline: simple: converter: Add scaling support
Niklas Söderlund
niklas.soderlund at ragnatech.se
Tue May 19 16:02:36 CEST 2020
Hi Laurent,
Thanks for your work.
On 2020-05-19 06:06:23 +0300, Laurent Pinchart wrote:
> Extend the SimpleConverter to support scaling, with reporting of the
> minimum and maximum output sizes supported for a given input size.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> src/libcamera/pipeline/simple/converter.cpp | 67 ++++++++++++++++++---
> src/libcamera/pipeline/simple/converter.h | 7 ++-
> src/libcamera/pipeline/simple/simple.cpp | 2 +-
> 3 files changed, 63 insertions(+), 13 deletions(-)
>
> diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp
> index 02443e7f78ed..e5e2f0fddb62 100644
> --- a/src/libcamera/pipeline/simple/converter.cpp
> +++ b/src/libcamera/pipeline/simple/converter.cpp
> @@ -8,10 +8,12 @@
> #include "converter.h"
>
> #include <algorithm>
> +#include <limits.h>
>
> #include <libcamera/buffer.h>
> #include <libcamera/geometry.h>
> #include <libcamera/signal.h>
> +#include <libcamera/stream.h>
>
> #include "libcamera/internal/log.h"
> #include "libcamera/internal/media_device.h"
> @@ -92,15 +94,60 @@ std::vector<PixelFormat> SimpleConverter::formats(PixelFormat input)
> return pixelFormats;
> }
>
> -int SimpleConverter::configure(PixelFormat inputFormat,
> - PixelFormat outputFormat, const Size &size)
> +SizeRange SimpleConverter::sizes(const Size &input)
> +{
> + if (!m2m_)
> + return {};
> +
> + /*
> + * Set the size on the input side (V4L2 output) of the converter to
> + * enumerate the scaling capabilities on its output (V4L2 capture).
> + */
> + V4L2DeviceFormat format;
> + format.fourcc = V4L2PixelFormat();
> + format.size = input;
> +
> + int ret = m2m_->output()->setFormat(&format);
> + if (ret < 0) {
> + LOG(SimplePipeline, Error)
> + << "Failed to set format: " << strerror(-ret);
> + return {};
> + }
> +
> + SizeRange sizes;
> +
> + format.size = { 1, 1 };
> + ret = m2m_->capture()->setFormat(&format);
> + if (ret < 0) {
> + LOG(SimplePipeline, Error)
> + << "Failed to set format: " << strerror(-ret);
> + return {};
> + }
> +
> + sizes.min = format.size;
> +
> + format.size = { UINT_MAX, UINT_MAX };
> + ret = m2m_->capture()->setFormat(&format);
> + if (ret < 0) {
> + LOG(SimplePipeline, Error)
> + << "Failed to set format: " << strerror(-ret);
> + return {};
> + }
> +
> + sizes.max = format.size;
> +
> + return sizes;
> +}
> +
> +int SimpleConverter::configure(PixelFormat inputFormat, const Size &inputSize,
> + StreamConfiguration *cfg)
> {
> V4L2DeviceFormat format;
> int ret;
>
> V4L2PixelFormat videoFormat = m2m_->output()->toV4L2PixelFormat(inputFormat);
> format.fourcc = videoFormat;
> - format.size = size;
> + format.size = inputSize;
>
> ret = m2m_->output()->setFormat(&format);
> if (ret < 0) {
> @@ -109,18 +156,16 @@ int SimpleConverter::configure(PixelFormat inputFormat,
> return ret;
> }
>
> - if (format.fourcc != videoFormat || format.size != size) {
> + if (format.fourcc != videoFormat || format.size != inputSize) {
> LOG(SimplePipeline, Error)
> << "Input format not supported";
> return -EINVAL;
> }
>
> - /*
> - * Set the pixel format on the output, the size is identical to the
> - * input as we don't support scaling.
> - */
> - videoFormat = m2m_->capture()->toV4L2PixelFormat(outputFormat);
> + /* Set the pixel format and size on the output. */
> + videoFormat = m2m_->capture()->toV4L2PixelFormat(cfg->pixelFormat);
> format.fourcc = videoFormat;
> + format.size = cfg->size;
>
> ret = m2m_->capture()->setFormat(&format);
> if (ret < 0) {
> @@ -129,12 +174,14 @@ int SimpleConverter::configure(PixelFormat inputFormat,
> return ret;
> }
>
> - if (format.fourcc != videoFormat || format.size != size) {
> + if (format.fourcc != videoFormat || format.size != cfg->size) {
> LOG(SimplePipeline, Error)
> << "Output format not supported";
> return -EINVAL;
> }
>
> + cfg->stride = format.planes[0].bpl;
This seems to be an unrelated change, but nice that it's fixed ;-)
Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> +
> return 0;
> }
>
> diff --git a/src/libcamera/pipeline/simple/converter.h b/src/libcamera/pipeline/simple/converter.h
> index a33071fa8578..1f770eb844b5 100644
> --- a/src/libcamera/pipeline/simple/converter.h
> +++ b/src/libcamera/pipeline/simple/converter.h
> @@ -20,6 +20,8 @@ namespace libcamera {
> class FrameBuffer;
> class MediaDevice;
> struct Size;
> +class SizeRange;
> +struct StreamConfiguration;
> class V4L2M2MDevice;
>
> class SimpleConverter
> @@ -32,9 +34,10 @@ public:
> void close();
>
> std::vector<PixelFormat> formats(PixelFormat input);
> + SizeRange sizes(const Size &input);
>
> - int configure(PixelFormat inputFormat, PixelFormat outputFormat,
> - const Size &size);
> + int configure(PixelFormat inputFormat, const Size &inputSize,
> + StreamConfiguration *cfg);
> int exportBuffers(unsigned int count,
> std::vector<std::unique_ptr<FrameBuffer>> *buffers);
>
> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
> index 2565190082c8..b21ad82e1a05 100644
> --- a/src/libcamera/pipeline/simple/simple.cpp
> +++ b/src/libcamera/pipeline/simple/simple.cpp
> @@ -554,7 +554,7 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
>
> if (useConverter_) {
> int ret = converter_->configure(pipeConfig.pixelFormat,
> - cfg.pixelFormat, cfg.size);
> + cfg.size, &cfg);
> if (ret < 0) {
> LOG(SimplePipeline, Error)
> << "Unable to configure converter";
> --
> Regards,
>
> Laurent Pinchart
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
--
Regards,
Niklas Söderlund
More information about the libcamera-devel
mailing list