[libcamera-devel,3/4] cam: sdl_sink: Support multi-planar formats
diff mbox series

Message ID 20220807021718.9789-4-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • cam: Add support for NV12 in the SDL sink
Related show

Commit Message

Laurent Pinchart Aug. 7, 2022, 2:17 a.m. UTC
In order to prepare for NV12 support, implement support for multi-planar
formats in the SDL sink. This mainly consists in passing a vector of
plane data to the SDLTexture::update() function instead of a single
value.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/cam/sdl_sink.cpp         | 21 +++++++++++++--------
 src/cam/sdl_texture.h        |  4 +++-
 src/cam/sdl_texture_mjpg.cpp |  4 ++--
 src/cam/sdl_texture_mjpg.h   |  2 +-
 src/cam/sdl_texture_yuv.cpp  |  4 ++--
 src/cam/sdl_texture_yuv.h    |  2 +-
 6 files changed, 22 insertions(+), 15 deletions(-)

Comments

Kieran Bingham Aug. 7, 2022, 10:26 p.m. UTC | #1
Quoting Laurent Pinchart via libcamera-devel (2022-08-07 03:17:17)
> In order to prepare for NV12 support, implement support for multi-planar
> formats in the SDL sink. This mainly consists in passing a vector of
> plane data to the SDLTexture::update() function instead of a single
> value.
> 

