Message ID | 20231212115046.102726-1-andrey.konovalov@linaro.org |
---|---|
Headers | show |
Series |
|
Related | show |
Hi! > Here is a draft implementation of Software ISP and Software IPA > which provide debayering and implementation of image processing > algorithms for systems without a hardware ISP, or in cases when > there are no public drivers for the hardware ISP present in the > system. After tweaks to support 8-bit it works for me and is quite useful on PinePhone. IMO something needs fixing in SimplePipelineHandler::generateConfiguration, otherwise code will sigsegv when suitable formats are not available. Tested-by: Pavel Machek <pavel@ucw.cz> Best regards, Pavel commit a9966b193ebe4c9624e00a962ba17786a1aeaad5 Author: Pavel Machek <pavel@ucw.cz> Date: Tue Dec 5 13:01:54 2023 +0100 b8: Got 8-bit bayer to work. diff --git a/include/libcamera/internal/software_isp/swisp_linaro.h b/include/libcamera/internal/software_isp/swisp_linaro.h index c0df7863..f7fc7682 100644 --- a/include/libcamera/internal/software_isp/swisp_linaro.h +++ b/include/libcamera/internal/software_isp/swisp_linaro.h @@ -89,6 +89,11 @@ private: int setDebayerInfo(PixelFormat format); debayerInfo *debayerInfo_; + void debayerRaw(uint8_t *dst, const uint8_t *src, bool is10p); + + /* Bayer 8 */ + void debayerRaw8(uint8_t *dst, const uint8_t *src); + /* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */ void debayerRaw10P(uint8_t *dst, const uint8_t *src); static SizeRange outSizesRaw10P(const Size &inSize); diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index b95d7689..4561961e 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1137,6 +1137,14 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo */ for ([[maybe_unused]] StreamRole role : roles) { StreamConfiguration cfg{ StreamFormats{ formats } }; + if (! formats.begin()->first) { + LOG(SimplePipeline, Error) + << "No formats -- first?"; + continue; + } + LOG(SimplePipeline, Error) + << "Going through roles?"; + cfg.pixelFormat = formats.begin()->first; cfg.size = formats.begin()->second[0].max; diff --git a/src/libcamera/software_isp/swisp_linaro.cpp b/src/libcamera/software_isp/swisp_linaro.cpp index b7f36db1..0255ce85 100644 --- a/src/libcamera/software_isp/swisp_linaro.cpp +++ b/src/libcamera/software_isp/swisp_linaro.cpp @@ -88,7 +88,7 @@ bool SwIspLinaro::isValid() const * \todo Split the stats calculations out of this function. * \todo Move the AWB algorithm into the IPA module. */ -void SwIspLinaro::IspWorker::debayerRaw10P(uint8_t *dst, const uint8_t *src) +void SwIspLinaro::IspWorker::debayerRaw(uint8_t *dst, const uint8_t *src, bool is10p) { /* for brightness values in the 0 to 255 range: */ static const unsigned int BRIGHT_LVL = 200U << 8; @@ -118,9 +118,15 @@ void SwIspLinaro::IspWorker::debayerRaw10P(uint8_t *dst, const uint8_t *src) int phase = 2 * phase_y + phase_x; /* x part of the offset in the input buffer: */ - int x_m1 = x + x / 4; /* offset for (x-1) */ - int x_0 = x + 1 + (x + 1) / 4; /* offset for x */ - int x_p1 = x + 2 + (x + 2) / 4; /* offset for (x+1) */ + int x_m1 = x; /* offset for (x-1) */ + int x_0 = x + 1; /* offset for x */ + int x_p1 = x + 2; /* offset for (x+1) */ + + if (is10p) { + x_m1 += x_m1 / 4; /* offset for (x-1) */ + x_0 += x_0 / 4; /* offset for x */ + x_p1 += x_p1 / 4; /* offset for (x+1) */ + } /* the colour component value to write to the output */ unsigned val; /* Y value times 256 */ @@ -267,6 +273,16 @@ void SwIspLinaro::IspWorker::debayerRaw10P(uint8_t *dst, const uint8_t *src) << " (minDenom = " << minDenom << ")"; } +void SwIspLinaro::IspWorker::debayerRaw10P(uint8_t *dst, const uint8_t *src) +{ + debayerRaw(dst, src, true); +} + +void SwIspLinaro::IspWorker::debayerRaw8(uint8_t *dst, const uint8_t *src) +{ + debayerRaw(dst, src, false); +} + SizeRange SwIspLinaro::IspWorker::outSizesRaw10P(const Size &inSize) { if (inSize.width < 2 || inSize.height < 2) { @@ -286,6 +302,10 @@ unsigned int SwIspLinaro::IspWorker::outStrideRaw10P(const Size &outSize) SwIspLinaro::IspWorker::IspWorker(SwIspLinaro *swIsp) : swIsp_(swIsp) { + debayerInfos_[formats::SBGGR8] = { formats::RGB888, + &SwIspLinaro::IspWorker::debayerRaw8, + &SwIspLinaro::IspWorker::outSizesRaw10P, + &SwIspLinaro::IspWorker::outStrideRaw10P }; debayerInfos_[formats::SBGGR10_CSI2P] = { formats::RGB888, &SwIspLinaro::IspWorker::debayerRaw10P, &SwIspLinaro::IspWorker::outSizesRaw10P,