[v2] apps: cam: sdl_texture: Support YUV420
diff mbox series

Message ID 20261019120939.111254-1-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • [v2] apps: cam: sdl_texture: Support YUV420
Related show

Commit Message

Barnabás Pőcze Oct. 19, 2026, 12:09 p.m. UTC
Add a new `SDLTexture` derived class that uses `SDL_UpdateYUVTexture()`,
and implement the handling of the aforementioned libcamera format.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
tested with:
  * https://patchwork.libcamera.org/patch/28458/
  * rkisp1
  * vivid

changes in v2:
  * drop YVU420 because `SDL_UpdateYUVTexture()` always wants the U, V
    planes in that order, so some kind of swapping would be needed

v1: https://patchwork.libcamera.org/patch/28466/
---
 src/apps/cam/sdl_sink.cpp        |  2 ++
 src/apps/cam/sdl_texture_yuv.cpp | 19 +++++++++++++++++++
 src/apps/cam/sdl_texture_yuv.h   |  7 +++++++
 3 files changed, 28 insertions(+)

--
2.56.0

Comments

Laurent Pinchart Oct. 19, 2026, 12:32 p.m. UTC | #1
Hi Barnabás,

Thank you for the patch.

On Mon, Oct 19, 2026 at 02:09:39PM +0200, Barnabás Pőcze wrote:
> Add a new `SDLTexture` derived class that uses `SDL_UpdateYUVTexture()`,
> and implement the handling of the aforementioned libcamera format.
> 
> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
> tested with:
>   * https://patchwork.libcamera.org/patch/28458/
>   * rkisp1
>   * vivid
> 
> changes in v2:
>   * drop YVU420 because `SDL_UpdateYUVTexture()` always wants the U, V
>     planes in that order, so some kind of swapping would be needed
> 
> v1: https://patchwork.libcamera.org/patch/28466/
> ---
>  src/apps/cam/sdl_sink.cpp        |  2 ++
>  src/apps/cam/sdl_texture_yuv.cpp | 19 +++++++++++++++++++
>  src/apps/cam/sdl_texture_yuv.h   |  7 +++++++
>  3 files changed, 28 insertions(+)
> 
> diff --git a/src/apps/cam/sdl_sink.cpp b/src/apps/cam/sdl_sink.cpp
> index d16e4dc14c..2d061ad823 100644
> --- a/src/apps/cam/sdl_sink.cpp
> +++ b/src/apps/cam/sdl_sink.cpp
> @@ -116,6 +116,8 @@ int SDLSink::configure(const libcamera::CameraConfiguration &config)
>  	else if (cfg.pixelFormat == libcamera::formats::NV21)
>  		texture_ = std::make_unique<SDLTextureNV>(rect_, SDL_PIXELFORMAT_NV21, cfg.stride);
>  #endif
> +	else if (cfg.pixelFormat == libcamera::formats::YUV420)
> +		texture_ = std::make_unique<SDLTextureYUV>(rect_, SDL_PIXELFORMAT_IYUV, cfg.stride);
>  	else {
>  		std::cerr << "Unsupported pixel format " << cfg.pixelFormat << std::endl;
>  		return -EINVAL;
> diff --git a/src/apps/cam/sdl_texture_yuv.cpp b/src/apps/cam/sdl_texture_yuv.cpp
> index 42c9d2ddfb..8bfaab5d6a 100644
> --- a/src/apps/cam/sdl_texture_yuv.cpp
> +++ b/src/apps/cam/sdl_texture_yuv.cpp
> @@ -28,3 +28,22 @@ void SDLTextureNV::update(std::span<const std::span<const uint8_t>> data)
>  			    data[1].data(), stride_);
>  }
>  #endif
> +
> +SDLTextureYUV::SDLTextureYUV(const SDL_Rect &rect, uint32_t pixelFormat, unsigned int stride)
> +	: SDLTexture(rect, pixelFormat, stride)
> +{
> +	assert(pixelFormat == SDL_PIXELFORMAT_IYUV);
> +}
> +
> +void SDLTextureYUV::update(std::span<const std::span<const uint8_t>> data)
> +{
> +	assert(data.size() == 3);
> +	assert(data[0].size_bytes() == std::size_t(rect_.h) * std::size_t(stride_));
> +	assert(data[1].size_bytes() == std::size_t(rect_.h) * std::size_t(stride_) / 4);
> +	assert(data[2].size_bytes() == std::size_t(rect_.h) * std::size_t(stride_) / 4);
> +
> +	SDL_UpdateYUVTexture(ptr_, nullptr,
> +			     data[0].data(), stride_,
> +			     data[1].data(), stride_ / 2,
> +			     data[2].data(), stride_ / 2);
> +}
> diff --git a/src/apps/cam/sdl_texture_yuv.h b/src/apps/cam/sdl_texture_yuv.h
> index 5a5ac011f7..531e857e0c 100644
> --- a/src/apps/cam/sdl_texture_yuv.h
> +++ b/src/apps/cam/sdl_texture_yuv.h
> @@ -17,3 +17,10 @@ public:
>  	void update(std::span<const std::span<const uint8_t>> data) override;
>  };
>  #endif
> +
> +class SDLTextureYUV : public SDLTexture
> +{
> +public:
> +	SDLTextureYUV(const SDL_Rect &rect, uint32_t pixelFormat, unsigned int stride);
> +	void update(std::span<const std::span<const uint8_t>> data) override;
> +};

