[libcamera-devel] [PATCH v3 3/4] qcam: viewfinder_gl: Add support for RAW12 packed formats
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Jun 15 02:48:15 CEST 2021
Hi Andrey,
Thank you for the patch.
On Fri, Jun 11, 2021 at 07:27:25PM +0300, Andrey Konovalov wrote:
> All the four Bayer orders are supported.
> The 4 LS bits of the 12-bit colour values are dropped as the RGBA
> format we convert into has only 8 bits per colour.
>
> Signed-off-by: Andrey Konovalov <andrey.konovalov at linaro.org>
> ---
> src/qcam/assets/shader/bayer_1x_packed.frag | 43 +++++++++++++++---
> src/qcam/viewfinder_gl.cpp | 48 ++++++++++++++++++---
> 2 files changed, 80 insertions(+), 11 deletions(-)
>
> diff --git a/src/qcam/assets/shader/bayer_1x_packed.frag b/src/qcam/assets/shader/bayer_1x_packed.frag
> index 0a87c6db..d09c6fce 100644
> --- a/src/qcam/assets/shader/bayer_1x_packed.frag
> +++ b/src/qcam/assets/shader/bayer_1x_packed.frag
> @@ -23,6 +23,40 @@
> precision mediump float;
> #endif
>
> +/*
> + * These constants are used to select the bytes containing the HS part of
> + * the pixel value:
> + * BPP - bytes per pixel,
> + * THRESHOLD_L = fract(BPP) * 0.5 + 0.02
> + * THRESHOLD_H = 1.0 - fract(BPP) * 1.5 + 0.02
> + * Let X is the x coordinate in the texture measured in bytes (so that the
> + * range is from 0 to (stride_-1)) aligned on the nearest pixel.
> + * E.g. for RAW10P:
> + * -------------+-------------------+-------------------+--
> + * pixel No | 0 1 2 3 | 4 5 6 7 | ...
> + * -------------+-------------------+-------------------+--
> + * byte offset | 0 1 2 3 4 | 5 6 7 8 9 | ...
> + * -------------+-------------------+-------------------+--
> + * X | 0.0 1.25 2.5 3.75 | 5.0 6.25 7.5 8.75 | ...
> + * -------------+-------------------+-------------------+--
> + * If fract(X) < THRESHOLD_L then the previous byte contains the LS
> + * bits of the pixel values and needs to be skipped.
> + * If fract(X) > THRESHOLD_H then the next byte contains the LS bits
> + * of the pixel values and needs to be skipped.
> + */
> +#if defined(RAW10P)
> +#define BPP 1.25
> +#define THRESHOLD_L 0.14
> +#define THRESHOLD_H 0.64
With the values aligned:
#define BPP 1.25
#define THRESHOLD_L 0.14
#define THRESHOLD_H 0.64
(and same below),
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> +#elif defined(RAW12P)
> +#define BPP 1.5
> +#define THRESHOLD_L 0.27
> +#define THRESHOLD_H 0.27
> +#else
> +#error Invalid raw format
> +#endif
> +
> +
> varying vec2 textureOut;
>
> /* the texture size: tex_size.xy is in bytes, tex_size.zw is in pixels */
> @@ -64,10 +98,7 @@ void main(void)
> * Add a small number (a few mantissa's LSBs) to avoid float
> * representation issues. Maybe paranoic.
> */
> - center.x = BPP_X * center.z + 0.02;
> -
> - const float threshold_l = 0.127 /* fract(BPP_X) * 0.5 + 0.02 */;
> - const float threshold_h = 0.625 /* 1.0 - fract(BPP_X) * 1.5 */;
> + center.x = BPP * center.z + 0.02;
>
> float fract_x = fract(center.x);
> /*
> @@ -86,13 +117,13 @@ void main(void)
> * of the previous group of the pixels, move xcoords[0] one
> * byte back.
> */
> - xcoords[0] += (fract_x < threshold_l) ? -tex_step.x : 0.0;
> + xcoords[0] += (fract_x < THRESHOLD_L) ? -tex_step.x : 0.0;
> /*
> * If xcoords[1] points at the byte containing the LS bits
> * of the current group of the pixels, move xcoords[1] one
> * byte forward.
> */
> - xcoords[1] += (fract_x > threshold_h) ? tex_step.x : 0.0;
> + xcoords[1] += (fract_x > THRESHOLD_H) ? tex_step.x : 0.0;
>
> vec2 alternate = mod(center.zw + tex_bayer_first_red, 2.0);
> bool even_col = alternate.x < 1.0;
> diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp
> index 44e410c9..dcfaf973 100644
> --- a/src/qcam/viewfinder_gl.cpp
> +++ b/src/qcam/viewfinder_gl.cpp
> @@ -41,6 +41,11 @@ static const QList<libcamera::PixelFormat> supportedFormats{
> libcamera::formats::SGBRG10_CSI2P,
> libcamera::formats::SGRBG10_CSI2P,
> libcamera::formats::SRGGB10_CSI2P,
> + /* Raw Bayer 12-bit packed */
> + libcamera::formats::SBGGR12_CSI2P,
> + libcamera::formats::SGBRG12_CSI2P,
> + libcamera::formats::SGRBG12_CSI2P,
> + libcamera::formats::SRGGB12_CSI2P,
> };
>
> ViewFinderGL::ViewFinderGL(QWidget *parent)
> @@ -218,28 +223,56 @@ bool ViewFinderGL::selectFormat(const libcamera::PixelFormat &format)
> case libcamera::formats::SBGGR10_CSI2P:
> firstRed_.setX(1.0);
> firstRed_.setY(1.0);
> - fragmentShaderDefines_.append("#define BPP_X 1.25");
> + fragmentShaderDefines_.append("#define RAW10P");
> fragmentShaderFile_ = ":bayer_1x_packed.frag";
> textureMinMagFilters_ = GL_NEAREST;
> break;
> case libcamera::formats::SGBRG10_CSI2P:
> firstRed_.setX(0.0);
> firstRed_.setY(1.0);
> - fragmentShaderDefines_.append("#define BPP_X 1.25");
> + fragmentShaderDefines_.append("#define RAW10P");
> fragmentShaderFile_ = ":bayer_1x_packed.frag";
> textureMinMagFilters_ = GL_NEAREST;
> break;
> case libcamera::formats::SGRBG10_CSI2P:
> firstRed_.setX(1.0);
> firstRed_.setY(0.0);
> - fragmentShaderDefines_.append("#define BPP_X 1.25");
> + fragmentShaderDefines_.append("#define RAW10P");
> fragmentShaderFile_ = ":bayer_1x_packed.frag";
> textureMinMagFilters_ = GL_NEAREST;
> break;
> case libcamera::formats::SRGGB10_CSI2P:
> firstRed_.setX(0.0);
> firstRed_.setY(0.0);
> - fragmentShaderDefines_.append("#define BPP_X 1.25");
> + fragmentShaderDefines_.append("#define RAW10P");
> + fragmentShaderFile_ = ":bayer_1x_packed.frag";
> + textureMinMagFilters_ = GL_NEAREST;
> + break;
> + case libcamera::formats::SBGGR12_CSI2P:
> + firstRed_.setX(1.0);
> + firstRed_.setY(1.0);
> + fragmentShaderDefines_.append("#define RAW12P");
> + fragmentShaderFile_ = ":bayer_1x_packed.frag";
> + textureMinMagFilters_ = GL_NEAREST;
> + break;
> + case libcamera::formats::SGBRG12_CSI2P:
> + firstRed_.setX(0.0);
> + firstRed_.setY(1.0);
> + fragmentShaderDefines_.append("#define RAW12P");
> + fragmentShaderFile_ = ":bayer_1x_packed.frag";
> + textureMinMagFilters_ = GL_NEAREST;
> + break;
> + case libcamera::formats::SGRBG12_CSI2P:
> + firstRed_.setX(1.0);
> + firstRed_.setY(0.0);
> + fragmentShaderDefines_.append("#define RAW12P");
> + fragmentShaderFile_ = ":bayer_1x_packed.frag";
> + textureMinMagFilters_ = GL_NEAREST;
> + break;
> + case libcamera::formats::SRGGB12_CSI2P:
> + firstRed_.setX(0.0);
> + firstRed_.setY(0.0);
> + fragmentShaderDefines_.append("#define RAW12P");
> fragmentShaderFile_ = ":bayer_1x_packed.frag";
> textureMinMagFilters_ = GL_NEAREST;
> break;
> @@ -595,8 +628,13 @@ void ViewFinderGL::doRender()
> case libcamera::formats::SGBRG10_CSI2P:
> case libcamera::formats::SGRBG10_CSI2P:
> case libcamera::formats::SRGGB10_CSI2P:
> + case libcamera::formats::SBGGR12_CSI2P:
> + case libcamera::formats::SGBRG12_CSI2P:
> + case libcamera::formats::SGRBG12_CSI2P:
> + case libcamera::formats::SRGGB12_CSI2P:
> /*
> - * Packed raw Bayer 10-bit formats are stored in GL_RED texture.
> + * Packed raw Bayer 10-bit and 12-bit formats are stored in
> + * GL_RED texture.
> * The texture width is equal to the stride.
> */
> glActiveTexture(GL_TEXTURE0);
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list