Looks ok here,


Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  src/cam/sdl_sink.cpp         | 21 +++++++++++++--------
>  src/cam/sdl_texture.h        |  4 +++-
>  src/cam/sdl_texture_mjpg.cpp |  4 ++--
>  src/cam/sdl_texture_mjpg.h   |  2 +-
>  src/cam/sdl_texture_yuv.cpp  |  4 ++--
>  src/cam/sdl_texture_yuv.h    |  2 +-
>  6 files changed, 22 insertions(+), 15 deletions(-)
> 
> diff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp
> index 04350bd5365b..9675cf275186 100644
> --- a/src/cam/sdl_sink.cpp
> +++ b/src/cam/sdl_sink.cpp
> @@ -185,16 +185,21 @@ void SDLSink::renderBuffer(FrameBuffer *buffer)
>  {
>         Image *image = mappedBuffers_[buffer].get();
>  
> -       /* \todo Implement support for multi-planar formats. */
> -       const FrameMetadata::Plane &meta = buffer->metadata().planes()[0];
> +       std::vector<Span<const uint8_t>> planes;
> +       unsigned int i = 0;
>  
> -       Span<uint8_t> data = image->data(0);
> -       if (meta.bytesused > data.size())
> -               std::cerr << "payload size " << meta.bytesused
> -                         << " larger than plane size " << data.size()
> -                         << std::endl;
> +       for (const FrameMetadata::Plane &meta : buffer->metadata().planes()) {
> +               Span<uint8_t> data = image->data(i);
> +               if (meta.bytesused > data.size())
> +                       std::cerr << "payload size " << meta.bytesused
> +                                 << " larger than plane size " << data.size()
> +                                 << std::endl;
>  
> -       texture_->update(data);
> +               planes.push_back(data);
> +               i++;
> +       }
> +
> +       texture_->update(planes);
>  
>         SDL_RenderClear(renderer_);
>         SDL_RenderCopy(renderer_, texture_->get(), nullptr, nullptr);
> diff --git a/src/cam/sdl_texture.h b/src/cam/sdl_texture.h
> index f523fa5ebf51..e4d3fb2bcf39 100644
> --- a/src/cam/sdl_texture.h
> +++ b/src/cam/sdl_texture.h
> @@ -7,6 +7,8 @@
>  
>  #pragma once
>  
> +#include <vector>
> +
>  #include <SDL2/SDL.h>
>  
>  #include "image.h"
> @@ -17,7 +19,7 @@ public:
>         SDLTexture(const SDL_Rect &rect, uint32_t pixelFormat, const int pitch);
>         virtual ~SDLTexture();
>         int create(SDL_Renderer *renderer);
> -       virtual void update(libcamera::Span<const uint8_t> data) = 0;
> +       virtual void update(const std::vector<libcamera::Span<const uint8_t>> &data) = 0;
>         SDL_Texture *get() const { return ptr_; }
>  
>  protected:
> diff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp
> index 7542efd75d96..8dd5ee3eb6bc 100644
> --- a/src/cam/sdl_texture_mjpg.cpp
> +++ b/src/cam/sdl_texture_mjpg.cpp
> @@ -76,8 +76,8 @@ int SDLTextureMJPG::decompress(Span<const uint8_t> data)
>         return 0;
>  }
>  
> -void SDLTextureMJPG::update(Span<const uint8_t> data)
> +void SDLTextureMJPG::update(const std::vector<libcamera::Span<const uint8_t>> &data)
>  {
> -       decompress(data);
> +       decompress(data[0]);
>         SDL_UpdateTexture(ptr_, nullptr, rgb_.get(), pitch_);
>  }
> diff --git a/src/cam/sdl_texture_mjpg.h b/src/cam/sdl_texture_mjpg.h
> index 5141ed73bf70..814ca79ac193 100644
> --- a/src/cam/sdl_texture_mjpg.h
> +++ b/src/cam/sdl_texture_mjpg.h
> @@ -14,7 +14,7 @@ class SDLTextureMJPG : public SDLTexture
>  public:
>         SDLTextureMJPG(const SDL_Rect &rect);
>  
> -       void update(libcamera::Span<const uint8_t> data) override;
> +       void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
>  
>  private:
>         int decompress(libcamera::Span<const uint8_t> data);
> diff --git a/src/cam/sdl_texture_yuv.cpp b/src/cam/sdl_texture_yuv.cpp
> index 07df4961a1ab..a5721182a68b 100644
> --- a/src/cam/sdl_texture_yuv.cpp
> +++ b/src/cam/sdl_texture_yuv.cpp
> @@ -14,7 +14,7 @@ SDLTextureYUYV::SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride)
>  {
>  }
>  
> -void SDLTextureYUYV::update(Span<const uint8_t> data)
> +void SDLTextureYUYV::update(const std::vector<libcamera::Span<const uint8_t>> &data)
>  {
> -       SDL_UpdateTexture(ptr_, &rect_, data.data(), pitch_);
> +       SDL_UpdateTexture(ptr_, &rect_, data[0].data(), pitch_);
>  }
> diff --git a/src/cam/sdl_texture_yuv.h b/src/cam/sdl_texture_yuv.h
> index 81e51381ec62..c9130298b91d 100644
> --- a/src/cam/sdl_texture_yuv.h
> +++ b/src/cam/sdl_texture_yuv.h
> @@ -13,5 +13,5 @@ class SDLTextureYUYV : public SDLTexture
>  {
>  public:
>         SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride);
> -       void update(libcamera::Span<const uint8_t> data) override;
> +       void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
>  };
> -- 
> Regards,
> 
> Laurent Pinchart
>
Jacopo Mondi Aug. 8, 2022, 8:28 a.m. UTC | #2
Hi Laurent

