[libcamera-devel] [PATCH v9 4/8] android: jpeg: Add an internal Encoder class in EncoderLibJpeg

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Jan 16 01:28:04 CET 2023


From: Harvey Yang <chenghaoyang at chromium.org>

To move the thumbnail encoder into EncoderLibJpeg in the following
patch, this patch adds a wrapper/internal Encoder class that allows
EncoderLibJpeg to have more than one encoder to tackle encoding of both
captured images and their thumbnails.

Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/android/jpeg/encoder_libjpeg.cpp | 57 ++++++++++++++++++----------
 src/android/jpeg/encoder_libjpeg.h   | 30 +++++++++++----
 2 files changed, 59 insertions(+), 28 deletions(-)

diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp
index fd62bd9c7c5b..69fd91122aa6 100644
--- a/src/android/jpeg/encoder_libjpeg.cpp
+++ b/src/android/jpeg/encoder_libjpeg.cpp
@@ -68,7 +68,35 @@ const struct JPEGPixelFormatInfo &findPixelInfo(const PixelFormat &format)
 
 } /* namespace */
 
-EncoderLibJpeg::EncoderLibJpeg()
+EncoderLibJpeg::EncoderLibJpeg() = default;
+EncoderLibJpeg::~EncoderLibJpeg() = default;
+
+int EncoderLibJpeg::configure(const StreamConfiguration &cfg)
+{
+	return encoder_.configure(cfg);
+}
+
+int EncoderLibJpeg::encode(const FrameBuffer &source, Span<uint8_t> dest,
+			   Span<const uint8_t> exifData, unsigned int quality)
+{
+	MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);
+	if (!frame.isValid()) {
+		LOG(JPEG, Error) << "Failed to map FrameBuffer: "
+				 << strerror(frame.error());
+		return frame.error();
+	}
+
+	return encoder_.encode(frame.planes(), dest, exifData, quality);
+}
+
+int EncoderLibJpeg::encode(const std::vector<Span<uint8_t>> &src,
+			   Span<uint8_t> dest, Span<const uint8_t> exifData,
+			   unsigned int quality)
+{
+	return encoder_.encode(src, dest, exifData, quality);
+}
+
+EncoderLibJpeg::Encoder::Encoder()
 {
 	/* \todo Expand error handling coverage with a custom handler. */
 	compress_.err = jpeg_std_error(&jerr_);
@@ -76,12 +104,12 @@ EncoderLibJpeg::EncoderLibJpeg()
 	jpeg_create_compress(&compress_);
 }
 
-EncoderLibJpeg::~EncoderLibJpeg()
+EncoderLibJpeg::Encoder::~Encoder()
 {
 	jpeg_destroy_compress(&compress_);
 }
 
-int EncoderLibJpeg::configure(const StreamConfiguration &cfg)
+int EncoderLibJpeg::Encoder::configure(const StreamConfiguration &cfg)
 {
 	const struct JPEGPixelFormatInfo info = findPixelInfo(cfg.pixelFormat);
 	if (info.colorSpace == JCS_UNKNOWN)
@@ -103,7 +131,7 @@ int EncoderLibJpeg::configure(const StreamConfiguration &cfg)
 	return 0;
 }
 
-void EncoderLibJpeg::compressRGB(const std::vector<Span<uint8_t>> &planes)
+void EncoderLibJpeg::Encoder::compressRGB(const std::vector<Span<uint8_t>> &planes)
 {
 	unsigned char *src = const_cast<unsigned char *>(planes[0].data());
 	/* \todo Stride information should come from buffer configuration. */
@@ -121,7 +149,7 @@ void EncoderLibJpeg::compressRGB(const std::vector<Span<uint8_t>> &planes)
  * Compress the incoming buffer from a supported NV format.
  * This naively unpacks the semi-planar NV12 to a YUV888 format for libjpeg.
  */
-void EncoderLibJpeg::compressNV(const std::vector<Span<uint8_t>> &planes)
+void EncoderLibJpeg::Encoder::compressNV(const std::vector<Span<uint8_t>> &planes)
 {
 	uint8_t tmprowbuf[compress_.image_width * 3];
 
@@ -178,22 +206,9 @@ void EncoderLibJpeg::compressNV(const std::vector<Span<uint8_t>> &planes)
 	}
 }
 
-int EncoderLibJpeg::encode(const FrameBuffer &source, Span<uint8_t> dest,
-			   Span<const uint8_t> exifData, unsigned int quality)
-{
-	MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);
-	if (!frame.isValid()) {
-		LOG(JPEG, Error) << "Failed to map FrameBuffer : "
-				 << strerror(frame.error());
-		return frame.error();
-	}
-
-	return encode(frame.planes(), dest, exifData, quality);
-}
-
-int EncoderLibJpeg::encode(const std::vector<Span<uint8_t>> &src,
-			   Span<uint8_t> dest, Span<const uint8_t> exifData,
-			   unsigned int quality)
+int EncoderLibJpeg::Encoder::encode(const std::vector<Span<uint8_t>> &src,
+				    Span<uint8_t> dest, Span<const uint8_t> exifData,
+				    unsigned int quality)
 {
 	unsigned char *destination = dest.data();
 	unsigned long size = dest.size();
diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h
index 1b3ac067a1c0..eba591633cbb 100644
--- a/src/android/jpeg/encoder_libjpeg.h
+++ b/src/android/jpeg/encoder_libjpeg.h
@@ -32,14 +32,30 @@ public:
 		   unsigned int quality);
 
 private:
-	void compressRGB(const std::vector<libcamera::Span<uint8_t>> &planes);
-	void compressNV(const std::vector<libcamera::Span<uint8_t>> &planes);
+	class Encoder
+	{
+	public:
+		Encoder();
+		~Encoder();
 
-	struct jpeg_compress_struct compress_;
-	struct jpeg_error_mgr jerr_;
+		int configure(const libcamera::StreamConfiguration &cfg);
+		int encode(const std::vector<libcamera::Span<uint8_t>> &planes,
+			   libcamera::Span<uint8_t> destination,
+			   libcamera::Span<const uint8_t> exifData,
+			   unsigned int quality);
 
-	const libcamera::PixelFormatInfo *pixelFormatInfo_;
+	private:
+		void compressRGB(const std::vector<libcamera::Span<uint8_t>> &planes);
+		void compressNV(const std::vector<libcamera::Span<uint8_t>> &planes);
 
-	bool nv_;
-	bool nvSwap_;
+		struct jpeg_compress_struct compress_;
+		struct jpeg_error_mgr jerr_;
+
+		const libcamera::PixelFormatInfo *pixelFormatInfo_;
+
+		bool nv_;
+		bool nvSwap_;
+	};
+
+	Encoder encoder_;
 };
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list