diff --git a/temp/libcamera/0001-libcamera-debayer_cpu-Add-32bits-aligned-output-form.patch b/temp/libcamera/0001-libcamera-debayer_cpu-Add-32bits-aligned-output-form.patch new file mode 100644 index 000000000..b015cf674 --- /dev/null +++ b/temp/libcamera/0001-libcamera-debayer_cpu-Add-32bits-aligned-output-form.patch @@ -0,0 +1,297 @@ +From 437e601653e69c82f5396979d99e7b9b5bb6086b Mon Sep 17 00:00:00 2001 +From: Robert Mader +Date: Tue, 18 Jun 2024 08:31:59 +0200 +Subject: [PATCH] libcamera: debayer_cpu: Add 32bits/aligned output formats + +In order to be more compatible with modern hardware and APIs. This +notably allows GL implementations to directly import the buffers more +often and seems to be required for Wayland. + +Further more, as we already enforce a 8 byte stride, these formats work +better for clients that don't support padding - such as libwebrtc at the +time of writing. + +Tested devices: + - Librem5 + - PinePhone + - Thinkpad X13s + +Signed-off-by: Robert Mader +Tested-by: Kieran Bingham +Reviewed-by: Milan Zamazal +Reviewed-by: Kieran Bingham +Signed-off-by: Kieran Bingham +--- + src/libcamera/software_isp/debayer_cpu.cpp | 75 +++++++++++++++++----- + src/libcamera/software_isp/debayer_cpu.h | 10 +++ + 2 files changed, 69 insertions(+), 16 deletions(-) + +diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp +index c038eed4..f8d2677d 100644 +--- a/src/libcamera/software_isp/debayer_cpu.cpp ++++ b/src/libcamera/software_isp/debayer_cpu.cpp +@@ -74,6 +74,8 @@ DebayerCpu::~DebayerCpu() + *dst++ = blue_[curr[x] / (div)]; \ + *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))]; \ + *dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \ ++ if constexpr (addAlphaByte) \ ++ *dst++ = 255; \ + x++; + + /* +@@ -85,6 +87,8 @@ DebayerCpu::~DebayerCpu() + *dst++ = blue_[(prev[x] + next[x]) / (2 * (div))]; \ + *dst++ = green_[curr[x] / (div)]; \ + *dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \ ++ if constexpr (addAlphaByte) \ ++ *dst++ = 255; \ + x++; + + /* +@@ -96,6 +100,8 @@ DebayerCpu::~DebayerCpu() + *dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \ + *dst++ = green_[curr[x] / (div)]; \ + *dst++ = red_[(prev[x] + next[x]) / (2 * (div))]; \ ++ if constexpr (addAlphaByte) \ ++ *dst++ = 255; \ + x++; + + /* +@@ -107,8 +113,11 @@ DebayerCpu::~DebayerCpu() + *dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \ + *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))]; \ + *dst++ = red_[curr[x] / (div)]; \ ++ if constexpr (addAlphaByte) \ ++ *dst++ = 255; \ + x++; + ++template + void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) + { + DECLARE_SRC_POINTERS(uint8_t) +@@ -119,6 +128,7 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) + { + DECLARE_SRC_POINTERS(uint8_t) +@@ -129,6 +139,7 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) + { + DECLARE_SRC_POINTERS(uint16_t) +@@ -140,6 +151,7 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) + { + DECLARE_SRC_POINTERS(uint16_t) +@@ -151,6 +163,7 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) + { + DECLARE_SRC_POINTERS(uint16_t) +@@ -162,6 +175,7 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) + { + DECLARE_SRC_POINTERS(uint16_t) +@@ -173,6 +187,7 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) + { + const int widthInBytes = window_.width * 5 / 4; +@@ -198,6 +213,7 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) + { + const int widthInBytes = window_.width * 5 / 4; +@@ -218,6 +234,7 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]) + { + const int widthInBytes = window_.width * 5 / 4; +@@ -238,6 +255,7 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]) + } + } + ++template + void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]) + { + const int widthInBytes = window_.width * 5 / 4; +@@ -280,7 +298,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf + config.bpp = (bayerFormat.bitDepth + 7) & ~7; + config.patternSize.width = 2; + config.patternSize.height = 2; +- config.outputFormats = std::vector({ formats::RGB888, formats::BGR888 }); ++ config.outputFormats = std::vector({ formats::RGB888, ++ formats::XRGB8888, ++ formats::ARGB8888, ++ formats::BGR888, ++ formats::XBGR8888, ++ formats::ABGR8888 }); + return 0; + } + +@@ -290,7 +313,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf + config.bpp = 10; + config.patternSize.width = 4; /* 5 bytes per *4* pixels */ + config.patternSize.height = 2; +- config.outputFormats = std::vector({ formats::RGB888, formats::BGR888 }); ++ config.outputFormats = std::vector({ formats::RGB888, ++ formats::XRGB8888, ++ formats::ARGB8888, ++ formats::BGR888, ++ formats::XBGR8888, ++ formats::ABGR8888 }); + return 0; + } + +@@ -306,6 +334,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c + return 0; + } + ++ if (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 || ++ outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) { ++ config.bpp = 32; ++ return 0; ++ } ++ + LOG(Debayer, Info) + << "Unsupported output format " << outputFormat.toString(); + return -EINVAL; +@@ -341,6 +375,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF + { + BayerFormat bayerFormat = + BayerFormat::fromPixelFormat(inputFormat); ++ bool addAlphaByte = false; + + xShift_ = 0; + swapRedBlueGains_ = false; +@@ -351,8 +386,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF + }; + + switch (outputFormat) { ++ case formats::XRGB8888: ++ case formats::ARGB8888: ++ addAlphaByte = true; ++ [[fallthrough]]; + case formats::RGB888: + break; ++ case formats::XBGR8888: ++ case formats::ABGR8888: ++ addAlphaByte = true; ++ [[fallthrough]]; + case formats::BGR888: + /* Swap R and B in bayer order to generate BGR888 instead of RGB888 */ + swapRedBlueGains_ = true; +@@ -383,16 +426,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF + isStandardBayerOrder(bayerFormat.order)) { + switch (bayerFormat.bitDepth) { + case 8: +- debayer0_ = &DebayerCpu::debayer8_BGBG_BGR888; +- debayer1_ = &DebayerCpu::debayer8_GRGR_BGR888; ++ debayer0_ = addAlphaByte ? &DebayerCpu::debayer8_BGBG_BGR888 : &DebayerCpu::debayer8_BGBG_BGR888; ++ debayer1_ = addAlphaByte ? &DebayerCpu::debayer8_GRGR_BGR888 : &DebayerCpu::debayer8_GRGR_BGR888; + break; + case 10: +- debayer0_ = &DebayerCpu::debayer10_BGBG_BGR888; +- debayer1_ = &DebayerCpu::debayer10_GRGR_BGR888; ++ debayer0_ = addAlphaByte ? &DebayerCpu::debayer10_BGBG_BGR888 : &DebayerCpu::debayer10_BGBG_BGR888; ++ debayer1_ = addAlphaByte ? &DebayerCpu::debayer10_GRGR_BGR888 : &DebayerCpu::debayer10_GRGR_BGR888; + break; + case 12: +- debayer0_ = &DebayerCpu::debayer12_BGBG_BGR888; +- debayer1_ = &DebayerCpu::debayer12_GRGR_BGR888; ++ debayer0_ = addAlphaByte ? &DebayerCpu::debayer12_BGBG_BGR888 : &DebayerCpu::debayer12_BGBG_BGR888; ++ debayer1_ = addAlphaByte ? &DebayerCpu::debayer12_GRGR_BGR888 : &DebayerCpu::debayer12_GRGR_BGR888; + break; + } + setupStandardBayerOrder(bayerFormat.order); +@@ -403,20 +446,20 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF + bayerFormat.packing == BayerFormat::Packing::CSI2) { + switch (bayerFormat.order) { + case BayerFormat::BGGR: +- debayer0_ = &DebayerCpu::debayer10P_BGBG_BGR888; +- debayer1_ = &DebayerCpu::debayer10P_GRGR_BGR888; ++ debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888 : &DebayerCpu::debayer10P_BGBG_BGR888; ++ debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888 : &DebayerCpu::debayer10P_GRGR_BGR888; + return 0; + case BayerFormat::GBRG: +- debayer0_ = &DebayerCpu::debayer10P_GBGB_BGR888; +- debayer1_ = &DebayerCpu::debayer10P_RGRG_BGR888; ++ debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888 : &DebayerCpu::debayer10P_GBGB_BGR888; ++ debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888 : &DebayerCpu::debayer10P_RGRG_BGR888; + return 0; + case BayerFormat::GRBG: +- debayer0_ = &DebayerCpu::debayer10P_GRGR_BGR888; +- debayer1_ = &DebayerCpu::debayer10P_BGBG_BGR888; ++ debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888 : &DebayerCpu::debayer10P_GRGR_BGR888; ++ debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888 : &DebayerCpu::debayer10P_BGBG_BGR888; + return 0; + case BayerFormat::RGGB: +- debayer0_ = &DebayerCpu::debayer10P_RGRG_BGR888; +- debayer1_ = &DebayerCpu::debayer10P_GBGB_BGR888; ++ debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888 : &DebayerCpu::debayer10P_RGRG_BGR888; ++ debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888 : &DebayerCpu::debayer10P_GBGB_BGR888; + return 0; + default: + break; +diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h +index be7dcdca..1dac6435 100644 +--- a/src/libcamera/software_isp/debayer_cpu.h ++++ b/src/libcamera/software_isp/debayer_cpu.h +@@ -85,18 +85,28 @@ private: + using debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]); + + /* 8-bit raw bayer format */ ++ template + void debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]); ++ template + void debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]); + /* unpacked 10-bit raw bayer format */ ++ template + void debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]); ++ template + void debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]); + /* unpacked 12-bit raw bayer format */ ++ template + void debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]); ++ template + void debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]); + /* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */ ++ template + void debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]); ++ template + void debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]); ++ template + void debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]); ++ template + void debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]); + + struct DebayerInputConfig { +-- +2.45.2 + diff --git a/temp/libcamera/APKBUILD b/temp/libcamera/APKBUILD index 1ca52ac23..b0df00d4d 100644 --- a/temp/libcamera/APKBUILD +++ b/temp/libcamera/APKBUILD @@ -3,7 +3,7 @@ pkgname=libcamera pkgver=9999 _pkgver=0.3.0 -pkgrel=0 +pkgrel=1 pkgdesc="Linux camera framework" url="https://libcamera.org/" arch="all" @@ -47,6 +47,7 @@ source="https://gitlab.freedesktop.org/camera/libcamera/-/archive/v$_pkgver/libc 0002-libcamera-simple-Force-disable-softwareISP-for-milli.patch 0003-libcamera-simple-Enable-softISP-for-the-Pinephone.patch 0004-libcamera-simple-Skip-hwISP-formats-if-swISP-is-acti.patch + 0001-libcamera-debayer_cpu-Add-32bits-aligned-output-form.patch qcam.desktop 90-libcamera.rules " @@ -152,6 +153,7 @@ d232593b6cc7f2b772e8cd0b6751fee00ddbde256328c4cf7162726d4766149afca36411075e2b55 26b274c32c9fc0d8220f58c7e37f6c0c9e590b2ff07adbc908b4c38ae4b7104639bb8ecf57b2faa15d2fae932d0021b51ad6a31a8762a05d3f876d55f0fef242 0002-libcamera-simple-Force-disable-softwareISP-for-milli.patch 68b66432d3e60adc7329713b1362d023244516b697fbcb67112d9aad1367d2c65a100470b1ab6747074ca2717ec18e848b3888b382f75be1646e182894c6a37c 0003-libcamera-simple-Enable-softISP-for-the-Pinephone.patch 4bfc5c35cf6bc8f1695744486a43695efa7bef5ce1c3bc93bda227832d08394f3bb0115863f7a30a8adfc4c93af293cdd5063fdb78f8d850f4d0c2ac7b1ff123 0004-libcamera-simple-Skip-hwISP-formats-if-swISP-is-acti.patch +231a355350d7bd25e997f58bf145c81cad9af852e131d005dcb75d9529ec56c5eff966fca106db1be3e3cefadc1539915340803d6d3a650d862d32fcd066fe55 0001-libcamera-debayer_cpu-Add-32bits-aligned-output-form.patch 22167a4eceb6d1b40b0b7c45fdf116c71684f5340de7f767535cb8e160ad9d2ae0f00cb3d461f73a344520a48a4641cf46226841d78bee06bfbfd2a91337f754 qcam.desktop 444a0a52b374751c388f807b6adcc63b36488547adaa5fb70b606dc5646132b1a893a76254236b5c80f3a6d041a4597d413e050af0323cd05626d758190838e2 90-libcamera.rules "