On Sun, Aug 07, 2022 at 05:17:17AM +0300, Laurent Pinchart via libcamera-devel wrote:
> In order to prepare for NV12 support, implement support for multi-planar
> formats in the SDL sink. This mainly consists in passing a vector of
> plane data to the SDLTexture::update() function instead of a single
> value.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  src/cam/sdl_sink.cpp         | 21 +++++++++++++--------
>  src/cam/sdl_texture.h        |  4 +++-
>  src/cam/sdl_texture_mjpg.cpp |  4 ++--
>  src/cam/sdl_texture_mjpg.h   |  2 +-
>  src/cam/sdl_texture_yuv.cpp  |  4 ++--
>  src/cam/sdl_texture_yuv.h    |  2 +-
>  6 files changed, 22 insertions(+), 15 deletions(-)
>
> diff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp
> index 04350bd5365b..9675cf275186 100644
> --- a/src/cam/sdl_sink.cpp
> +++ b/src/cam/sdl_sink.cpp
> @@ -185,16 +185,21 @@ void SDLSink::renderBuffer(FrameBuffer *buffer)
>  {
>  	Image *image = mappedBuffers_[buffer].get();
>
> -	/* \todo Implement support for multi-planar formats. */
> -	const FrameMetadata::Plane &meta = buffer->metadata().planes()[0];
> +	std::vector<Span<const uint8_t>> planes;

You could .reserve() but it's not a big deal

> +	unsigned int i = 0;
>
> -	Span<uint8_t> data = image->data(0);
> -	if (meta.bytesused > data.size())
> -		std::cerr << "payload size " << meta.bytesused
> -			  << " larger than plane size " << data.size()
> -			  << std::endl;
> +	for (const FrameMetadata::Plane &meta : buffer->metadata().planes()) {

I was about to suggest

        for (const auto &[i, meta] : utils::enumerate(buffer->metadata().planes())) {

and to use utils::enumerate() I have to:

#include <libcamera/base/utils.h>

Which gives me

In file included from ../include/libcamera/base/utils.h:23,
                 from ../src/cam/image.h:17,
                 from ../src/cam/image.cpp:8:
../include/libcamera/base/private.h:21:2: error: #error "Private headers must not be included in the libcamera API"
   21 | #error "Private headers must not be included in the libcamera API"

Which is a bit strange as the file includes several headers from the
<libcamera/base/> inclusion path already :/

That apart
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
  j


> +		Span<uint8_t> data = image->data(i);
> +		if (meta.bytesused > data.size())
> +			std::cerr << "payload size " << meta.bytesused
> +				  << " larger than plane size " << data.size()
> +				  << std::endl;
>
> -	texture_->update(data);
> +		planes.push_back(data);
> +		i++;
> +	}
> +
> +	texture_->update(planes);
>
>  	SDL_RenderClear(renderer_);
>  	SDL_RenderCopy(renderer_, texture_->get(), nullptr, nullptr);
> diff --git a/src/cam/sdl_texture.h b/src/cam/sdl_texture.h
> index f523fa5ebf51..e4d3fb2bcf39 100644
> --- a/src/cam/sdl_texture.h
> +++ b/src/cam/sdl_texture.h
> @@ -7,6 +7,8 @@
>
>  #pragma once
>
> +#include <vector>
> +
>  #include <SDL2/SDL.h>
>
>  #include "image.h"
> @@ -17,7 +19,7 @@ public:
>  	SDLTexture(const SDL_Rect &rect, uint32_t pixelFormat, const int pitch);
>  	virtual ~SDLTexture();
>  	int create(SDL_Renderer *renderer);
> -	virtual void update(libcamera::Span<const uint8_t> data) = 0;
> +	virtual void update(const std::vector<libcamera::Span<const uint8_t>> &data) = 0;
>  	SDL_Texture *get() const { return ptr_; }
>
>  protected:
> diff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp
> index 7542efd75d96..8dd5ee3eb6bc 100644
> --- a/src/cam/sdl_texture_mjpg.cpp
> +++ b/src/cam/sdl_texture_mjpg.cpp
> @@ -76,8 +76,8 @@ int SDLTextureMJPG::decompress(Span<const uint8_t> data)
>  	return 0;
>  }
>
> -void SDLTextureMJPG::update(Span<const uint8_t> data)
> +void SDLTextureMJPG::update(const std::vector<libcamera::Span<const uint8_t>> &data)
>  {
> -	decompress(data);
> +	decompress(data[0]);
>  	SDL_UpdateTexture(ptr_, nullptr, rgb_.get(), pitch_);
>  }
> diff --git a/src/cam/sdl_texture_mjpg.h b/src/cam/sdl_texture_mjpg.h
> index 5141ed73bf70..814ca79ac193 100644
> --- a/src/cam/sdl_texture_mjpg.h
> +++ b/src/cam/sdl_texture_mjpg.h
> @@ -14,7 +14,7 @@ class SDLTextureMJPG : public SDLTexture
>  public:
>  	SDLTextureMJPG(const SDL_Rect &rect);
>
> -	void update(libcamera::Span<const uint8_t> data) override;
> +	void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
>
>  private:
>  	int decompress(libcamera::Span<const uint8_t> data);
> diff --git a/src/cam/sdl_texture_yuv.cpp b/src/cam/sdl_texture_yuv.cpp
> index 07df4961a1ab..a5721182a68b 100644
> --- a/src/cam/sdl_texture_yuv.cpp
> +++ b/src/cam/sdl_texture_yuv.cpp
> @@ -14,7 +14,7 @@ SDLTextureYUYV::SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride)
>  {
>  }
>
> -void SDLTextureYUYV::update(Span<const uint8_t> data)
> +void SDLTextureYUYV::update(const std::vector<libcamera::Span<const uint8_t>> &data)
>  {
> -	SDL_UpdateTexture(ptr_, &rect_, data.data(), pitch_);
> +	SDL_UpdateTexture(ptr_, &rect_, data[0].data(), pitch_);
>  }
> diff --git a/src/cam/sdl_texture_yuv.h b/src/cam/sdl_texture_yuv.h
> index 81e51381ec62..c9130298b91d 100644
> --- a/src/cam/sdl_texture_yuv.h
> +++ b/src/cam/sdl_texture_yuv.h
> @@ -13,5 +13,5 @@ class SDLTextureYUYV : public SDLTexture
>  {
>  public:
>  	SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride);
> -	void update(libcamera::Span<const uint8_t> data) override;
> +	void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
>  };
> --
> Regards,
>
> Laurent Pinchart
>
Eric Curtin Aug. 8, 2022, 9:21 a.m. UTC | #3
On Sun, 7 Aug 2022 at 03:17, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> In order to prepare for NV12 support, implement support for multi-planar
> formats in the SDL sink. This mainly consists in passing a vector of
> plane data to the SDLTexture::update() function instead of a single
> value.
>

