[libcamera-devel] [PATCH v2 4/5] qcam: format_converter: Add fully-planar YUV formats support
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Wed Sep 22 09:54:13 CEST 2021
Hi Paul,
On Wed, Sep 22, 2021 at 04:09:19PM +0900, paul.elder at ideasonboard.com wrote:
> On Tue, Sep 07, 2021 at 03:20:43AM +0300, Laurent Pinchart wrote:
> > Add support for the YUV420, YVU420 and YUV420 formats supported by
>
> YUV420 and YUV420? :p
Oops :-) I'll fix that.
> > libcamera. YUV420 can be produced by the Raspberry Pi pipeline handler,
> > being able to display it is useful for testing.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
>
> Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>
>
> > ---
> > src/qcam/format_converter.cpp | 66 +++++++++++++++++++++++++++++++++++
> > src/qcam/format_converter.h | 2 ++
> > 2 files changed, 68 insertions(+)
> >
> > diff --git a/src/qcam/format_converter.cpp b/src/qcam/format_converter.cpp
> > index 7979ea8a77ff..d4d3223bc698 100644
> > --- a/src/qcam/format_converter.cpp
> > +++ b/src/qcam/format_converter.cpp
> > @@ -8,6 +8,7 @@
> > #include "format_converter.h"
> >
> > #include <errno.h>
> > +#include <utility>
> >
> > #include <QImage>
> >
> > @@ -141,6 +142,25 @@ int FormatConverter::configure(const libcamera::PixelFormat &format,
> > cb_pos_ = 1;
> > break;
> >
> > + case libcamera::formats::YUV420:
> > + formatFamily_ = YUVPlanar;
> > + horzSubSample_ = 2;
> > + vertSubSample_ = 2;
> > + nvSwap_ = false;
> > + break;
> > + case libcamera::formats::YVU420:
> > + formatFamily_ = YUVPlanar;
> > + horzSubSample_ = 2;
> > + vertSubSample_ = 2;
> > + nvSwap_ = true;
> > + break;
> > + case libcamera::formats::YUV422:
> > + formatFamily_ = YUVPlanar;
> > + horzSubSample_ = 2;
> > + vertSubSample_ = 1;
> > + nvSwap_ = false;
> > + break;
> > +
> > case libcamera::formats::MJPEG:
> > formatFamily_ = MJPEG;
> > break;
> > @@ -172,6 +192,9 @@ void FormatConverter::convert(const Image *src, size_t size, QImage *dst)
> > case YUVSemiPlanar:
> > convertYUVSemiPlanar(src, dst->bits());
> > break;
> > + case YUVPlanar:
> > + convertYUVPlanar(src, dst->bits());
> > + break;
> > };
> > }
> >
> > @@ -247,6 +270,49 @@ void FormatConverter::convertYUVPacked(const Image *srcImage, unsigned char *dst
> > }
> > }
> >
> > +void FormatConverter::convertYUVPlanar(const Image *srcImage, unsigned char *dst)
> > +{
> > + unsigned int c_stride = stride_ / horzSubSample_;
> > + unsigned int c_inc = horzSubSample_ == 1 ? 1 : 0;
> > + const unsigned char *src_y = srcImage->data(0).data();
> > + const unsigned char *src_cb = srcImage->data(1).data();
> > + const unsigned char *src_cr = srcImage->data(2).data();
> > + int r, g, b;
> > +
> > + if (nvSwap_)
> > + std::swap(src_cb, src_cr);
> > +
> > + for (unsigned int y = 0; y < height_; y++) {
> > + const unsigned char *line_y = src_y + y * stride_;
> > + const unsigned char *line_cb = src_cb + (y / vertSubSample_) *
> > + c_stride;
> > + const unsigned char *line_cr = src_cr + (y / vertSubSample_) *
> > + c_stride;
> > +
> > + for (unsigned int x = 0; x < width_; x += 2) {
> > + yuv_to_rgb(*line_y, *line_cb, *line_cr, &r, &g, &b);
> > + dst[0] = b;
> > + dst[1] = g;
> > + dst[2] = r;
> > + dst[3] = 0xff;
> > + line_y++;
> > + line_cb += c_inc;
> > + line_cr += c_inc;
> > + dst += 4;
> > +
> > + yuv_to_rgb(*line_y, *line_cb, *line_cr, &r, &g, &b);
> > + dst[0] = b;
> > + dst[1] = g;
> > + dst[2] = r;
> > + dst[3] = 0xff;
> > + line_y++;
> > + line_cb += 1;
> > + line_cr += 1;
> > + dst += 4;
> > + }
> > + }
> > +}
> > +
> > void FormatConverter::convertYUVSemiPlanar(const Image *srcImage, unsigned char *dst)
> > {
> > unsigned int c_stride = stride_ * (2 / horzSubSample_);
> > diff --git a/src/qcam/format_converter.h b/src/qcam/format_converter.h
> > index 9ce2cc6da7f2..9da2df5d294b 100644
> > --- a/src/qcam/format_converter.h
> > +++ b/src/qcam/format_converter.h
> > @@ -29,11 +29,13 @@ private:
> > MJPEG,
> > RGB,
> > YUVPacked,
> > + YUVPlanar,
> > YUVSemiPlanar,
> > };
> >
> > void convertRGB(const Image *src, unsigned char *dst);
> > void convertYUVPacked(const Image *src, unsigned char *dst);
> > + void convertYUVPlanar(const Image *src, unsigned char *dst);
> > void convertYUVSemiPlanar(const Image *src, unsigned char *dst);
> >
> > libcamera::PixelFormat format_;
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list