From 153b468930a9df22debb28889312f8a5c511ee04 Mon Sep 17 00:00:00 2001
From: Eric Curtin <ecurtin@redhat.com>
Date: Fri, 20 May 2022 20:01:06 +0100
Subject: cam: sdl_sink: Add MJPG support to SDL sink

So we have at least two supported capturing pixel formats (although
many possible output pixel formats thanks to SDL conversion). MJPG
support only built in if SDL2_image is available, provides
decompression.

Signed-off-by: Eric Curtin <ecurtin@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/cam/meson.build          |  9 +++++++++
 src/cam/sdl_sink.cpp         |  8 ++++++++
 src/cam/sdl_texture_mjpg.cpp | 25 +++++++++++++++++++++++++
 src/cam/sdl_texture_mjpg.h   | 17 +++++++++++++++++
 4 files changed, 59 insertions(+)
 create mode 100644 src/cam/sdl_texture_mjpg.cpp
 create mode 100644 src/cam/sdl_texture_mjpg.h

(limited to 'src')

diff --git a/src/cam/meson.build b/src/cam/meson.build
index c17a971f..5957ce14 100644
--- a/src/cam/meson.build
+++ b/src/cam/meson.build
@@ -25,6 +25,7 @@ cam_cpp_args = []
 
 libdrm = dependency('libdrm', required : false)
 libsdl2 = dependency('SDL2', required : false)
+libsdl2_image = dependency('SDL2_image', required : false)
 
 if libdrm.found()
     cam_cpp_args += [ '-DHAVE_KMS' ]
@@ -41,6 +42,13 @@ if libsdl2.found()
         'sdl_texture.cpp',
         'sdl_texture_yuyv.cpp'
     ])
+
+    if libsdl2_image.found()
+        cam_cpp_args += ['-DHAVE_SDL_IMAGE']
+        cam_sources += files([
+            'sdl_texture_mjpg.cpp'
+        ])
+    endif
 endif
 
 cam  = executable('cam', cam_sources,
@@ -50,6 +58,7 @@ cam  = executable('cam', cam_sources,
                       libdrm,
                       libevent,
                       libsdl2,
+                      libsdl2_image,
                       libyaml,
                   ],
                   cpp_args : cam_cpp_args,
diff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp
index 4c74bce7..f8e3e95d 100644
--- a/src/cam/sdl_sink.cpp
+++ b/src/cam/sdl_sink.cpp
@@ -21,6 +21,9 @@
 
 #include "event_loop.h"
 #include "image.h"
+#ifdef HAVE_SDL_IMAGE
+#include "sdl_texture_mjpg.h"
+#endif
 #include "sdl_texture_yuyv.h"
 
 using namespace libcamera;
@@ -59,6 +62,11 @@ int SDLSink::configure(const libcamera::CameraConfiguration &config)
 	rect_.h = cfg.size.height;
 
 	switch (cfg.pixelFormat) {
+#ifdef HAVE_SDL_IMAGE
+	case libcamera::formats::MJPEG:
+		texture_ = std::make_unique<SDLTextureMJPG>(rect_);
+		break;
+#endif
 	case libcamera::formats::YUYV:
 		texture_ = std::make_unique<SDLTextureYUYV>(rect_);
 		break;
diff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp
new file mode 100644
index 00000000..69e99ad3
--- /dev/null
+++ b/src/cam/sdl_texture_mjpg.cpp
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2022, Ideas on Board Oy
+ *
+ * sdl_texture_mjpg.cpp - SDL Texture MJPG
+ */
+
+#include "sdl_texture_mjpg.h"
+
+#include <SDL2/SDL_image.h>
+
+using namespace libcamera;
+
+SDLTextureMJPG::SDLTextureMJPG(const SDL_Rect &rect)
+	: SDLTexture(rect, SDL_PIXELFORMAT_RGB24, 0)
+{
+}
+
+void SDLTextureMJPG::update(const Span<uint8_t> &data)
+{
+	SDL_RWops *bufferStream = SDL_RWFromMem(data.data(), data.size());
+	SDL_Surface *frame = IMG_Load_RW(bufferStream, 0);
+	SDL_UpdateTexture(ptr_, nullptr, frame->pixels, frame->pitch);
+	SDL_FreeSurface(frame);
+}
diff --git a/src/cam/sdl_texture_mjpg.h b/src/cam/sdl_texture_mjpg.h
new file mode 100644
index 00000000..b103f801
--- /dev/null
+++ b/src/cam/sdl_texture_mjpg.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2022, Ideas on Board Oy
+ *
+ * sdl_texture_mjpg.h - SDL Texture MJPG
+ */
+
+#pragma once
+
+#include "sdl_texture.h"
+
+class SDLTextureMJPG : public SDLTexture
+{
+public:
+	SDLTextureMJPG(const SDL_Rect &rect);
+	void update(const libcamera::Span<uint8_t> &data) override;
+};
-- 
cgit v1.2.1