From 6bfb571142fbe2262077a890425a258ee63b2843 Mon Sep 17 00:00:00 2001 From: Gyorgy Sarvari Date: Sat, 13 Sep 2025 18:55:50 +0200 Subject: [PATCH] libcamera-apps: upgrade 1.4.2 -> 1.9.0 Quite a few things have changed lately, eaiser to browse the release page: https://github.com/raspberrypi/rpicam-apps/releases The main reason for the update it improved build-compatibiltiy with tensorflow-lite: it doesn't need cmake/pkg-config file anymore to find the library, so it should be easier to integrate it with meta-tensorflow. Signed-off-by: Gyorgy Sarvari --- ...ompressed-pixel-formats-when-saving-.patch | 271 ------------------ .../libcamera-apps/add-missing-header.patch | 24 ++ .../libcamera-apps/libcamera-apps_1.9.0.bb | 47 +++ .../libcamera-apps/libcamera-apps_git.bb | 44 --- 4 files changed, 71 insertions(+), 315 deletions(-) delete mode 100644 dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps/0002-Revert-Support-compressed-pixel-formats-when-saving-.patch create mode 100644 dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps/add-missing-header.patch create mode 100644 dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_1.9.0.bb delete mode 100644 dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_git.bb diff --git a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps/0002-Revert-Support-compressed-pixel-formats-when-saving-.patch b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps/0002-Revert-Support-compressed-pixel-formats-when-saving-.patch deleted file mode 100644 index c965b2c..0000000 --- a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps/0002-Revert-Support-compressed-pixel-formats-when-saving-.patch +++ /dev/null @@ -1,271 +0,0 @@ -From 500f1e9eaeca29b255d0364e1383d70ade1d1177 Mon Sep 17 00:00:00 2001 -From: Martin Jansa -Date: Tue, 30 Jan 2024 12:02:09 +0000 -Subject: [PATCH] Revert "Support compressed pixel formats when saving DNGs" - -This reverts commit a85aed7603a0b69a6685d3f81ee860246d5b1621. - -This requires rpi specific fork of libcamera to provide e.g. -formats::RGGB16_PISP_COMP1 -added in: -https://github.com/raspberrypi/libcamera/commit/fb3cb844f2117f30d3eeece99d6ce4d02624e492 -but not included in libcamera from meta-oe: -https://git.openembedded.org/meta-openembedded/commit/?id=711c6fbce39df685225bca081c5f42bae2de658b - -See https://github.com/raspberrypi/rpicam-apps/issues/627 - -Upstream-Status: Pending ---- - image/dng.cpp | 205 ++++++++------------------------------------------ - 1 file changed, 33 insertions(+), 172 deletions(-) - -diff --git a/image/dng.cpp b/image/dng.cpp -index 7692f92..fc10439 100644 ---- a/image/dng.cpp -+++ b/image/dng.cpp -@@ -33,47 +33,40 @@ struct BayerFormat - int bits; - char const *order; - bool packed; -- bool compressed; - }; - - static const std::map bayer_formats = - { -- { formats::SRGGB10_CSI2P, { "RGGB-10", 10, TIFF_RGGB, true, false } }, -- { formats::SGRBG10_CSI2P, { "GRBG-10", 10, TIFF_GRBG, true, false } }, -- { formats::SBGGR10_CSI2P, { "BGGR-10", 10, TIFF_BGGR, true, false } }, -- { formats::SGBRG10_CSI2P, { "GBRG-10", 10, TIFF_GBRG, true, false } }, -- -- { formats::SRGGB10, { "RGGB-10", 10, TIFF_RGGB, false, false } }, -- { formats::SGRBG10, { "GRBG-10", 10, TIFF_GRBG, false, false } }, -- { formats::SBGGR10, { "BGGR-10", 10, TIFF_BGGR, false, false } }, -- { formats::SGBRG10, { "GBRG-10", 10, TIFF_GBRG, false, false } }, -- -- { formats::SRGGB12_CSI2P, { "RGGB-12", 12, TIFF_RGGB, true, false } }, -- { formats::SGRBG12_CSI2P, { "GRBG-12", 12, TIFF_GRBG, true, false } }, -- { formats::SBGGR12_CSI2P, { "BGGR-12", 12, TIFF_BGGR, true, false } }, -- { formats::SGBRG12_CSI2P, { "GBRG-12", 12, TIFF_GBRG, true, false } }, -- -- { formats::SRGGB12, { "RGGB-12", 12, TIFF_RGGB, false, false } }, -- { formats::SGRBG12, { "GRBG-12", 12, TIFF_GRBG, false, false } }, -- { formats::SBGGR12, { "BGGR-12", 12, TIFF_BGGR, false, false } }, -- { formats::SGBRG12, { "GBRG-12", 12, TIFF_GBRG, false, false } }, -- -- { formats::SRGGB16, { "RGGB-16", 16, TIFF_RGGB, false, false } }, -- { formats::SGRBG16, { "GRBG-16", 16, TIFF_GRBG, false, false } }, -- { formats::SBGGR16, { "BGGR-16", 16, TIFF_BGGR, false, false } }, -- { formats::SGBRG16, { "GBRG-16", 16, TIFF_GBRG, false, false } }, -- -- { formats::R10_CSI2P, { "BGGR-10", 10, TIFF_BGGR, true, false } }, -- { formats::R10, { "BGGR-10", 10, TIFF_BGGR, false, false } }, -+ { formats::SRGGB10_CSI2P, { "RGGB-10", 10, TIFF_RGGB, true } }, -+ { formats::SGRBG10_CSI2P, { "GRBG-10", 10, TIFF_GRBG, true } }, -+ { formats::SBGGR10_CSI2P, { "BGGR-10", 10, TIFF_BGGR, true } }, -+ { formats::SGBRG10_CSI2P, { "GBRG-10", 10, TIFF_GBRG, true } }, -+ -+ { formats::SRGGB10, { "RGGB-10", 10, TIFF_RGGB, false } }, -+ { formats::SGRBG10, { "GRBG-10", 10, TIFF_GRBG, false } }, -+ { formats::SBGGR10, { "BGGR-10", 10, TIFF_BGGR, false } }, -+ { formats::SGBRG10, { "GBRG-10", 10, TIFF_GBRG, false } }, -+ -+ { formats::SRGGB12_CSI2P, { "RGGB-12", 12, TIFF_RGGB, true } }, -+ { formats::SGRBG12_CSI2P, { "GRBG-12", 12, TIFF_GRBG, true } }, -+ { formats::SBGGR12_CSI2P, { "BGGR-12", 12, TIFF_BGGR, true } }, -+ { formats::SGBRG12_CSI2P, { "GBRG-12", 12, TIFF_GBRG, true } }, -+ -+ { formats::SRGGB12, { "RGGB-12", 12, TIFF_RGGB, false } }, -+ { formats::SGRBG12, { "GRBG-12", 12, TIFF_GRBG, false } }, -+ { formats::SBGGR12, { "BGGR-12", 12, TIFF_BGGR, false } }, -+ { formats::SGBRG12, { "GBRG-12", 12, TIFF_GBRG, false } }, -+ -+ { formats::SRGGB16, { "RGGB-16", 16, TIFF_RGGB, false } }, -+ { formats::SGRBG16, { "GRBG-16", 16, TIFF_GRBG, false } }, -+ { formats::SBGGR16, { "BGGR-16", 16, TIFF_BGGR, false } }, -+ { formats::SGBRG16, { "GBRG-16", 16, TIFF_GBRG, false } }, -+ -+ { formats::R10_CSI2P, { "BGGR-10", 10, TIFF_BGGR, true } }, -+ { formats::R10, { "BGGR-10", 10, TIFF_BGGR, false } }, - // Currently not in the main libcamera branch - //{ formats::R12_CSI2P, { "BGGR-12", 12, TIFF_BGGR, true } }, -- { formats::R12, { "BGGR-12", 12, TIFF_BGGR, false, false } }, -- -- /* PiSP compressed formats. */ -- { formats::RGGB16_PISP_COMP1, { "RGGB-16-PISP", 16, TIFF_RGGB, false, true } }, -- { formats::GRBG16_PISP_COMP1, { "GRBG-16-PISP", 16, TIFF_GRBG, false, true } }, -- { formats::GBRG16_PISP_COMP1, { "GBRG-16-PISP", 16, TIFF_GBRG, false, true } }, -- { formats::BGGR16_PISP_COMP1, { "BGGR-16-PISP", 16, TIFF_BGGR, false, true } }, -+ { formats::R12, { "BGGR-12", 12, TIFF_BGGR, false } }, - }; - - static void unpack_10bit(uint8_t const *src, StreamInfo const &info, uint16_t *dest) -@@ -124,129 +117,6 @@ static void unpack_16bit(uint8_t const *src, StreamInfo const &info, uint16_t *d - } - } - --// We always use these compression parameters. --#define COMPRESS_OFFSET 2048 --#define COMPRESS_MODE 1 -- --static uint16_t postprocess(uint16_t a) --{ -- if (COMPRESS_MODE & 2) -- { -- if (COMPRESS_MODE == 3 && a < 0x4000) -- a = a >> 2; -- else if (a < 0x1000) -- a = a >> 4; -- else if (a < 0x1800) -- a = (a - 0x800) >> 3; -- else if (a < 0x3000) -- a = (a - 0x1000) >> 2; -- else if (a < 0x6000) -- a = (a - 0x2000) >> 1; -- else if (a < 0xC000) -- a = (a - 0x4000); -- else -- a = 2 * (a - 0x8000); -- } -- -- return std::min(0xFFFF, a + COMPRESS_OFFSET); --} -- --static uint16_t dequantize(uint16_t q, int qmode) --{ -- switch (qmode) -- { -- case 0: -- return (q < 320) ? 16 * q : 32 * (q - 160); -- -- case 1: -- return 64 * q; -- -- case 2: -- return 128 * q; -- -- default: -- return (q < 94) ? 256 * q : std::min(0xFFFF, 512 * (q - 47)); -- } --} -- --static void subBlockFunction(uint16_t *d, uint32_t w) --{ -- int q[4]; -- -- int qmode = (w & 3); -- if (qmode < 3) -- { -- int field0 = (w >> 2) & 511; -- int field1 = (w >> 11) & 127; -- int field2 = (w >> 18) & 127; -- int field3 = (w >> 25) & 127; -- if (qmode == 2 && field0 >= 384) -- { -- q[1] = field0; -- q[2] = field1 + 384; -- } -- else -- { -- q[1] = (field1 >= 64) ? field0 : field0 + 64 - field1; -- q[2] = (field1 >= 64) ? field0 + field1 - 64 : field0; -- } -- int p1 = std::max(0, q[1] - 64); -- if (qmode == 2) -- p1 = std::min(384, p1); -- int p2 = std::max(0, q[2] - 64); -- if (qmode == 2) -- p2 = std::min(384, p2); -- q[0] = p1 + field2; -- q[3] = p2 + field3; -- } -- else -- { -- int pack0 = (w >> 2) & 32767; -- int pack1 = (w >> 17) & 32767; -- q[0] = (pack0 & 15) + 16 * ((pack0 >> 8) / 11); -- q[1] = (pack0 >> 4) % 176; -- q[2] = (pack1 & 15) + 16 * ((pack1 >> 8) / 11); -- q[3] = (pack1 >> 4) % 176; -- } -- -- d[0] = dequantize(q[0], qmode); -- d[2] = dequantize(q[1], qmode); -- d[4] = dequantize(q[2], qmode); -- d[6] = dequantize(q[3], qmode); --} -- --static void uncompress(uint8_t const *src, StreamInfo const &info, uint16_t *dest) --{ -- // In all cases, the *decompressed* image must be a multiple of 8 columns wide. -- unsigned int buf_stride_pixels = (info.width + 7) & ~7; -- for (unsigned int y = 0; y < info.height; ++y) -- { -- uint16_t *dp = dest + y * buf_stride_pixels; -- uint8_t const *sp = src + y * info.stride; -- -- for (unsigned int x = 0; x < info.width; x+=8) -- { -- if (COMPRESS_MODE & 1) -- { -- uint32_t w0 = 0, w1 = 0; -- for (int b = 0; b < 4; ++b) -- w0 |= (*sp++) << (b * 8); -- for (int b = 0; b < 4; ++b) -- w1 |= (*sp++) << (b * 8); -- subBlockFunction(dp, w0); -- subBlockFunction(dp + 1, w1); -- for (int i = 0; i < 8; ++i, ++dp) -- *dp = postprocess(*dp); -- } -- else -- { -- for (int i = 0; i < 8; ++i) -- *dp++ = postprocess((*sp++) << 8); -- } -- } -- } --} -- - struct Matrix - { - Matrix(float m0, float m1, float m2, -@@ -307,16 +177,8 @@ void dng_save(std::vector> const &mem, StreamInfo const - BayerFormat const &bayer_format = it->second; - LOG(1, "Bayer format is " << bayer_format.name); - -- // Decompression will require a buffer that's 8 pixels aligned. -- unsigned int buf_stride_pixels = info.width; -- unsigned int buf_stride_pixels_padded = (buf_stride_pixels + 7) & ~7; -- std::vector buf(buf_stride_pixels_padded * info.height); -- if (bayer_format.compressed) -- { -- uncompress(mem[0].data(), info, &buf[0]); -- buf_stride_pixels = buf_stride_pixels_padded; -- } -- else if (bayer_format.packed) -+ std::vector buf(info.width * info.height); -+ if (bayer_format.packed) - { - switch (bayer_format.bits) - { -@@ -444,9 +306,8 @@ void dng_save(std::vector> const &mem, StreamInfo const - { - for (unsigned int x = 0; x < (info.width >> 4); x++) - { -- unsigned int off = (y * buf_stride_pixels + x) << 4; -- uint32_t grey = -- buf[off] + buf[off + 1] + buf[off + buf_stride_pixels] + buf[off + buf_stride_pixels + 1]; -+ unsigned int off = (y * info.width + x) << 4; -+ uint32_t grey = buf[off] + buf[off + 1] + buf[off + info.width] + buf[off + info.width + 1]; - grey = (grey << 14) >> bayer_format.bits; - grey = sqrt((double)grey); // simple "gamma correction" - thumb_buf[3 * x] = thumb_buf[3 * x + 1] = thumb_buf[3 * x + 2] = grey; -@@ -478,7 +339,7 @@ void dng_save(std::vector> const &mem, StreamInfo const - - for (unsigned int y = 0; y < info.height; y++) - { -- if (TIFFWriteScanline(tif, &buf[buf_stride_pixels * y], y, 0) != 1) -+ if (TIFFWriteScanline(tif, &buf[info.width * y], y, 0) != 1) - throw std::runtime_error("error writing DNG image data"); - } - diff --git a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps/add-missing-header.patch b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps/add-missing-header.patch new file mode 100644 index 0000000..7d41e36 --- /dev/null +++ b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps/add-missing-header.patch @@ -0,0 +1,24 @@ +add missing header + +When compiling with gcc15, compiliation fails with the following error: + +| In file included from ../sources/libcamera-apps-1.9.0/post_processing_stages/segmentation_tf_stage.cpp:8: +| ../sources/libcamera-apps-1.9.0/post_processing_stages/segmentation.hpp:15:82: error: 'uint8_t' was not declared in this scope +| 15 | Segmentation(int w, int h, std::vector l, const std::vector &s) + +To avoid it, add the cstdint header to the offending file. + +Upstream-Status: Submitted [https://github.com/raspberrypi/rpicam-apps/pull/861] +Signed-off-by: Gyorgy Sarvari +diff --git a/post_processing_stages/segmentation.hpp b/post_processing_stages/segmentation.hpp +index ac87228..82d7939 100644 +--- a/post_processing_stages/segmentation.hpp ++++ b/post_processing_stages/segmentation.hpp +@@ -7,6 +7,7 @@ + + #pragma once + ++#include + #include + #include + diff --git a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_1.9.0.bb b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_1.9.0.bb new file mode 100644 index 0000000..ce94975 --- /dev/null +++ b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_1.9.0.bb @@ -0,0 +1,47 @@ +SUMMARY = "A suite of libcamera-based apps" +DESCRIPTION = "This is a small suite of libcamera-based apps that aim to \ +copy the functionality of the existing \"raspicam\" apps." +HOMEPAGE = "https://github.com/raspberrypi/rpicam-apps" +SECTION = "console/utils" + +LICENSE = "BSD-2-Clause" +LIC_FILES_CHKSUM = "file://license.txt;md5=a0013d1b383d72ba4bdc5b750e7d1d77" + +SRC_URI = "\ + git://github.com/raspberrypi/rpicam-apps.git;protocol=https;branch=main \ + file://0001-utils-version.py-use-usr-bin-env-in-shebang.patch \ + file://add-missing-header.patch \ +" + +SRCREV = "eca9928b76c106141667288f1cef935d02ba59b3" + +PROVIDES += "rpicam-apps" + +DEPENDS = "libcamera libexif jpeg tiff libpng boost" + +PACKAGECONFIG ??= "drm" +PACKAGECONFIG[libav] = "-Denable_libav=enabled, -Denable_libav=disabled, libav" +PACKAGECONFIG[drm] = "-Denable_drm=enabled, -Denable_drm=disabled, libdrm" +PACKAGECONFIG[egl] = "-Denable_egl=enabled, -Denable_egl=disabled, virtual/egl" +PACKAGECONFIG[qt] = "-Denable_qt=enabled, -Denable_qt=disabled, qtbase" +PACKAGECONFIG[opencv] = "-Denable_opencv=enabled, -Denable_opencv=disabled, opencv" +PACKAGECONFIG[tflite] = "-Denable_tflite=enabled, -Denable_tflite=disabled, tensorflow-lite" + +inherit meson pkgconfig + +NEON_FLAGS = "" +NEON_FLAGS:aarch64 = "-Dneon_flags=arm64" +NEON_FLAGS:arm:raspberrypi3 = "-Dneon_flags=armv8-neon" +NEON_FLAGS:arm:raspberrypi4 = "-Dneon_flags=armv8-neon" +EXTRA_OEMESON += "${NEON_FLAGS}" + +# QA Issue: /usr/bin/camera-bug-report contained in package libcamera-apps requires /usr/bin/python3 +# QA Issue: File /usr/lib/pkgconfig/rpicam_app.pc in package libcamera-apps-dev contains reference to TMPDIR +do_install:append() { + rm -v ${D}/${bindir}/camera-bug-report + sed -i "s,${RECIPE_SYSROOT}${libdir},$\{libdir},g" ${D}${libdir}/pkgconfig/rpicam_app.pc +} + +FILES:${PN} += "${libdir}/rpicam-apps-postproc \ + ${libdir}/rpicam-apps-preview \ + ${datadir}/rpi-camera-assets" diff --git a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_git.bb b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_git.bb deleted file mode 100644 index 8585526..0000000 --- a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_git.bb +++ /dev/null @@ -1,44 +0,0 @@ -SUMMARY = "A suite of libcamera-based apps" -DESCRIPTION = "This is a small suite of libcamera-based apps that aim to \ -copy the functionality of the existing \"raspicam\" apps." -HOMEPAGE = "https://github.com/raspberrypi/libcamera-apps" -SECTION = "console/utils" - -LICENSE = "BSD-2-Clause" -LIC_FILES_CHKSUM = "file://license.txt;md5=a0013d1b383d72ba4bdc5b750e7d1d77" - -SRC_URI = "\ - git://github.com/raspberrypi/libcamera-apps.git;protocol=https;branch=main \ - file://0001-utils-version.py-use-usr-bin-env-in-shebang.patch \ - file://0002-Revert-Support-compressed-pixel-formats-when-saving-.patch \ -" -PV = "1.4.2+git${SRCPV}" -SRCREV = "9ae39f85ae6bee9761c36b9b5b80d675bc1fa369" - -DEPENDS = "libcamera libexif jpeg tiff libpng boost" - -PACKAGECONFIG ??= "drm" -PACKAGECONFIG[libav] = "-Denable_libav=true, -Denable_libav=false, libav" -PACKAGECONFIG[drm] = "-Denable_drm=true, -Denable_drm=false, libdrm" -PACKAGECONFIG[egl] = "-Denable_egl=true, -Denable_egl=false, virtual/egl" -PACKAGECONFIG[qt] = "-Denable_qt=true, -Denable_qt=false, qtbase" -PACKAGECONFIG[opencv] = "-Denable_opencv=true, -Denable_opencv=false, opencv" -PACKAGECONFIG[tflite] = "-Denable_tflite=true, -Denable_tflite=false, tensorflow-lite" - -inherit meson pkgconfig - -NEON_FLAGS = "" -NEON_FLAGS:aarch64 = "-Dneon_flags=arm64" -NEON_FLAGS:arm:raspberrypi3 = "-Dneon_flags=armv8-neon" -NEON_FLAGS:arm:raspberrypi4 = "-Dneon_flags=armv8-neon" -EXTRA_OEMESON += "${NEON_FLAGS}" - -# QA Issue: /usr/bin/camera-bug-report contained in package libcamera-apps requires /usr/bin/python3 -do_install:append() { - rm -v ${D}/${bindir}/camera-bug-report -} - -# not picked automatically, because it's missing common 'lib' prefix -FILES:${PN}-dev += "${libdir}/rpicam_app.so" - -FILES:${PN} += "${libdir}/rpicam_app.so.${@d.getVar("PV", False).__str__().split('+')[0]}"