LGTM

Reviewed-by: Eric Curtin <ecurtin@redhat.com>

> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  src/cam/sdl_sink.cpp         | 21 +++++++++++++--------
>  src/cam/sdl_texture.h        |  4 +++-
>  src/cam/sdl_texture_mjpg.cpp |  4 ++--
>  src/cam/sdl_texture_mjpg.h   |  2 +-
>  src/cam/sdl_texture_yuv.cpp  |  4 ++--
>  src/cam/sdl_texture_yuv.h    |  2 +-
>  6 files changed, 22 insertions(+), 15 deletions(-)
>
> diff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp
> index 04350bd5365b..9675cf275186 100644
> --- a/src/cam/sdl_sink.cpp
> +++ b/src/cam/sdl_sink.cpp
> @@ -185,16 +185,21 @@ void SDLSink::renderBuffer(FrameBuffer *buffer)
>  {
>         Image *image = mappedBuffers_[buffer].get();
>
> -       /* \todo Implement support for multi-planar formats. */
> -       const FrameMetadata::Plane &meta = buffer->metadata().planes()[0];
> +       std::vector<Span<const uint8_t>> planes;
> +       unsigned int i = 0;
>
> -       Span<uint8_t> data = image->data(0);
> -       if (meta.bytesused > data.size())
> -               std::cerr << "payload size " << meta.bytesused
> -                         << " larger than plane size " << data.size()
> -                         << std::endl;
> +       for (const FrameMetadata::Plane &meta : buffer->metadata().planes()) {
> +               Span<uint8_t> data = image->data(i);
> +               if (meta.bytesused > data.size())
> +                       std::cerr << "payload size " << meta.bytesused
> +                                 << " larger than plane size " << data.size()
> +                                 << std::endl;
>
> -       texture_->update(data);
> +               planes.push_back(data);
> +               i++;
> +       }
> +
> +       texture_->update(planes);
>
>         SDL_RenderClear(renderer_);
>         SDL_RenderCopy(renderer_, texture_->get(), nullptr, nullptr);
> diff --git a/src/cam/sdl_texture.h b/src/cam/sdl_texture.h
> index f523fa5ebf51..e4d3fb2bcf39 100644
> --- a/src/cam/sdl_texture.h
> +++ b/src/cam/sdl_texture.h
> @@ -7,6 +7,8 @@
>
>  #pragma once
>
> +#include <vector>
> +
>  #include <SDL2/SDL.h>
>
>  #include "image.h"
> @@ -17,7 +19,7 @@ public:
>         SDLTexture(const SDL_Rect &rect, uint32_t pixelFormat, const int pitch);
>         virtual ~SDLTexture();
>         int create(SDL_Renderer *renderer);
> -       virtual void update(libcamera::Span<const uint8_t> data) = 0;
> +       virtual void update(const std::vector<libcamera::Span<const uint8_t>> &data) = 0;
>         SDL_Texture *get() const { return ptr_; }
>
>  protected:
> diff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp
> index 7542efd75d96..8dd5ee3eb6bc 100644
> --- a/src/cam/sdl_texture_mjpg.cpp
> +++ b/src/cam/sdl_texture_mjpg.cpp
> @@ -76,8 +76,8 @@ int SDLTextureMJPG::decompress(Span<const uint8_t> data)
>         return 0;
>  }
>
> -void SDLTextureMJPG::update(Span<const uint8_t> data)
> +void SDLTextureMJPG::update(const std::vector<libcamera::Span<const uint8_t>> &data)
>  {
> -       decompress(data);
> +       decompress(data[0]);
>         SDL_UpdateTexture(ptr_, nullptr, rgb_.get(), pitch_);
>  }
> diff --git a/src/cam/sdl_texture_mjpg.h b/src/cam/sdl_texture_mjpg.h
> index 5141ed73bf70..814ca79ac193 100644
> --- a/src/cam/sdl_texture_mjpg.h
> +++ b/src/cam/sdl_texture_mjpg.h
> @@ -14,7 +14,7 @@ class SDLTextureMJPG : public SDLTexture
>  public:
>         SDLTextureMJPG(const SDL_Rect &rect);
>
> -       void update(libcamera::Span<const uint8_t> data) override;
> +       void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
>
>  private:
>         int decompress(libcamera::Span<const uint8_t> data);
> diff --git a/src/cam/sdl_texture_yuv.cpp b/src/cam/sdl_texture_yuv.cpp
> index 07df4961a1ab..a5721182a68b 100644
> --- a/src/cam/sdl_texture_yuv.cpp
> +++ b/src/cam/sdl_texture_yuv.cpp
> @@ -14,7 +14,7 @@ SDLTextureYUYV::SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride)
>  {
>  }
>
> -void SDLTextureYUYV::update(Span<const uint8_t> data)
> +void SDLTextureYUYV::update(const std::vector<libcamera::Span<const uint8_t>> &data)
>  {
> -       SDL_UpdateTexture(ptr_, &rect_, data.data(), pitch_);
> +       SDL_UpdateTexture(ptr_, &rect_, data[0].data(), pitch_);
>  }
> diff --git a/src/cam/sdl_texture_yuv.h b/src/cam/sdl_texture_yuv.h
> index 81e51381ec62..c9130298b91d 100644
> --- a/src/cam/sdl_texture_yuv.h
> +++ b/src/cam/sdl_texture_yuv.h
> @@ -13,5 +13,5 @@ class SDLTextureYUYV : public SDLTexture
>  {
>  public:
>         SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride);
> -       void update(libcamera::Span<const uint8_t> data) override;
> +       void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
>  };
> --
> Regards,
>
> Laurent Pinchart
>
Laurent Pinchart Aug. 8, 2022, 2:31 p.m. UTC | #4
Hi Jacopo,

