[v4,4/4] apps: cam: sdl_sink: Support more single-plane formats
diff mbox series

Message ID 20250430075849.2790398-5-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • apps: cam: sdl_sink: Support more RGB and YUV formats
Related show

Commit Message

Barnabás Pőcze April 30, 2025, 7:58 a.m. UTC
With the newly introduced `SDLTexture1Plane` it is easy to handle
any single-plane format that has an SDL equivalent. So use it for
more YUV and RGB formats.

The mapping of RGB formats is not entirely straightforward because
`SDL_PIXELFORMAT_ZZZ...888...` defines a format where the order of
the components is endian dependent, while libcamera's `ZZZ...888...`
formats are derived from the matching DRM formats, and the RGB formats
in question are defined to be little-endian there. So the
endian-independent `SDL_PIXELFORMAT_{ZZZ24,ZZZZ32}` are used.

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>
---
 src/apps/cam/sdl_sink.cpp | 58 +++++++++++++++++++++++++++++++--------
 1 file changed, 46 insertions(+), 12 deletions(-)

Patch
diff mbox series

diff --git a/src/apps/cam/sdl_sink.cpp b/src/apps/cam/sdl_sink.cpp
index b295675dc..15087ec7a 100644
--- a/src/apps/cam/sdl_sink.cpp
+++ b/src/apps/cam/sdl_sink.cpp
@@ -11,6 +11,7 @@ 
 #include <fcntl.h>
 #include <iomanip>
 #include <iostream>
+#include <optional>
 #include <signal.h>
 #include <sstream>
 #include <string.h>
@@ -32,6 +33,44 @@  using namespace libcamera;
 
 using namespace std::chrono_literals;
 
+namespace {
+
+std::optional<SDL_PixelFormatEnum> singlePlaneFormatToSDL(const libcamera::PixelFormat &f)
+{
+	switch (f) {
+	case libcamera::formats::RGB888:
+		return SDL_PIXELFORMAT_BGR24;
+	case libcamera::formats::BGR888:
+		return SDL_PIXELFORMAT_RGB24;
+	case libcamera::formats::ARGB8888:
+		return SDL_PIXELFORMAT_BGRA32;
+	case libcamera::formats::XRGB8888:
+		return SDL_PIXELFORMAT_BGRX32;
+	case libcamera::formats::RGBA8888:
+		return SDL_PIXELFORMAT_ABGR32;
+	case libcamera::formats::RGBX8888:
+		return SDL_PIXELFORMAT_XBGR32;
+	case libcamera::formats::ABGR8888:
+		return SDL_PIXELFORMAT_RGBA32;
+	case libcamera::formats::XBGR8888:
+		return SDL_PIXELFORMAT_RGBX32;
+	case libcamera::formats::BGRA8888:
+		return SDL_PIXELFORMAT_ARGB32;
+	case libcamera::formats::BGRX8888:
+		return SDL_PIXELFORMAT_XRGB32;
+	case libcamera::formats::YUYV:
+		return SDL_PIXELFORMAT_YUY2;
+	case libcamera::formats::UYVY:
+		return SDL_PIXELFORMAT_UYVY;
+	case libcamera::formats::YVYU:
+		return SDL_PIXELFORMAT_YVYU;
+	}
+
+	return {};
+}
+
+} /* namespace */
+
 SDLSink::SDLSink()
 	: window_(nullptr), renderer_(nullptr), rect_({}),
 	  init_(false)
@@ -63,25 +102,20 @@  int SDLSink::configure(const libcamera::CameraConfiguration &config)
 	rect_.w = cfg.size.width;
 	rect_.h = cfg.size.height;
 
-	switch (cfg.pixelFormat) {
+	if (auto sdlFormat = singlePlaneFormatToSDL(cfg.pixelFormat))
+		texture_ = std::make_unique<SDLTexture1Plane>(rect_, *sdlFormat, cfg.stride);
 #ifdef HAVE_LIBJPEG
-	case libcamera::formats::MJPEG:
+	else if (cfg.pixelFormat == libcamera::formats::MJPEG)
 		texture_ = std::make_unique<SDLTextureMJPG>(rect_);
-		break;
 #endif
 #if SDL_VERSION_ATLEAST(2, 0, 16)
-	case libcamera::formats::NV12:
+	else if (cfg.pixelFormat == libcamera::formats::NV12)
 		texture_ = std::make_unique<SDLTextureNV12>(rect_, cfg.stride);
-		break;
 #endif
-	case libcamera::formats::YUYV:
-		texture_ = std::make_unique<SDLTexture1Plane>(rect_, SDL_PIXELFORMAT_YUY2, cfg.stride);
-		break;
-	default:
-		std::cerr << "Unsupported pixel format "
-			  << cfg.pixelFormat.toString() << std::endl;
+	else {
+		std::cerr << "Unsupported pixel format " << cfg.pixelFormat << std::endl;
 		return -EINVAL;
-	};
+	}
 
 	return 0;
 }