Patch Detail
Show a patch.
GET /api/1.1/patches/16702/?format=api
{ "id": 16702, "url": "https://patchwork.libcamera.org/api/1.1/patches/16702/?format=api", "web_url": "https://patchwork.libcamera.org/patch/16702/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20220720130348.1337-2-laurent.pinchart@ideasonboard.com>", "date": "2022-07-20T13:03:47", "name": "[libcamera-devel,v5,1/2] cam: sdl_sink: Use libjpeg over SDL2_image", "commit_ref": "dc1f4a91dfefa9f86202ab148e05fb901b6e3e73", "pull_url": null, "state": "accepted", "archived": false, "hash": "3a41fb777f1cdd8287a8c9a04efaf698fb9e07e0", "submitter": { "id": 2, "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api", "name": "Laurent Pinchart", "email": "laurent.pinchart@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/16702/mbox/", "series": [ { "id": 3308, "url": "https://patchwork.libcamera.org/api/1.1/series/3308/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3308", "date": "2022-07-20T13:03:46", "name": "cam: Replace dependency on SDL2_image with libjpeg", "version": 5, "mbox": "https://patchwork.libcamera.org/series/3308/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/16702/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/16702/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 1ED70BD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 20 Jul 2022 13:04:30 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 581CD63311;\n\tWed, 20 Jul 2022 15:04:29 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C31A860489\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 20 Jul 2022 15:04:26 +0200 (CEST)", "from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 61F7488F;\n\tWed, 20 Jul 2022 15:04:26 +0200 (CEST)" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1658322269;\n\tbh=sI4UlJbLvGIZhicBLEjHbefgyOesG1ClvDSiJl0g0kg=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=3vy9RYit1AJxAEK3XV9EOMTqaNG8+4pHdMD20YhA25fgSCAulOeBY6ZBvSjKhLIlu\n\tjFRMkeN7CxQivlNrwX/mQG/TZDydwPZJm2o41ofmB/M6HInbJRs6/hr0aI2DA48wpc\n\t2kx5xvHIaNzGY7ypGAzdIxfV9QbL/5bRsfRsqaBgsjY74hYjXa6yKaswp4K992iGhs\n\tgM0f1gp7SFsmj9NOl3/ZD7cC+LGEGZE9eGeiRrGhOUjGT/wK0zpr37GwnKMUGdkudB\n\tsmfz57vDdOQsHO3uEnLCUcKBKMGch8OUD+P7RncFnQCVXOjt3gRxGJ0cyX04oFMFcf\n\tKvSkGCePPWg7A==", "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1658322266;\n\tbh=sI4UlJbLvGIZhicBLEjHbefgyOesG1ClvDSiJl0g0kg=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=QjvvZb1ZpIy3mus6DmhG7hyteMK+fALcj7EHo2we7GgdMsCmizKKAKGp5GsxuTrFc\n\ty3H9c2MYDgU4GKWZ4jTAacfgyNeW3+ZVO4fm0RjYSgyZwvdJgMeF2PQ+Oy0jwNdWwn\n\tqwlEwM6fC61tInM7H5HtKt76Uy+JqQz7sLhEdcrs=" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"QjvvZb1Z\"; dkim-atps=neutral", "To": "libcamera-devel@lists.libcamera.org", "Date": "Wed, 20 Jul 2022 16:03:47 +0300", "Message-Id": "<20220720130348.1337-2-laurent.pinchart@ideasonboard.com>", "X-Mailer": "git-send-email 2.35.1", "In-Reply-To": "<20220720130348.1337-1-laurent.pinchart@ideasonboard.com>", "References": "<20220720130348.1337-1-laurent.pinchart@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v5 1/2] cam: sdl_sink: Use libjpeg over\n\tSDL2_image", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "From": "Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>", "Reply-To": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "From: Eric Curtin <ecurtin@redhat.com>\n\nWe were using the libjpeg functionality of SDL2_image only, instead just\nuse libjpeg directly to reduce our dependancy count, it is a more\ncommonly available library.\n\nSigned-off-by: Eric Curtin <ecurtin@redhat.com>\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\nChanges since v4:\n\n- Move JpegErrorManager to sdl_texture_mjpg.cpp\n- Make JpegErrorManager inherit from jpeg_error_mgr\n- Define errorExit and outputMessage as member functions\n---\n README.rst | 2 +-\n src/cam/meson.build | 8 ++---\n src/cam/sdl_sink.cpp | 4 +--\n src/cam/sdl_texture_mjpg.cpp | 70 ++++++++++++++++++++++++++++++++----\n src/cam/sdl_texture_mjpg.h | 6 ++++\n 5 files changed, 77 insertions(+), 13 deletions(-)", "diff": "diff --git a/README.rst b/README.rst\nindex b9e72d81b90c..47b914f02260 100644\n--- a/README.rst\n+++ b/README.rst\n@@ -92,8 +92,8 @@ for cam: [optional]\n tool:\n \n - libdrm-dev: Enables the KMS sink\n+ - libjpeg-dev: Enables MJPEG on the SDL sink\n - libsdl2-dev: Enables the SDL sink\n- - libsdl2-image-dev: Supports MJPEG on the SDL sink\n \n for qcam: [optional]\n qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev\ndiff --git a/src/cam/meson.build b/src/cam/meson.build\nindex 5957ce140391..4dfa7b22aea9 100644\n--- a/src/cam/meson.build\n+++ b/src/cam/meson.build\n@@ -24,8 +24,8 @@ cam_sources = files([\n cam_cpp_args = []\n \n libdrm = dependency('libdrm', required : false)\n+libjpeg = dependency('libjpeg', required : false)\n libsdl2 = dependency('SDL2', required : false)\n-libsdl2_image = dependency('SDL2_image', required : false)\n \n if libdrm.found()\n cam_cpp_args += [ '-DHAVE_KMS' ]\n@@ -43,8 +43,8 @@ if libsdl2.found()\n 'sdl_texture_yuyv.cpp'\n ])\n \n- if libsdl2_image.found()\n- cam_cpp_args += ['-DHAVE_SDL_IMAGE']\n+ if libjpeg.found()\n+ cam_cpp_args += ['-DHAVE_LIBJPEG']\n cam_sources += files([\n 'sdl_texture_mjpg.cpp'\n ])\n@@ -57,8 +57,8 @@ cam = executable('cam', cam_sources,\n libcamera_public,\n libdrm,\n libevent,\n+ libjpeg,\n libsdl2,\n- libsdl2_image,\n libyaml,\n ],\n cpp_args : cam_cpp_args,\ndiff --git a/src/cam/sdl_sink.cpp b/src/cam/sdl_sink.cpp\nindex f8e3e95dd392..19fdfd6dced5 100644\n--- a/src/cam/sdl_sink.cpp\n+++ b/src/cam/sdl_sink.cpp\n@@ -21,7 +21,7 @@\n \n #include \"event_loop.h\"\n #include \"image.h\"\n-#ifdef HAVE_SDL_IMAGE\n+#ifdef HAVE_LIBJPEG\n #include \"sdl_texture_mjpg.h\"\n #endif\n #include \"sdl_texture_yuyv.h\"\n@@ -62,7 +62,7 @@ int SDLSink::configure(const libcamera::CameraConfiguration &config)\n \trect_.h = cfg.size.height;\n \n \tswitch (cfg.pixelFormat) {\n-#ifdef HAVE_SDL_IMAGE\n+#ifdef HAVE_LIBJPEG\n \tcase libcamera::formats::MJPEG:\n \t\ttexture_ = std::make_unique<SDLTextureMJPG>(rect_);\n \t\tbreak;\ndiff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp\nindex 69e99ad35219..7eddc00cd210 100644\n--- a/src/cam/sdl_texture_mjpg.cpp\n+++ b/src/cam/sdl_texture_mjpg.cpp\n@@ -7,19 +7,77 @@\n \n #include \"sdl_texture_mjpg.h\"\n \n-#include <SDL2/SDL_image.h>\n+#include <iostream>\n+#include <setjmp.h>\n+#include <stdio.h>\n+\n+#include <jpeglib.h>\n \n using namespace libcamera;\n \n+struct JpegErrorManager : public jpeg_error_mgr {\n+\tJpegErrorManager()\n+\t{\n+\t\tjpeg_std_error(this);\n+\t\terror_exit = errorExit;\n+\t\toutput_message = outputMessage;\n+\t}\n+\n+\tstatic void errorExit(j_common_ptr cinfo)\n+\t{\n+\t\tJpegErrorManager *self =\n+\t\t\tstatic_cast<JpegErrorManager *>(cinfo->err);\n+\t\tlongjmp(self->escape_, 1);\n+\t}\n+\n+\tstatic void outputMessage([[maybe_unused]] j_common_ptr cinfo)\n+\t{\n+\t}\n+\n+\tjmp_buf escape_;\n+};\n+\n SDLTextureMJPG::SDLTextureMJPG(const SDL_Rect &rect)\n-\t: SDLTexture(rect, SDL_PIXELFORMAT_RGB24, 0)\n+\t: SDLTexture(rect, SDL_PIXELFORMAT_RGB24, rect.w * 3),\n+\t rgb_(std::make_unique<unsigned char[]>(pitch_ * rect.h))\n {\n }\n \n+int SDLTextureMJPG::decompress(const Span<uint8_t> &data)\n+{\n+\tstruct jpeg_decompress_struct cinfo;\n+\n+\tJpegErrorManager errorManager;\n+\tif (setjmp(errorManager.escape_)) {\n+\t\t/* libjpeg found an error */\n+\t\tjpeg_destroy_decompress(&cinfo);\n+\t\tstd::cerr << \"JPEG decompression error\" << std::endl;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tcinfo.err = &errorManager;\n+\tjpeg_create_decompress(&cinfo);\n+\n+\tjpeg_mem_src(&cinfo, data.data(), data.size());\n+\n+\tjpeg_read_header(&cinfo, TRUE);\n+\n+\tjpeg_start_decompress(&cinfo);\n+\n+\tfor (int i = 0; cinfo.output_scanline < cinfo.output_height; ++i) {\n+\t\tJSAMPROW rowptr = rgb_.get() + i * pitch_;\n+\t\tjpeg_read_scanlines(&cinfo, &rowptr, 1);\n+\t}\n+\n+\tjpeg_finish_decompress(&cinfo);\n+\n+\tjpeg_destroy_decompress(&cinfo);\n+\n+\treturn 0;\n+}\n+\n void SDLTextureMJPG::update(const Span<uint8_t> &data)\n {\n-\tSDL_RWops *bufferStream = SDL_RWFromMem(data.data(), data.size());\n-\tSDL_Surface *frame = IMG_Load_RW(bufferStream, 0);\n-\tSDL_UpdateTexture(ptr_, nullptr, frame->pixels, frame->pitch);\n-\tSDL_FreeSurface(frame);\n+\tdecompress(data);\n+\tSDL_UpdateTexture(ptr_, nullptr, rgb_.get(), pitch_);\n }\ndiff --git a/src/cam/sdl_texture_mjpg.h b/src/cam/sdl_texture_mjpg.h\nindex b103f801176d..328c45a913c5 100644\n--- a/src/cam/sdl_texture_mjpg.h\n+++ b/src/cam/sdl_texture_mjpg.h\n@@ -13,5 +13,11 @@ class SDLTextureMJPG : public SDLTexture\n {\n public:\n \tSDLTextureMJPG(const SDL_Rect &rect);\n+\n \tvoid update(const libcamera::Span<uint8_t> &data) override;\n+\n+private:\n+\tint decompress(const libcamera::Span<uint8_t> &data);\n+\n+\tstd::unique_ptr<unsigned char[]> rgb_;\n };\n", "prefixes": [ "libcamera-devel", "v5", "1/2" ] }