[libcamera-devel] [PATCH 09/11] apps: qcam: Add support for IPU3_Y10
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Apr 18 18:37:03 CEST 2023
Hi Dan,
On Mon, Apr 17, 2023 at 10:59:43AM +0100, Dan Scally wrote:
> On 19/03/2023 23:34, Laurent Pinchart wrote:
> > On Sat, Mar 18, 2023 at 11:40:12PM +0000, Daniel Scally via libcamera-devel wrote:
> >> Add support for the IPU3_Y10 format to the FormatConverter.
> >
> > Before reviewing this patch in details, I'd like to know if there would
> > be a way to use the ImgU to convert the IPU3-packed greyscale format to
> > a more standard format. Is this something you have considered ?
>
> Sorry for the delay on this. I had concluded some time ago that this
> wasn't possible, so I hadn't particularly considered it lately. Since
> you ask I have been double checking and the conclusion seems to hold -
> I talked to the ipu3/cio2 maintainers and my understanding from those
> conversations is that the Imgu supports bayer input only, and the CIO2
> can only output packed data, so I think we are stuck with this or
> something like this.
OK, thanks for checking.
> >> Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
> >> ---
> >> src/apps/qcam/format_converter.cpp | 50 ++++++++++++++++++++++++++++++
> >> src/apps/qcam/format_converter.h | 2 ++
> >> 2 files changed, 52 insertions(+)
> >>
> >> diff --git a/src/apps/qcam/format_converter.cpp b/src/apps/qcam/format_converter.cpp
> >> index de76b32c..7f5648f3 100644
> >> --- a/src/apps/qcam/format_converter.cpp
> >> +++ b/src/apps/qcam/format_converter.cpp
> >> @@ -169,6 +169,10 @@ int FormatConverter::configure(const libcamera::PixelFormat &format,
> >> formatFamily_ = MJPEG;
> >> break;
> >>
> >> + case libcamera::formats::Y10_IPU3:
> >> + formatFamily_ = IPU3Packed;
> >> + break;
> >> +
> >> default:
> >> return -EINVAL;
> >> };
> >> @@ -199,6 +203,9 @@ void FormatConverter::convert(const Image *src, size_t size, QImage *dst)
> >> case YUVPlanar:
> >> convertYUVPlanar(src, dst->bits());
> >> break;
> >> + case IPU3Packed:
> >> + convertIPU3Packed(src, dst->bits(), size);
> >> + break;
Will we need to soon write a generic-purpose format conversion library ?
:-(
> >> };
> >> }
> >>
> >> @@ -357,3 +364,46 @@ void FormatConverter::convertYUVSemiPlanar(const Image *srcImage, unsigned char
> >> }
> >> }
> >> }
> >> +
> >> +void FormatConverter::convertIPU3Packed(const Image *srcImage, unsigned char *dst, size_t size)
> >> +{
> >> + const unsigned char *src = srcImage->data(0).data();
> >> + unsigned int bytesprocessed = 0;
> >> + unsigned int lsb_shift;
> >> + unsigned int msb_shift;
> >> + unsigned int index;
> >> + unsigned int x = 0;
> >> + uint16_t pixel;
> >> +
> >> + while (bytesprocessed < size) {
> >> + for (unsigned int i = 0; i < 25; ++i) {
> >> + index = (i * 10) / 8;
> >> + lsb_shift = (i * 10) % 8;
> >> + msb_shift = 8 - lsb_shift;
> >> +
> >> + /*
> >> + * The IPU3-packed format can result in padding at the
> >> + * end of a 32-byte block if the last pixel in a row is
> >> + * within that block. Check whether we're on the line's
> >> + * last pixel and skip the rest of the block if so.
> >> + */
> >> + if (x == width_) {
> >> + x = 0;
> >> + dst += width_ * 4;
> >> + break;
> >> + }
> >> +
> >> + pixel = (((src + bytesprocessed)[index+1] << msb_shift) & 0x3ff)
> >> + | (((src + bytesprocessed)[index+0] >> lsb_shift) & 0x3ff);
> >> +
> >> + dst[4 * x + 0] = (pixel >> 2) & 0xff;
> >> + dst[4 * x + 1] = (pixel >> 2) & 0xff;
> >> + dst[4 * x + 2] = (pixel >> 2) & 0xff;
> >> + dst[4 * x + 3] = 0xff;
> >> +
> >> + x++;
> >> + }
> >> +
> >> + bytesprocessed += 32;
There's probably room for improvement when it comes to efficiency here.
We can optimize the code later, but I wonder if
pixel = ((src[index+1] << msb_shift) & 0x3ff)
| ((src[index+0] >> lsb_shift) & 0x3ff);
...
bytesprocessed += 32;
src += 32;
couldn't help already. Doing something similar with dst to avoid the 4*x
offset could also possibly help.
> >> + }
> >> +}
> >> diff --git a/src/apps/qcam/format_converter.h b/src/apps/qcam/format_converter.h
> >> index 37dbfae2..940f8b6b 100644
> >> --- a/src/apps/qcam/format_converter.h
> >> +++ b/src/apps/qcam/format_converter.h
> >> @@ -31,12 +31,14 @@ private:
> >> YUVPacked,
> >> YUVPlanar,
> >> YUVSemiPlanar,
> >> + IPU3Packed,
> >> };
> >>
> >> 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);
> >> + void convertIPU3Packed(const Image *src, unsigned char *dst, size_t size);
> >>
> >> libcamera::PixelFormat format_;
> >> unsigned int width_;
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list