On Mon, Aug 08, 2022 at 10:28:29AM +0200, Jacopo Mondi wrote:
> On Sun, Aug 07, 2022 at 05:17:17AM +0300, Laurent Pinchart via libcamera-devel wrote:
> > In order to prepare for NV12 support, implement support for multi-planar
> > formats in the SDL sink. This mainly consists in passing a vector of
> > plane data to the SDLTexture::update() function instead of a single
> > value.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> >  src/cam/sdl_sink.cpp         | 21 +++++++++++++--------
> >  src/cam/sdl_texture.h        |  4 +++-
> >  src/cam/sdl_texture_mjpg.cpp |  4 ++--
> >  src/cam/sdl_texture_mjpg.h   |  2 +-
> >  src/cam/sdl_texture_yuv.cpp  |  4 ++--
> >  src/cam/sdl_texture_yuv.h    |  2 +-
> >  6 files changed, 22 insertions(+), 15 deletions(-)
> >
> > diff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp
> > index 04350bd5365b..9675cf275186 100644
> > --- a/src/cam/sdl_sink.cpp
> > +++ b/src/cam/sdl_sink.cpp
> > @@ -185,16 +185,21 @@ void SDLSink::renderBuffer(FrameBuffer *buffer)
> >  {
> >  	Image *image = mappedBuffers_[buffer].get();
> >
> > -	/* \todo Implement support for multi-planar formats. */
> > -	const FrameMetadata::Plane &meta = buffer->metadata().planes()[0];
> > +	std::vector<Span<const uint8_t>> planes;
> 
> You could .reserve() but it's not a big deal

I'll add:

	planes.reserve(buffer->metadata()->planes().size());

> > +	unsigned int i = 0;
> >
> > -	Span<uint8_t> data = image->data(0);
> > -	if (meta.bytesused > data.size())
> > -		std::cerr << "payload size " << meta.bytesused
> > -			  << " larger than plane size " << data.size()
> > -			  << std::endl;
> > +	for (const FrameMetadata::Plane &meta : buffer->metadata().planes()) {
> 
> I was about to suggest
> 
>         for (const auto &[i, meta] : utils::enumerate(buffer->metadata().planes())) {
> 
> and to use utils::enumerate() I have to:
> 
> #include <libcamera/base/utils.h>
> 
> Which gives me
> 
> In file included from ../include/libcamera/base/utils.h:23,
>                  from ../src/cam/image.h:17,
>                  from ../src/cam/image.cpp:8:
> ../include/libcamera/base/private.h:21:2: error: #error "Private headers must not be included in the libcamera API"
>    21 | #error "Private headers must not be included in the libcamera API"
> 
> Which is a bit strange as the file includes several headers from the
> <libcamera/base/> inclusion path already :/

That's because some of the base headers are considered private, to avoid
having to maintain ABI compatibility. The headers we expose in the
public API are the ones used the libcamera public API:

- bound_method.h
- class.h
- compiler.h
- flags.h
- message.h
- mutex.h
- object.h
- shared_fd.h
- signal.h
- span.h
- thread.h
- unique_fd.h

message.h, mutex.h and thread.h actually don't need to be exposed. I'll
send a patch to make them private.

> That apart
> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
> 
> > +		Span<uint8_t> data = image->data(i);
> > +		if (meta.bytesused > data.size())
> > +			std::cerr << "payload size " << meta.bytesused
> > +				  << " larger than plane size " << data.size()
> > +				  << std::endl;
> >
> > -	texture_->update(data);
> > +		planes.push_back(data);
> > +		i++;
> > +	}
> > +
> > +	texture_->update(planes);
> >
> >  	SDL_RenderClear(renderer_);
> >  	SDL_RenderCopy(renderer_, texture_->get(), nullptr, nullptr);
> > diff --git a/src/cam/sdl_texture.h b/src/cam/sdl_texture.h
> > index f523fa5ebf51..e4d3fb2bcf39 100644
> > --- a/src/cam/sdl_texture.h
> > +++ b/src/cam/sdl_texture.h
> > @@ -7,6 +7,8 @@
> >
> >  #pragma once
> >
> > +#include <vector>
> > +
> >  #include <SDL2/SDL.h>
> >
> >  #include "image.h"
> > @@ -17,7 +19,7 @@ public:
> >  	SDLTexture(const SDL_Rect &rect, uint32_t pixelFormat, const int pitch);
> >  	virtual ~SDLTexture();
> >  	int create(SDL_Renderer *renderer);
> > -	virtual void update(libcamera::Span<const uint8_t> data) = 0;
> > +	virtual void update(const std::vector<libcamera::Span<const uint8_t>> &data) = 0;
> >  	SDL_Texture *get() const { return ptr_; }
> >
> >  protected:
> > diff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp
> > index 7542efd75d96..8dd5ee3eb6bc 100644
> > --- a/src/cam/sdl_texture_mjpg.cpp
> > +++ b/src/cam/sdl_texture_mjpg.cpp
> > @@ -76,8 +76,8 @@ int SDLTextureMJPG::decompress(Span<const uint8_t> data)
> >  	return 0;
> >  }
> >
> > -void SDLTextureMJPG::update(Span<const uint8_t> data)
> > +void SDLTextureMJPG::update(const std::vector<libcamera::Span<const uint8_t>> &data)
> >  {
> > -	decompress(data);
> > +	decompress(data[0]);
> >  	SDL_UpdateTexture(ptr_, nullptr, rgb_.get(), pitch_);
> >  }
> > diff --git a/src/cam/sdl_texture_mjpg.h b/src/cam/sdl_texture_mjpg.h
> > index 5141ed73bf70..814ca79ac193 100644
> > --- a/src/cam/sdl_texture_mjpg.h
> > +++ b/src/cam/sdl_texture_mjpg.h
> > @@ -14,7 +14,7 @@ class SDLTextureMJPG : public SDLTexture
> >  public:
> >  	SDLTextureMJPG(const SDL_Rect &rect);
> >
> > -	void update(libcamera::Span<const uint8_t> data) override;
> > +	void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
> >
> >  private:
> >  	int decompress(libcamera::Span<const uint8_t> data);
> > diff --git a/src/cam/sdl_texture_yuv.cpp b/src/cam/sdl_texture_yuv.cpp
> > index 07df4961a1ab..a5721182a68b 100644
> > --- a/src/cam/sdl_texture_yuv.cpp
> > +++ b/src/cam/sdl_texture_yuv.cpp
> > @@ -14,7 +14,7 @@ SDLTextureYUYV::SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride)
> >  {
> >  }
> >
> > -void SDLTextureYUYV::update(Span<const uint8_t> data)
> > +void SDLTextureYUYV::update(const std::vector<libcamera::Span<const uint8_t>> &data)
> >  {
> > -	SDL_UpdateTexture(ptr_, &rect_, data.data(), pitch_);
> > +	SDL_UpdateTexture(ptr_, &rect_, data[0].data(), pitch_);
> >  }
> > diff --git a/src/cam/sdl_texture_yuv.h b/src/cam/sdl_texture_yuv.h
> > index 81e51381ec62..c9130298b91d 100644
> > --- a/src/cam/sdl_texture_yuv.h
> > +++ b/src/cam/sdl_texture_yuv.h
> > @@ -13,5 +13,5 @@ class SDLTextureYUYV : public SDLTexture
> >  {
> >  public:
> >  	SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride);
> > -	void update(libcamera::Span<const uint8_t> data) override;
> > +	void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
> >  };

