[libcamera-devel] [RFC] Add 8-bit bayer support.
Hans de Goede
hdegoede at redhat.com
Fri Dec 15 15:17:44 CET 2023
Hi Pavel,
On 12/14/23 22:37, Pavel Machek wrote:
> ---
>
> Did I get it mostly right? I can't test other formats but providing
> them should not be too hard. Does it make sense to add this to your
> series or is it better to just wait for v1 to be merged?
Yes this looks about right. Yesterday I finished about a 10
day libcamera sprint so for now I'm not going to touch
libcamera for a few days.
I plan to get back to libcamera again on Wednesday.
I'll add a commit adding 8bpp bayer, all 4 orders,
to my personal libcamera softisp branch then and when
that is in place I'll send you an email asking to test it.
Regards,
Hans
>
>
> diff --git a/include/libcamera/internal/software_isp/debayer_cpu.h b/include/libcamera/internal/software_isp/debayer_cpu.h
> index 7fb5be77..f3bb4321 100644
> --- a/include/libcamera/internal/software_isp/debayer_cpu.h
> +++ b/include/libcamera/internal/software_isp/debayer_cpu.h
> @@ -67,6 +67,9 @@ private:
> void debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src);
> void debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src);
>
> + void debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src);
> + void debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src);
> +
> typedef void (DebayerCpu::*debayerFn)(uint8_t *dst, const uint8_t *src);
>
> struct DebayerInputConfig {
> diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h
> index 0ceb995f..3c43e146 100644
> --- a/include/libcamera/internal/software_isp/swstats_cpu.h
> +++ b/include/libcamera/internal/software_isp/swstats_cpu.h
> @@ -29,6 +29,8 @@ public:
> /* FIXME this should be dropped once AWB has moved to the IPA */
> SwIspStats getStats() { return *sharedStats_; }
> private:
> + void statsBGGR8Line0(const uint8_t *src, unsigned int stride);
> +
> void statsBGGR10PLine0(const uint8_t *src, unsigned int stride);
> void statsGBRG10PLine0(const uint8_t *src, unsigned int stride);
> void statsGRBG10PLine0(const uint8_t *src, unsigned int stride);
> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp
> index 3eacdd5d..52910a03 100644
> --- a/src/libcamera/software_isp/debayer_cpu.cpp
> +++ b/src/libcamera/software_isp/debayer_cpu.cpp
> @@ -111,6 +111,36 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src)
> }
> }
>
> +void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src)
> +{
> + const int width_in_bytes = window_.width;
> + struct ctxt_8bit_src c = {
> + src - inputConfig_.stride, src, src + inputConfig_.stride,
> + red_, green_, blue_ };
> +
> + for (int x = 0; x < width_in_bytes; ) {
> + /* Even pixel */
> + bggr8_bgr888(c, dst, x++, 1, 1);
> + /* Odd pixel BGGR -> GBRG */
> + gbrg8_bgr888(c, dst, x++, 1, 1);
> + }
> +}
> +
> +void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src)
> +{
> + const int width_in_bytes = window_.width;
> + struct ctxt_8bit_src c = {
> + src - inputConfig_.stride, src, src + inputConfig_.stride,
> + red_, green_, blue_ };
> +
> + for (int x = 0; x < width_in_bytes; ) {
> + /* Even pixel */
> + grbg8_bgr888(c, dst, x++, 1, 1);
> + /* Odd pixel GRBG -> RGGB */
> + rggb8_bgr888(c, dst, x++, 1, 1);
> + }
> +}
> +
> void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src)
> {
> const int width_in_bytes = window_.width * 5 / 4;
> @@ -152,6 +182,22 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf
> BayerFormat bayerFormat =
> BayerFormat::fromPixelFormat(inputFormat);
>
> + if (bayerFormat.bitDepth == 8) {
> + config.bpp = 8;
> + config.patternSize.height = 2;
> + config.patternSize.width = 4;
> + config.x_shift = 0;
> + config.outputFormats = std::vector<PixelFormat>({ formats::RGB888 });
> +
> + switch (bayerFormat.order) {
> + case BayerFormat::BGGR:
> + return 0;
> + default:
> + break;
> + }
> + /* } else if (future supported fmts) { ... */
> + }
> +
> if (bayerFormat.bitDepth == 10 &&
> bayerFormat.packing == BayerFormat::Packing::CSI2) {
> config.bpp = 10;
> @@ -195,6 +241,17 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, [[maybe_unused]] Pi
> BayerFormat bayerFormat =
> BayerFormat::fromPixelFormat(inputFormat);
>
> + if (bayerFormat.bitDepth == 8) {
> + switch (bayerFormat.order) {
> + case BayerFormat::BGGR:
> + debayer0_ = &DebayerCpu::debayer8_BGBG_BGR888;
> + debayer1_ = &DebayerCpu::debayer8_GRGR_BGR888;
> + return 0;
> + default:
> + break;
> + }
> + }
> +
> if (bayerFormat.bitDepth == 10 &&
> bayerFormat.packing == BayerFormat::Packing::CSI2) {
> switch (bayerFormat.order) {
> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp
> index 15f23953..e65b1b65 100644
> --- a/src/libcamera/software_isp/swstats_cpu.cpp
> +++ b/src/libcamera/software_isp/swstats_cpu.cpp
> @@ -37,9 +37,9 @@ static const unsigned int GREEN_Y_MUL = 150; /* 0.59 * 256 */
> static const unsigned int BLUE_Y_MUL = 29; /* 0.11 * 256 */
>
> static inline __attribute__((always_inline)) void
> -statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, unsigned int &bright_sum_, unsigned int &too_bright_sum_, SwIspStats &stats_)
> +statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, unsigned int &bright_sum_, unsigned int &too_bright_sum_, SwIspStats &stats_, bool is10p)
> {
> - const int width_in_bytes = width * 5 / 4;
> + const int width_in_bytes = width * (4 + is10p) / 4;
> uint8_t r, g, b, g2;
> unsigned int y_val;
> unsigned int sumR = 0;
> @@ -49,7 +49,7 @@ statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bg
> unsigned int bright_sum = 0;
> unsigned int too_bright_sum = 0;
>
> - for (int x = 0; x < width_in_bytes; x += 5) {
> + for (int x = 0; x < width_in_bytes; x += (4 + is10p)) {
> if (bggr) {
> /* BGGR */
> b = src0[x];
> @@ -84,26 +84,31 @@ statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bg
> too_bright_sum_ += too_bright_sum;
> }
>
> +void SwStatsCpu::statsBGGR8Line0(const uint8_t *src, unsigned int stride)
> +{
> + statsBayer10P(window_.width, src, src + stride, true, bright_sum_, too_bright_sum_, stats_, false);
> +}
> +
> void SwStatsCpu::statsBGGR10PLine0(const uint8_t *src, unsigned int stride)
> {
> - statsBayer10P(window_.width, src, src + stride, true, bright_sum_, too_bright_sum_, stats_);
> + statsBayer10P(window_.width, src, src + stride, true, bright_sum_, too_bright_sum_, stats_, true);
> }
>
> void SwStatsCpu::statsGBRG10PLine0(const uint8_t *src, unsigned int stride)
> {
> - statsBayer10P(window_.width, src, src + stride, false, bright_sum_, too_bright_sum_, stats_);
> + statsBayer10P(window_.width, src, src + stride, false, bright_sum_, too_bright_sum_, stats_, true);
> }
>
> void SwStatsCpu::statsGRBG10PLine0(const uint8_t *src, unsigned int stride)
> {
> /* GRBG is BGGR with the lines swapped */
> - statsBayer10P(window_.width, src + stride, src, true, bright_sum_, too_bright_sum_, stats_);
> + statsBayer10P(window_.width, src + stride, src, true, bright_sum_, too_bright_sum_, stats_, true);
> }
>
> void SwStatsCpu::statsRGGB10PLine0(const uint8_t *src, unsigned int stride)
> {
> /* RGGB is GBRG with the lines swapped */
> - statsBayer10P(window_.width, src + stride, src, false, bright_sum_, too_bright_sum_, stats_);
> + statsBayer10P(window_.width, src + stride, src, false, bright_sum_, too_bright_sum_, stats_, true);
> }
>
> void SwStatsCpu::resetStats(void)
> @@ -134,6 +139,24 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)
> startFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::resetStats;
> finishFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::finishStats;
>
> + if (bayerFormat.bitDepth == 8) {
> + bpp_ = 8;
> + patternSize_.height = 2;
> + patternSize_.width = 4;
> + y_skip_mask_ = 0x0c; /* Skip every 3th and 4th line */
> + x_shift_ = 0;
> +
> + switch (bayerFormat.order) {
> + case BayerFormat::BGGR:
> + stats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsBGGR8Line0;
> + return 0;
> + default:
> + break;
> + }
> + /* } else if (future supported fmts) { ... */
> + }
> +
> +
> if (bayerFormat.bitDepth == 10 &&
> bayerFormat.packing == BayerFormat::Packing::CSI2) {
> bpp_ = 10;
>
More information about the libcamera-devel
mailing list