diff options
Diffstat (limited to 'src/apps/cam/sdl_texture_mjpg.cpp')
-rw-r--r-- | src/apps/cam/sdl_texture_mjpg.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/apps/cam/sdl_texture_mjpg.cpp b/src/apps/cam/sdl_texture_mjpg.cpp new file mode 100644 index 00000000..da958e03 --- /dev/null +++ b/src/apps/cam/sdl_texture_mjpg.cpp @@ -0,0 +1,83 @@ +/* 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 <iostream> +#include <setjmp.h> +#include <stdio.h> + +#include <jpeglib.h> + +using namespace libcamera; + +struct JpegErrorManager : public jpeg_error_mgr { + 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[]>(stride_ * rect.h)) +{ +} + +int SDLTextureMJPG::decompress(Span<const 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 * stride_; + jpeg_read_scanlines(&cinfo, &rowptr, 1); + } + + jpeg_finish_decompress(&cinfo); + + jpeg_destroy_decompress(&cinfo); + + return 0; +} + +void SDLTextureMJPG::update(const std::vector<libcamera::Span<const uint8_t>> &data) +{ + decompress(data[0]); + SDL_UpdateTexture(ptr_, nullptr, rgb_.get(), stride_); +} |