Patch
diff mbox series

diff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp
index 04350bd5365b..9675cf275186 100644
--- a/src/cam/sdl_sink.cpp
+++ b/src/cam/sdl_sink.cpp
@@ -185,16 +185,21 @@  void SDLSink::renderBuffer(FrameBuffer *buffer)
 {
 	Image *image = mappedBuffers_[buffer].get();
 
-	/* \todo Implement support for multi-planar formats. */
-	const FrameMetadata::Plane &meta = buffer->metadata().planes()[0];
+	std::vector<Span<const uint8_t>> planes;
+	unsigned int i = 0;
 
-	Span<uint8_t> data = image->data(0);
-	if (meta.bytesused > data.size())
-		std::cerr << "payload size " << meta.bytesused
-			  << " larger than plane size " << data.size()
-			  << std::endl;
+	for (const FrameMetadata::Plane &meta : buffer->metadata().planes()) {
+		Span<uint8_t> data = image->data(i);
+		if (meta.bytesused > data.size())
+			std::cerr << "payload size " << meta.bytesused
+				  << " larger than plane size " << data.size()
+				  << std::endl;
 
-	texture_->update(data);
+		planes.push_back(data);
+		i++;
+	}
+
+	texture_->update(planes);
 
 	SDL_RenderClear(renderer_);
 	SDL_RenderCopy(renderer_, texture_->get(), nullptr, nullptr);
diff --git a/src/cam/sdl_texture.h b/src/cam/sdl_texture.h
index f523fa5ebf51..e4d3fb2bcf39 100644
--- a/src/cam/sdl_texture.h
+++ b/src/cam/sdl_texture.h
@@ -7,6 +7,8 @@ 
 
 #pragma once
 
+#include <vector>
+
 #include <SDL2/SDL.h>
 
 #include "image.h"
@@ -17,7 +19,7 @@  public:
 	SDLTexture(const SDL_Rect &rect, uint32_t pixelFormat, const int pitch);
 	virtual ~SDLTexture();
 	int create(SDL_Renderer *renderer);
-	virtual void update(libcamera::Span<const uint8_t> data) = 0;
+	virtual void update(const std::vector<libcamera::Span<const uint8_t>> &data) = 0;
 	SDL_Texture *get() const { return ptr_; }
 
 protected:
diff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp
index 7542efd75d96..8dd5ee3eb6bc 100644
--- a/src/cam/sdl_texture_mjpg.cpp
+++ b/src/cam/sdl_texture_mjpg.cpp
@@ -76,8 +76,8 @@  int SDLTextureMJPG::decompress(Span<const uint8_t> data)
 	return 0;
 }
 
