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 c965b2c52..000000000 --- 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_git.bb b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera-apps/libcamera-apps_git.bb index 858552692..3feece3c9 100644 --- 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 @@ -10,20 +10,19 @@ 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" +PV = "1.5.2+git${SRCPV}" +SRCREV = "50958df98d3cf77b54706a794226d556d649981c" 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" +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 @@ -38,6 +37,13 @@ do_install:append() { rm -v ${D}/${bindir}/camera-bug-report } +FILES:${PN}:append = " \ + /usr/share/rpi-camera-assets/negate.json \ + /usr/share/rpi-camera-assets/hdr.json \ + /usr/share/rpi-camera-assets/motion_detect.json \ + /usr/lib/rpicam-apps-postproc/core-postproc.so \ +" + # not picked automatically, because it's missing common 'lib' prefix FILES:${PN}-dev += "${libdir}/rpicam_app.so" diff --git a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera/libcamera_%.bbappend b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera/libcamera_%.bbappend deleted file mode 100644 index c152b7803..000000000 --- a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera/libcamera_%.bbappend +++ /dev/null @@ -1,3 +0,0 @@ -PACKAGECONFIG[raspberrypi] = "-Dpipelines=rpi/vc4 -Dipas=rpi/vc4" -PACKAGECONFIG:append:rpi = " raspberrypi" -CXXFLAGS:append:rpi = " -Wno-unaligned-access " diff --git a/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera/libcamera_0.4.0.bb b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera/libcamera_0.4.0.bb new file mode 100644 index 000000000..4a2f98b8c --- /dev/null +++ b/dynamic-layers/multimedia-layer/recipes-multimedia/libcamera/libcamera_0.4.0.bb @@ -0,0 +1,79 @@ +SUMMARY = "Linux libcamera framework" +SECTION = "libs" + +LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later" + +LIC_FILES_CHKSUM = "\ + file://LICENSES/GPL-2.0-or-later.txt;md5=fed54355545ffd980b814dab4a3b312c \ + file://LICENSES/LGPL-2.1-or-later.txt;md5=2a4f4fd2128ea2f65047ee63fbca9f68 \ +" + +SRC_URI = " git://github.com/raspberrypi/libcamera.git;protocol=https;branch=main" + +SRCREV = "29156679717bec7cc4784aeba3548807f2c27fca" + +PE = "1" + +S = "${WORKDIR}/git" + +DEPENDS = "python3-pyyaml-native python3-jinja2-native python3-ply-native python3-jinja2-native udev gnutls chrpath-native libevent libyaml" +DEPENDS += "${@bb.utils.contains('DISTRO_FEATURES', 'qt', 'qtbase qtbase-native', '', d)}" + +PACKAGES =+ "${PN}-gst ${PN}-pycamera" + +PACKAGECONFIG ??= "raspberrypi" +PACKAGECONFIG[gst] = "-Dgstreamer=enabled,-Dgstreamer=disabled,gstreamer1.0 gstreamer1.0-plugins-base" +PACKAGECONFIG[pycamera] = "-Dpycamera=enabled,-Dpycamera=disabled,python3 python3-pybind11" + +RPI_CONF_STR = "-Dpipelines=rpi/vc4,rpi/pisp -Dipas=rpi/vc4,rpi/pisp" + +PACKAGECONFIG[raspberrypi] = "${RPI_CONF_STR},, libpisp" + +LIBCAMERA_PIPELINES ??= "auto" + +EXTRA_OEMESON = " \ + -Dpipelines=${LIBCAMERA_PIPELINES} \ + -Dv4l2=true \ + -Dcam=enabled \ + -Dlc-compliance=disabled \ + -Dtest=false \ + -Ddocumentation=disabled \ +" + +RDEPENDS:${PN} = "${@bb.utils.contains('DISTRO_FEATURES', 'wayland qt', 'qtwayland', '', d)}" + +inherit meson pkgconfig python3native + +do_configure:prepend() { +} + +do_install:append() { + chrpath -d ${D}${libdir}/libcamera.so + chrpath -d ${D}${libexecdir}/libcamera/v4l2-compat.so +} + +do_package:append() { + bb.build.exec_func("do_package_recalculate_ipa_signatures", d) +} + +do_package_recalculate_ipa_signatures() { + local modules + for module in $(find ${PKGD}/usr/lib/libcamera -name "*.so.sign"); do + module="${module%.sign}" + if [ -f "${module}" ] ; then + modules="${modules} ${module}" + fi + done + + ${S}/src/ipa/ipa-sign-install.sh ${B}/src/ipa-priv-key.pem "${modules}" +} + +FILES:${PN} += " ${libexecdir}/libcamera/v4l2-compat.so" +FILES:${PN}-gst = "${libdir}/gstreamer-1.0" +FILES:${PN}-pycamera = "${PYTHON_SITEPACKAGES_DIR}/libcamera" + +# libcamera-v4l2 explicitly sets _FILE_OFFSET_BITS=32 to get access to +# both 32 and 64 bit file APIs. +GLIBC_64BIT_TIME_FLAGS = "" + +CXXFLAGS:append:rpi = " -Wno-stringop-truncation " diff --git a/recipes-multimedia/libpisp/libpisp_git.bb b/recipes-multimedia/libpisp/libpisp_git.bb new file mode 100644 index 000000000..9caa987cf --- /dev/null +++ b/recipes-multimedia/libpisp/libpisp_git.bb @@ -0,0 +1,22 @@ +SUMMARY = "Raspberry Pi ISP (PiSP)" +SECTION = "libs" + +LICENSE = "BSD-2-Clause" + +LIC_FILES_CHKSUM = " file://LICENSES/BSD-2-Clause.txt;md5=3417a46e992fdf62e5759fba9baef7a7" + +SRC_URI = " \ + git://github.com/raspberrypi/libpisp.git;protocol=https;branch=main \ +" + +SRCREV = "50426319aa1a9ba4672f91977429365ad4e335a2" + +PV = "1.2.0" + +S = "${WORKDIR}/git" + +DEPENDS = "nlohmann-json" + +INSANE_SKIP:${PN} = "buildpaths" + +inherit meson pkgconfig \ No newline at end of file