cam: sdl_sink: Use libjpeg over SDL2_image
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@redhat.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
parent
c13f86704b
commit
dc1f4a91df
5 changed files with 77 additions and 13 deletions
|
@ -86,8 +86,8 @@ for cam: [optional]
|
||||||
tool:
|
tool:
|
||||||
|
|
||||||
- libdrm-dev: Enables the KMS sink
|
- libdrm-dev: Enables the KMS sink
|
||||||
|
- libjpeg-dev: Enables MJPEG on the SDL sink
|
||||||
- libsdl2-dev: Enables the SDL sink
|
- libsdl2-dev: Enables the SDL sink
|
||||||
- libsdl2-image-dev: Supports MJPEG on the SDL sink
|
|
||||||
|
|
||||||
for qcam: [optional]
|
for qcam: [optional]
|
||||||
qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev
|
qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev
|
||||||
|
|
|
@ -24,8 +24,8 @@ cam_sources = files([
|
||||||
cam_cpp_args = []
|
cam_cpp_args = []
|
||||||
|
|
||||||
libdrm = dependency('libdrm', required : false)
|
libdrm = dependency('libdrm', required : false)
|
||||||
|
libjpeg = dependency('libjpeg', required : false)
|
||||||
libsdl2 = dependency('SDL2', required : false)
|
libsdl2 = dependency('SDL2', required : false)
|
||||||
libsdl2_image = dependency('SDL2_image', required : false)
|
|
||||||
|
|
||||||
if libdrm.found()
|
if libdrm.found()
|
||||||
cam_cpp_args += [ '-DHAVE_KMS' ]
|
cam_cpp_args += [ '-DHAVE_KMS' ]
|
||||||
|
@ -43,8 +43,8 @@ if libsdl2.found()
|
||||||
'sdl_texture_yuyv.cpp'
|
'sdl_texture_yuyv.cpp'
|
||||||
])
|
])
|
||||||
|
|
||||||
if libsdl2_image.found()
|
if libjpeg.found()
|
||||||
cam_cpp_args += ['-DHAVE_SDL_IMAGE']
|
cam_cpp_args += ['-DHAVE_LIBJPEG']
|
||||||
cam_sources += files([
|
cam_sources += files([
|
||||||
'sdl_texture_mjpg.cpp'
|
'sdl_texture_mjpg.cpp'
|
||||||
])
|
])
|
||||||
|
@ -57,8 +57,8 @@ cam = executable('cam', cam_sources,
|
||||||
libcamera_public,
|
libcamera_public,
|
||||||
libdrm,
|
libdrm,
|
||||||
libevent,
|
libevent,
|
||||||
|
libjpeg,
|
||||||
libsdl2,
|
libsdl2,
|
||||||
libsdl2_image,
|
|
||||||
libyaml,
|
libyaml,
|
||||||
],
|
],
|
||||||
cpp_args : cam_cpp_args,
|
cpp_args : cam_cpp_args,
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "event_loop.h"
|
#include "event_loop.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#ifdef HAVE_SDL_IMAGE
|
#ifdef HAVE_LIBJPEG
|
||||||
#include "sdl_texture_mjpg.h"
|
#include "sdl_texture_mjpg.h"
|
||||||
#endif
|
#endif
|
||||||
#include "sdl_texture_yuyv.h"
|
#include "sdl_texture_yuyv.h"
|
||||||
|
@ -62,7 +62,7 @@ int SDLSink::configure(const libcamera::CameraConfiguration &config)
|
||||||
rect_.h = cfg.size.height;
|
rect_.h = cfg.size.height;
|
||||||
|
|
||||||
switch (cfg.pixelFormat) {
|
switch (cfg.pixelFormat) {
|
||||||
#ifdef HAVE_SDL_IMAGE
|
#ifdef HAVE_LIBJPEG
|
||||||
case libcamera::formats::MJPEG:
|
case libcamera::formats::MJPEG:
|
||||||
texture_ = std::make_unique<SDLTextureMJPG>(rect_);
|
texture_ = std::make_unique<SDLTextureMJPG>(rect_);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -7,19 +7,77 @@
|
||||||
|
|
||||||
#include "sdl_texture_mjpg.h"
|
#include "sdl_texture_mjpg.h"
|
||||||
|
|
||||||
#include <SDL2/SDL_image.h>
|
#include <iostream>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <jpeglib.h>
|
||||||
|
|
||||||
using namespace libcamera;
|
using namespace libcamera;
|
||||||
|
|
||||||
SDLTextureMJPG::SDLTextureMJPG(const SDL_Rect &rect)
|
struct JpegErrorManager : public jpeg_error_mgr {
|
||||||
: SDLTexture(rect, SDL_PIXELFORMAT_RGB24, 0)
|
JpegErrorManager()
|
||||||
{
|
{
|
||||||
|
jpeg_std_error(this);
|
||||||
|
error_exit = errorExit;
|
||||||
|
output_message = outputMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void errorExit(j_common_ptr cinfo)
|
||||||
|
{
|
||||||
|
JpegErrorManager *self =
|
||||||
|
static_cast<JpegErrorManager *>(cinfo->err);
|
||||||
|
longjmp(self->escape_, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void outputMessage([[maybe_unused]] j_common_ptr cinfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
jmp_buf escape_;
|
||||||
|
};
|
||||||
|
|
||||||
|
SDLTextureMJPG::SDLTextureMJPG(const SDL_Rect &rect)
|
||||||
|
: SDLTexture(rect, SDL_PIXELFORMAT_RGB24, rect.w * 3),
|
||||||
|
rgb_(std::make_unique<unsigned char[]>(pitch_ * rect.h))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SDLTextureMJPG::decompress(const Span<uint8_t> &data)
|
||||||
|
{
|
||||||
|
struct jpeg_decompress_struct cinfo;
|
||||||
|
|
||||||
|
JpegErrorManager errorManager;
|
||||||
|
if (setjmp(errorManager.escape_)) {
|
||||||
|
/* libjpeg found an error */
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
std::cerr << "JPEG decompression error" << std::endl;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cinfo.err = &errorManager;
|
||||||
|
jpeg_create_decompress(&cinfo);
|
||||||
|
|
||||||
|
jpeg_mem_src(&cinfo, data.data(), data.size());
|
||||||
|
|
||||||
|
jpeg_read_header(&cinfo, TRUE);
|
||||||
|
|
||||||
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
|
for (int i = 0; cinfo.output_scanline < cinfo.output_height; ++i) {
|
||||||
|
JSAMPROW rowptr = rgb_.get() + i * pitch_;
|
||||||
|
jpeg_read_scanlines(&cinfo, &rowptr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
jpeg_finish_decompress(&cinfo);
|
||||||
|
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLTextureMJPG::update(const Span<uint8_t> &data)
|
void SDLTextureMJPG::update(const Span<uint8_t> &data)
|
||||||
{
|
{
|
||||||
SDL_RWops *bufferStream = SDL_RWFromMem(data.data(), data.size());
|
decompress(data);
|
||||||
SDL_Surface *frame = IMG_Load_RW(bufferStream, 0);
|
SDL_UpdateTexture(ptr_, nullptr, rgb_.get(), pitch_);
|
||||||
SDL_UpdateTexture(ptr_, nullptr, frame->pixels, frame->pitch);
|
|
||||||
SDL_FreeSurface(frame);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,5 +13,11 @@ class SDLTextureMJPG : public SDLTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SDLTextureMJPG(const SDL_Rect &rect);
|
SDLTextureMJPG(const SDL_Rect &rect);
|
||||||
|
|
||||||
void update(const libcamera::Span<uint8_t> &data) override;
|
void update(const libcamera::Span<uint8_t> &data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int decompress(const libcamera::Span<uint8_t> &data);
|
||||||
|
|
||||||
|
std::unique_ptr<unsigned char[]> rgb_;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue