[libcamera-devel] [PATCH 09/11] apps: qcam: Add support for IPU3_Y10

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Mar 20 00:34:04 CET 2023


Hi Dan,

Thank you for the patch.

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 ?

> 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;
>  	};
>  }
>  
> @@ -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;
> +	}
> +}
> 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