Patch
diff mbox series

diff --git a/src/apps/cam/sdl_sink.cpp b/src/apps/cam/sdl_sink.cpp
index d16e4dc14c..2d061ad823 100644
--- a/src/apps/cam/sdl_sink.cpp
+++ b/src/apps/cam/sdl_sink.cpp
@@ -116,6 +116,8 @@  int SDLSink::configure(const libcamera::CameraConfiguration &config)
 	else if (cfg.pixelFormat == libcamera::formats::NV21)
 		texture_ = std::make_unique<SDLTextureNV>(rect_, SDL_PIXELFORMAT_NV21, cfg.stride);
 #endif
+	else if (cfg.pixelFormat == libcamera::formats::YUV420)
+		texture_ = std::make_unique<SDLTextureYUV>(rect_, SDL_PIXELFORMAT_IYUV, cfg.stride);
 	else {
 		std::cerr << "Unsupported pixel format " << cfg.pixelFormat << std::endl;
 		return -EINVAL;
diff --git a/src/apps/cam/sdl_texture_yuv.cpp b/src/apps/cam/sdl_texture_yuv.cpp
index 42c9d2ddfb..8bfaab5d6a 100644
--- a/src/apps/cam/sdl_texture_yuv.cpp
+++ b/src/apps/cam/sdl_texture_yuv.cpp
@@ -28,3 +28,22 @@  void SDLTextureNV::update(std::span<const std::span<const uint8_t>> data)
 			    data[1].data(), stride_);
 }
 #endif
+
+SDLTextureYUV::SDLTextureYUV(const SDL_Rect &rect, uint32_t pixelFormat, unsigned int stride)
+	: SDLTexture(rect, pixelFormat, stride)
+{
+	assert(pixelFormat == SDL_PIXELFORMAT_IYUV);
+}
+
+void SDLTextureYUV::update(std::span<const std::span<const uint8_t>> data)
+{
+	assert(data.size() == 3);
+	assert(data[0].size_bytes() == std::size_t(rect_.h) * std::size_t(stride_));
+	assert(data[1].size_bytes() == std::size_t(rect_.h) * std::size_t(stride_) / 4);
+	assert(data[2].size_bytes() == std::size_t(rect_.h) * std::size_t(stride_) / 4);
+
+	SDL_UpdateYUVTexture(ptr_, nullptr,
+			     data[0].data(), stride_,
+			     data[1].data(), stride_ / 2,
+			     data[2].data(), stride_ / 2);
+}
diff --git a/src/apps/cam/sdl_texture_yuv.h b/src/apps/cam/sdl_texture_yuv.h
index 5a5ac011f7..531e857e0c 100644
--- a/src/apps/cam/sdl_texture_yuv.h
+++ b/src/apps/cam/sdl_texture_yuv.h
@@ -17,3 +17,10 @@  public:
 	void update(std::span<const std::span<const uint8_t>> data) override;
 };
 #endif
+
+class SDLTextureYUV : public SDLTexture
+{
+public:
+	SDLTextureYUV(const SDL_Rect &rect, uint32_t pixelFormat, unsigned int stride);
+	void update(std::span<const std::span<const uint8_t>> data) override;
+};