libcamera: debayer_cpu: Add BGR888 output support

BGR888 is RGB888 with the red and blue pixels swapped, adjust
the debayering to swap the red and blue pixels in the bayer pattern
to add support for writing formats::BGR888.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Hans de Goede 2024-04-16 11:13:52 +02:00 committed by Kieran Bingham
parent 17c58df4b4
commit 09fb65486e
2 changed files with 43 additions and 8 deletions

View file

@ -281,7 +281,7 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf
config.bpp = (bayerFormat.bitDepth + 7) & ~7; config.bpp = (bayerFormat.bitDepth + 7) & ~7;
config.patternSize.width = 2; config.patternSize.width = 2;
config.patternSize.height = 2; config.patternSize.height = 2;
config.outputFormats = std::vector<PixelFormat>({ formats::RGB888 }); config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });
return 0; return 0;
} }
@ -291,7 +291,7 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf
config.bpp = 10; config.bpp = 10;
config.patternSize.width = 4; /* 5 bytes per *4* pixels */ config.patternSize.width = 4; /* 5 bytes per *4* pixels */
config.patternSize.height = 2; config.patternSize.height = 2;
config.outputFormats = std::vector<PixelFormat>({ formats::RGB888 }); config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });
return 0; return 0;
} }
@ -302,7 +302,7 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf
int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config) int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config)
{ {
if (outputFormat == formats::RGB888) { if (outputFormat == formats::RGB888 || outputFormat == formats::BGR888) {
config.bpp = 24; config.bpp = 24;
return 0; return 0;
} }
@ -338,14 +338,46 @@ int DebayerCpu::setupStandardBayerOrder(BayerFormat::Order order)
return 0; return 0;
} }
/* \todo This ignores outputFormat since there is only 1 supported outputFormat int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat)
for now */
int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, [[maybe_unused]] PixelFormat outputFormat)
{ {
BayerFormat bayerFormat = BayerFormat bayerFormat =
BayerFormat::fromPixelFormat(inputFormat); BayerFormat::fromPixelFormat(inputFormat);
xShift_ = 0; xShift_ = 0;
swapRedBlueGains_ = false;
auto invalidFmt = []() -> int {
LOG(Debayer, Error) << "Unsupported input output format combination";
return -EINVAL;
};
switch (outputFormat) {
case formats::RGB888:
break;
case formats::BGR888:
/* Swap R and B in bayer order to generate BGR888 instead of RGB888 */
swapRedBlueGains_ = true;
switch (bayerFormat.order) {
case BayerFormat::BGGR:
bayerFormat.order = BayerFormat::RGGB;
break;
case BayerFormat::GBRG:
bayerFormat.order = BayerFormat::GRBG;
break;
case BayerFormat::GRBG:
bayerFormat.order = BayerFormat::GBRG;
break;
case BayerFormat::RGGB:
bayerFormat.order = BayerFormat::BGGR;
break;
default:
return invalidFmt();
}
break;
default:
return invalidFmt();
}
if ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10 || bayerFormat.bitDepth == 12) && if ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10 || bayerFormat.bitDepth == 12) &&
bayerFormat.packing == BayerFormat::Packing::None && bayerFormat.packing == BayerFormat::Packing::None &&
@ -392,8 +424,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, [[maybe_unused]] Pi
} }
} }
LOG(Debayer, Error) << "Unsupported input output format combination"; return invalidFmt();
return -EINVAL;
} }
int DebayerCpu::configure(const StreamConfiguration &inputCfg, int DebayerCpu::configure(const StreamConfiguration &inputCfg,
@ -675,6 +706,9 @@ void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams
gammaCorrection_ = params.gamma; gammaCorrection_ = params.gamma;
} }
if (swapRedBlueGains_)
std::swap(params.gainR, params.gainB);
for (unsigned int i = 0; i < kRGBLookupSize; i++) { for (unsigned int i = 0; i < kRGBLookupSize; i++) {
constexpr unsigned int div = constexpr unsigned int div =
kRGBLookupSize * DebayerParams::kGain10 / kGammaLookupSize; kRGBLookupSize * DebayerParams::kGain10 / kGammaLookupSize;

View file

@ -145,6 +145,7 @@ private:
unsigned int lineBufferIndex_; unsigned int lineBufferIndex_;
unsigned int xShift_; /* Offset of 0/1 applied to window_.x */ unsigned int xShift_; /* Offset of 0/1 applied to window_.x */
bool enableInputMemcpy_; bool enableInputMemcpy_;
bool swapRedBlueGains_;
float gammaCorrection_; float gammaCorrection_;
unsigned int measuredFrames_; unsigned int measuredFrames_;
int64_t frameProcessTime_; int64_t frameProcessTime_;