apps: cam: sdl_sink: Support more single-plane formats

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>
This commit is contained in:
Barnabás Pőcze 2025-04-18 15:01:34 +02:00
parent b24cd12293
commit e5442c3150

View file

@ -11,6 +11,7 @@
#include <fcntl.h>
#include <iomanip>
#include <iostream>
#include <optional>
#include <signal.h>
#include <sstream>
#include <string.h>
@ -32,6 +33,46 @@ 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::RGBA8888:
return SDL_PIXELFORMAT_ABGR32;
case libcamera::formats::ARGB8888:
return SDL_PIXELFORMAT_BGRA32;
case libcamera::formats::BGRA8888:
return SDL_PIXELFORMAT_ARGB32;
case libcamera::formats::ABGR8888:
return SDL_PIXELFORMAT_RGBA32;
#if SDL_VERSION_ATLEAST(2, 29, 1)
case libcamera::formats::RGBX8888:
return SDL_PIXELFORMAT_XBGR32;
case libcamera::formats::XRGB8888:
return SDL_PIXELFORMAT_BGRX32;
case libcamera::formats::BGRX8888:
return SDL_PIXELFORMAT_XRGB32;
case libcamera::formats::XBGR8888:
return SDL_PIXELFORMAT_RGBX32;
#endif
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 +104,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;
}