-void SDLTextureMJPG::update(Span<const uint8_t> data)
+void SDLTextureMJPG::update(const std::vector<libcamera::Span<const uint8_t>> &data)
 {
-	decompress(data);
+	decompress(data[0]);
 	SDL_UpdateTexture(ptr_, nullptr, rgb_.get(), pitch_);
 }
diff --git a/src/cam/sdl_texture_mjpg.h b/src/cam/sdl_texture_mjpg.h
index 5141ed73bf70..814ca79ac193 100644
--- a/src/cam/sdl_texture_mjpg.h
+++ b/src/cam/sdl_texture_mjpg.h
@@ -14,7 +14,7 @@  class SDLTextureMJPG : public SDLTexture
 public:
 	SDLTextureMJPG(const SDL_Rect &rect);
 
-	void update(libcamera::Span<const uint8_t> data) override;
+	void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
 
 private:
 	int decompress(libcamera::Span<const uint8_t> data);
diff --git a/src/cam/sdl_texture_yuv.cpp b/src/cam/sdl_texture_yuv.cpp
index 07df4961a1ab..a5721182a68b 100644
--- a/src/cam/sdl_texture_yuv.cpp
+++ b/src/cam/sdl_texture_yuv.cpp
@@ -14,7 +14,7 @@  SDLTextureYUYV::SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride)
 {
 }
 
-void SDLTextureYUYV::update(Span<const uint8_t> data)
+void SDLTextureYUYV::update(const std::vector<libcamera::Span<const uint8_t>> &data)
 {
-	SDL_UpdateTexture(ptr_, &rect_, data.data(), pitch_);
+	SDL_UpdateTexture(ptr_, &rect_, data[0].data(), pitch_);
 }
diff --git a/src/cam/sdl_texture_yuv.h b/src/cam/sdl_texture_yuv.h
index 81e51381ec62..c9130298b91d 100644
--- a/src/cam/sdl_texture_yuv.h
+++ b/src/cam/sdl_texture_yuv.h
@@ -13,5 +13,5 @@  class SDLTextureYUYV : public SDLTexture
 {
 public:
 	SDLTextureYUYV(const SDL_Rect &rect, unsigned int stride);
-	void update(libcamera::Span<const uint8_t> data) override;
+	void update(const std::vector<libcamera::Span<const uint8_t>> &data) override;
 };