| Message ID | 20261015194335.287960-4-halfline@gmail.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
On 15/10/2026 20:43, Ray Strode wrote: > From: Ray Strode <rstrode@redhat.com> > > The GPU debayer path draws a centered sensor crop into the requested > output size, while CPU statistics read the original input buffer. > > The statistics window still follows the output dimensions, so metering > covers a different part of the sensor when output sizes or aspect ratios > change. > > This commit derives the visible crop in sensor coordinates and centers > the statistics window on that region. I really only got what this patch did once I read the code. I think the commit log here doesn't really summarise - perhaps a one line up the top about only running stats on the cropped area - in plain and simple language - followed by the complex description would help. > Signed-off-by: Ray Strode <rstrode@redhat.com> > --- > src/libcamera/software_isp/debayer_egl.cpp | 14 ++++---------- > src/libcamera/software_isp/debayer_egl.h | 1 - > 2 files changed, 4 insertions(+), 11 deletions(-) > > diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp > index 0f515c5e..3335eaf9 100644 > --- a/src/libcamera/software_isp/debayer_egl.cpp > +++ b/src/libcamera/software_isp/debayer_egl.cpp > @@ -295,72 +295,66 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, > > inputConfig_.stride = inputCfg.stride; > inputPixelFormat_ = inputCfg.pixelFormat; > width_ = inputCfg.size.width; > height_ = inputCfg.size.height; > > if (outputCfgs.size() != 1) { > LOG(Debayer, Error) > << "Unsupported number of output streams: " > << outputCfgs.size(); > return -EINVAL; > } > > const StreamConfiguration &outputCfg = outputCfgs[0]; > SizeRange outSizeRange = sizes(inputCfg.pixelFormat, inputCfg.size); > std::tie(outputConfig_.stride, outputConfig_.frameSize) = > strideAndFrameSize(outputCfg.pixelFormat, outputCfg.size); > > if (!outSizeRange.contains(outputCfg.size) || outputConfig_.stride != outputCfg.stride) { > LOG(Debayer, Error) > << "Invalid output size/stride: " > << "\n " << outputCfg.size << " (" << outSizeRange << ")" > << "\n " << outputCfg.stride << " (" << outputConfig_.stride << ")"; > return -EINVAL; > } > > outputPixelFormat_ = outputCfg.pixelFormat; > outputSize_ = outputCfg.size; > nativeOutputSize_ = outSizeRange.max; > > - window_.x = ((inputCfg.size.width - outputCfg.size.width) / 2) & > - ~(inputConfig_.patternSize.width - 1); > - window_.y = ((inputCfg.size.height - outputCfg.size.height) / 2) & > - ~(inputConfig_.patternSize.height - 1); > - window_.width = outputCfg.size.width; > - window_.height = outputCfg.size.height; > - > /* > - * Don't pass x,y from window_ since process() already adjusts for it. > - * But crop the window to 2/3 of its width and height for speedup. > + * The GPU scales the visible sensor crop to outputSize_. Statistics > + * consume the original input buffer, so use sensor coordinates here. > */ > - stats_->setWindow(Rectangle(window_.size())); > + const Size visibleSize = nativeOutputSize_.boundedToAspectRatio(outputSize_); > + stats_->setWindow(visibleSize.centeredTo(Rectangle(inputCfg.size).center())); > > inputBufferCount_ = inputCfg.bufferCount; > outputBufferCount_ = outputCfg.bufferCount; > > return 0; > } > > Size DebayerEGL::patternSize(PixelFormat inputFormat) > { > DebayerEGL::DebayerInputConfig config; > > if (getInputConfig(inputFormat, config) != 0) > return {}; > > return config.patternSize; > } > > std::vector<PixelFormat> DebayerEGL::formats(PixelFormat inputFormat) > { > DebayerEGL::DebayerInputConfig config; > > if (getInputConfig(inputFormat, config) != 0) > return std::vector<PixelFormat>(); > > return config.outputFormats; > } > > std::tuple<unsigned int, unsigned int> > DebayerEGL::strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) > { > diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h > index 30e51a47..52b8aa07 100644 > --- a/src/libcamera/software_isp/debayer_egl.h > +++ b/src/libcamera/software_isp/debayer_egl.h > @@ -84,41 +84,40 @@ private: > > /* Shader parameters */ > float firstRed_x_; > float firstRed_y_; > GLint attributeVertex_; > GLint attributeTexture_; > GLint textureUniformStep_; > GLint textureUniformSize_; > GLint textureUniformStrideFactor_; > GLint textureUniformBayerFirstRed_; > GLint textureUniformProjMatrix_; > > GLint textureUniformBayerDataIn_; > > /* Per-frame AWB gains */ > GLint awbUniformDataIn_; > > /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ > GLint ccmUniformDataIn_; > > /* Black Level compensation */ > GLint blackLevelUniformDataIn_; > > /* Gamma */ > GLint gammaUniformDataIn_; > > /* Contrast */ > GLint contrastExpUniformDataIn_; > > Size nativeOutputSize_; > - Rectangle window_; > std::unique_ptr<SwStatsCpu> stats_; > eGL egl_; > uint32_t width_; > uint32_t height_; > GLint glFormat_; > unsigned int bytesPerPixel_; > uint32_t shaderStridePixels_; > }; > > } /* namespace libcamera */ > -- > 2.56.0
Hi Bryan, I've rewritten the opening to say that statistics follow the sensor area visible in the GPU output: https://patchwork.libcamera.org/patch/28475/ Thanks, Ray
diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 0f515c5e..3335eaf9 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -295,72 +295,66 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, inputConfig_.stride = inputCfg.stride; inputPixelFormat_ = inputCfg.pixelFormat; width_ = inputCfg.size.width; height_ = inputCfg.size.height; if (outputCfgs.size() != 1) { LOG(Debayer, Error) << "Unsupported number of output streams: " << outputCfgs.size(); return -EINVAL; } const StreamConfiguration &outputCfg = outputCfgs[0]; SizeRange outSizeRange = sizes(inputCfg.pixelFormat, inputCfg.size); std::tie(outputConfig_.stride, outputConfig_.frameSize) = strideAndFrameSize(outputCfg.pixelFormat, outputCfg.size); if (!outSizeRange.contains(outputCfg.size) || outputConfig_.stride != outputCfg.stride) { LOG(Debayer, Error) << "Invalid output size/stride: " << "\n " << outputCfg.size << " (" << outSizeRange << ")" << "\n " << outputCfg.stride << " (" << outputConfig_.stride << ")"; return -EINVAL; } outputPixelFormat_ = outputCfg.pixelFormat; outputSize_ = outputCfg.size; nativeOutputSize_ = outSizeRange.max; - window_.x = ((inputCfg.size.width - outputCfg.size.width) / 2) & - ~(inputConfig_.patternSize.width - 1); - window_.y = ((inputCfg.size.height - outputCfg.size.height) / 2) & - ~(inputConfig_.patternSize.height - 1); - window_.width = outputCfg.size.width; - window_.height = outputCfg.size.height; - /* - * Don't pass x,y from window_ since process() already adjusts for it. - * But crop the window to 2/3 of its width and height for speedup. + * The GPU scales the visible sensor crop to outputSize_. Statistics + * consume the original input buffer, so use sensor coordinates here. */ - stats_->setWindow(Rectangle(window_.size())); + const Size visibleSize = nativeOutputSize_.boundedToAspectRatio(outputSize_); + stats_->setWindow(visibleSize.centeredTo(Rectangle(inputCfg.size).center())); inputBufferCount_ = inputCfg.bufferCount; outputBufferCount_ = outputCfg.bufferCount; return 0; } Size DebayerEGL::patternSize(PixelFormat inputFormat) { DebayerEGL::DebayerInputConfig config; if (getInputConfig(inputFormat, config) != 0) return {}; return config.patternSize; } std::vector<PixelFormat> DebayerEGL::formats(PixelFormat inputFormat) { DebayerEGL::DebayerInputConfig config; if (getInputConfig(inputFormat, config) != 0) return std::vector<PixelFormat>(); return config.outputFormats; } std::tuple<unsigned int, unsigned int> DebayerEGL::strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) { diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 30e51a47..52b8aa07 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -84,41 +84,40 @@ private: /* Shader parameters */ float firstRed_x_; float firstRed_y_; GLint attributeVertex_; GLint attributeTexture_; GLint textureUniformStep_; GLint textureUniformSize_; GLint textureUniformStrideFactor_; GLint textureUniformBayerFirstRed_; GLint textureUniformProjMatrix_; GLint textureUniformBayerDataIn_; /* Per-frame AWB gains */ GLint awbUniformDataIn_; /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ GLint ccmUniformDataIn_; /* Black Level compensation */ GLint blackLevelUniformDataIn_; /* Gamma */ GLint gammaUniformDataIn_; /* Contrast */ GLint contrastExpUniformDataIn_; Size nativeOutputSize_; - Rectangle window_; std::unique_ptr<SwStatsCpu> stats_; eGL egl_; uint32_t width_; uint32_t height_; GLint glFormat_; unsigned int bytesPerPixel_; uint32_t shaderStridePixels_; }; } /* namespace libcamera */