[v1] apps: cam: sdl_texture: Support YUV420, YVU420
diff mbox series

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

Commit Message

Barnabás Pőcze Oct. 15, 2026, 10:05 p.m. UTC
Add a new `SDLTexture` derived class that uses `SDL_UpdateYUVTexture()`,
and implement the handling of the aforementioned two libcamera formats.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
---
Inspired and tested only with https://patchwork.libcamera.org/patch/28458/
---
 src/apps/cam/sdl_sink.cpp        |  4 ++++
 src/apps/cam/sdl_texture_yuv.cpp | 19 +++++++++++++++++++
 src/apps/cam/sdl_texture_yuv.h   |  7 +++++++
 3 files changed, 30 insertions(+)

Patch
diff mbox series

diff --git a/src/apps/cam/sdl_sink.cpp b/src/apps/cam/sdl_sink.cpp
index d16e4dc14c..8184933eaf 100644
--- a/src/apps/cam/sdl_sink.cpp
+++ b/src/apps/cam/sdl_sink.cpp
@@ -116,6 +116,10 @@  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 if (cfg.pixelFormat == libcamera::formats::YVU420)
+		texture_ = std::make_unique<SDLTextureYUV>(rect_, SDL_PIXELFORMAT_YV12, 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..6b166f01b9 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 || pixelFormat == SDL_PIXELFORMAT_YV12);
+}
+
+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;
+};