[libcamera-devel] [PATCH] cam: sdl_sink: Use libjpeg over SDL2_image
Eric Curtin
ecurtin at redhat.com
Thu Jul 7 17:53:13 CEST 2022
We were using the libjpeg functionality of SDL2_image only, instead just
use libjpeg directly to reduce our dependancy count, it is a more
commonly available library.
Signed-off-by: Eric Curtin <ecurtin at redhat.com>
---
README.rst | 2 +-
src/cam/meson.build | 8 +++----
src/cam/sdl_sink.cpp | 4 ++--
src/cam/sdl_texture.h | 2 +-
src/cam/sdl_texture_mjpg.cpp | 43 +++++++++++++++++++++++++++++++-----
src/cam/sdl_texture_mjpg.h | 5 +++++
6 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/README.rst b/README.rst
index b9e72d81..5e8bc1cc 100644
--- a/README.rst
+++ b/README.rst
@@ -93,7 +93,7 @@ for cam: [optional]
- libdrm-dev: Enables the KMS sink
- libsdl2-dev: Enables the SDL sink
- - libsdl2-image-dev: Supports MJPEG on the SDL sink
+ - libjpeg-dev: Supports MJPEG on the SDL sink
for qcam: [optional]
qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev
diff --git a/src/cam/meson.build b/src/cam/meson.build
index 5957ce14..27cbd0de 100644
--- a/src/cam/meson.build
+++ b/src/cam/meson.build
@@ -25,7 +25,7 @@ cam_cpp_args = []
libdrm = dependency('libdrm', required : false)
libsdl2 = dependency('SDL2', required : false)
-libsdl2_image = dependency('SDL2_image', required : false)
+libjpeg = dependency('libjpeg', required : false)
if libdrm.found()
cam_cpp_args += [ '-DHAVE_KMS' ]
@@ -43,8 +43,8 @@ if libsdl2.found()
'sdl_texture_yuyv.cpp'
])
- if libsdl2_image.found()
- cam_cpp_args += ['-DHAVE_SDL_IMAGE']
+ if libjpeg.found()
+ cam_cpp_args += ['-DHAVE_LIBJPEG']
cam_sources += files([
'sdl_texture_mjpg.cpp'
])
@@ -58,7 +58,7 @@ cam = executable('cam', cam_sources,
libdrm,
libevent,
libsdl2,
- libsdl2_image,
+ libjpeg,
libyaml,
],
cpp_args : cam_cpp_args,
diff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp
index f8e3e95d..19fdfd6d 100644
--- a/src/cam/sdl_sink.cpp
+++ b/src/cam/sdl_sink.cpp
@@ -21,7 +21,7 @@
#include "event_loop.h"
#include "image.h"
-#ifdef HAVE_SDL_IMAGE
+#ifdef HAVE_LIBJPEG
#include "sdl_texture_mjpg.h"
#endif
#include "sdl_texture_yuyv.h"
@@ -62,7 +62,7 @@ int SDLSink::configure(const libcamera::CameraConfiguration &config)
rect_.h = cfg.size.height;
switch (cfg.pixelFormat) {
-#ifdef HAVE_SDL_IMAGE
+#ifdef HAVE_LIBJPEG
case libcamera::formats::MJPEG:
texture_ = std::make_unique<SDLTextureMJPG>(rect_);
break;
diff --git a/src/cam/sdl_texture.h b/src/cam/sdl_texture.h
index 90974798..42c906f2 100644
--- a/src/cam/sdl_texture.h
+++ b/src/cam/sdl_texture.h
@@ -25,5 +25,5 @@ protected:
SDL_Texture *ptr_;
const SDL_Rect rect_;
const SDL_PixelFormatEnum pixelFormat_;
- const int pitch_;
+ int pitch_;
};
diff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp
index 69e99ad3..232af673 100644
--- a/src/cam/sdl_texture_mjpg.cpp
+++ b/src/cam/sdl_texture_mjpg.cpp
@@ -7,19 +7,52 @@
#include "sdl_texture_mjpg.h"
-#include <SDL2/SDL_image.h>
+#include <jpeglib.h>
using namespace libcamera;
SDLTextureMJPG::SDLTextureMJPG(const SDL_Rect &rect)
: SDLTexture(rect, SDL_PIXELFORMAT_RGB24, 0)
{
+ pitch_ = rect_.w * 3;
+ rgbdata_ = (unsigned char *)malloc(pitch_ * rect_.h);
+}
+
+SDLTextureMJPG::~SDLTextureMJPG()
+{
+ free(rgbdata_);
+}
+
+void SDLTextureMJPG::decompress(const unsigned char *jpeg,
+ unsigned long jpeg_size)
+{
+ struct jpeg_error_mgr jerr;
+ struct jpeg_decompress_struct cinfo;
+ cinfo.err = jpeg_std_error(&jerr);
+
+ jpeg_create_decompress(&cinfo);
+
+ jpeg_mem_src(&cinfo, jpeg, jpeg_size);
+
+ jpeg_read_header(&cinfo, TRUE);
+
+ jpeg_start_decompress(&cinfo);
+
+ int row_stride = cinfo.output_width * cinfo.output_components;
+ unsigned char *buffer = (unsigned char *)malloc(row_stride);
+ for (int i = 0; cinfo.output_scanline < cinfo.output_height; ++i) {
+ jpeg_read_scanlines(&cinfo, &buffer, 1);
+ memcpy(rgbdata_ + i * pitch_, buffer, row_stride);
+ }
+
+ free(buffer);
+ jpeg_finish_decompress(&cinfo);
+
+ jpeg_destroy_decompress(&cinfo);
}
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);
+ decompress(data.data(), data.size());
+ SDL_UpdateTexture(ptr_, nullptr, rgbdata_, pitch_);
}
diff --git a/src/cam/sdl_texture_mjpg.h b/src/cam/sdl_texture_mjpg.h
index b103f801..73c7fb68 100644
--- a/src/cam/sdl_texture_mjpg.h
+++ b/src/cam/sdl_texture_mjpg.h
@@ -13,5 +13,10 @@ class SDLTextureMJPG : public SDLTexture
{
public:
SDLTextureMJPG(const SDL_Rect &rect);
+ virtual ~SDLTextureMJPG();
void update(const libcamera::Span<uint8_t> &data) override;
+
+private:
+ unsigned char *rgbdata_ = 0;
+ void decompress(const unsigned char *jpeg, unsigned long jpeg_size);
};
--
2.35.3
More information about the libcamera-devel
mailing list