[libcamera-devel] [PATCH v9 6/8] android: jpeg: Return an error code from generateThumbnail()
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Mon Jan 16 01:28:06 CET 2023
The usual way to signal errors in libcamera is to return an error code.
Change the Encoder::generateThumbnail() function to return an int
instead of signaling errors by not resizing the thumbnail vector. This
allows propagating error codes to the callers.
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
src/android/jpeg/encoder.h | 8 +--
src/android/jpeg/encoder_libjpeg.cpp | 70 +++++++++++++-----------
src/android/jpeg/encoder_libjpeg.h | 8 +--
src/android/jpeg/post_processor_jpeg.cpp | 6 +-
4 files changed, 48 insertions(+), 44 deletions(-)
diff --git a/src/android/jpeg/encoder.h b/src/android/jpeg/encoder.h
index 5f9ef890023a..d15f22e67830 100644
--- a/src/android/jpeg/encoder.h
+++ b/src/android/jpeg/encoder.h
@@ -22,8 +22,8 @@ public:
libcamera::Span<uint8_t> destination,
libcamera::Span<const uint8_t> exifData,
unsigned int quality) = 0;
- virtual void generateThumbnail(const libcamera::FrameBuffer &source,
- const libcamera::Size &targetSize,
- unsigned int quality,
- std::vector<unsigned char> *thumbnail) = 0;
+ virtual int generateThumbnail(const libcamera::FrameBuffer &source,
+ const libcamera::Size &targetSize,
+ unsigned int quality,
+ std::vector<unsigned char> *thumbnail) = 0;
};
diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp
index 9bbf1abbe09c..8f4df7899dfd 100644
--- a/src/android/jpeg/encoder_libjpeg.cpp
+++ b/src/android/jpeg/encoder_libjpeg.cpp
@@ -89,53 +89,57 @@ int EncoderLibJpeg::encode(const FrameBuffer &source, Span<uint8_t> dest,
return captureEncoder_.encode(frame.planes(), dest, exifData, quality);
}
-void EncoderLibJpeg::generateThumbnail(const libcamera::FrameBuffer &source,
- const libcamera::Size &targetSize,
- unsigned int quality,
- std::vector<unsigned char> *thumbnail)
+int EncoderLibJpeg::generateThumbnail(const libcamera::FrameBuffer &source,
+ const libcamera::Size &targetSize,
+ unsigned int quality,
+ std::vector<unsigned char> *thumbnail)
{
/* Stores the raw scaled-down thumbnail bytes. */
std::vector<unsigned char> rawThumbnail;
thumbnailer_.createThumbnail(source, targetSize, &rawThumbnail);
+ if (rawThumbnail.empty())
+ return -EINVAL;
StreamConfiguration thCfg;
thCfg.size = targetSize;
thCfg.pixelFormat = thumbnailer_.pixelFormat();
int ret = thumbnailEncoder_.configure(thCfg);
+ if (ret)
+ return ret;
- if (!rawThumbnail.empty() && !ret) {
- /*
- * \todo Avoid value-initialization of all elements of the
- * vector.
- */
- thumbnail->resize(rawThumbnail.size());
+ /*
+ * \todo Avoid value-initialization of all elements of the
+ * vector.
+ */
+ thumbnail->resize(rawThumbnail.size());
- /*
- * Split planes manually as the encoder expects a vector of
- * planes.
- *
- * \todo Pass a vector of planes directly to
- * Thumbnailer::createThumbnailer above and remove the manual
- * planes split from here.
- */
- std::vector<Span<uint8_t>> thumbnailPlanes;
- const PixelFormatInfo &formatNV12 =
- PixelFormatInfo::info(formats::NV12);
- size_t yPlaneSize = formatNV12.planeSize(targetSize, 0);
- size_t uvPlaneSize = formatNV12.planeSize(targetSize, 1);
- thumbnailPlanes.push_back({ rawThumbnail.data(), yPlaneSize });
- thumbnailPlanes.push_back({ rawThumbnail.data() + yPlaneSize,
- uvPlaneSize });
+ /*
+ * Split planes manually as the encoder expects a vector of
+ * planes.
+ *
+ * \todo Pass a vector of planes directly to
+ * Thumbnailer::createThumbnailer above and remove the manual
+ * planes split from here.
+ */
+ std::vector<Span<uint8_t>> thumbnailPlanes;
+ const PixelFormatInfo &formatNV12 =
+ PixelFormatInfo::info(formats::NV12);
+ size_t yPlaneSize = formatNV12.planeSize(targetSize, 0);
+ size_t uvPlaneSize = formatNV12.planeSize(targetSize, 1);
+ thumbnailPlanes.push_back({ rawThumbnail.data(), yPlaneSize });
+ thumbnailPlanes.push_back({ rawThumbnail.data() + yPlaneSize,
+ uvPlaneSize });
- int jpegSize = thumbnailEncoder_.encode(thumbnailPlanes, *thumbnail,
- {}, quality);
- thumbnail->resize(jpegSize);
+ int jpegSize = thumbnailEncoder_.encode(thumbnailPlanes, *thumbnail,
+ {}, quality);
+ thumbnail->resize(jpegSize);
- LOG(JPEG, Debug)
- << "Thumbnail compress returned "
- << jpegSize << " bytes";
- }
+ LOG(JPEG, Debug)
+ << "Thumbnail compress returned "
+ << jpegSize << " bytes";
+
+ return 0;
}
EncoderLibJpeg::Encoder::Encoder()
diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h
index a022a72e02bf..9cff4f1b42e3 100644
--- a/src/android/jpeg/encoder_libjpeg.h
+++ b/src/android/jpeg/encoder_libjpeg.h
@@ -28,10 +28,10 @@ public:
libcamera::Span<uint8_t> destination,
libcamera::Span<const uint8_t> exifData,
unsigned int quality) override;
- void generateThumbnail(const libcamera::FrameBuffer &source,
- const libcamera::Size &targetSize,
- unsigned int quality,
- std::vector<unsigned char> *thumbnail) override;
+ int generateThumbnail(const libcamera::FrameBuffer &source,
+ const libcamera::Size &targetSize,
+ unsigned int quality,
+ std::vector<unsigned char> *thumbnail) override;
private:
class Encoder
diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp
index 69b18a2e5945..5df89383e1af 100644
--- a/src/android/jpeg/post_processor_jpeg.cpp
+++ b/src/android/jpeg/post_processor_jpeg.cpp
@@ -115,9 +115,9 @@ void PostProcessorJpeg::process(Camera3RequestDescriptor::StreamBuffer *streamBu
if (thumbnailSize != Size(0, 0)) {
std::vector<unsigned char> thumbnail;
- encoder_->generateThumbnail(source, thumbnailSize,
- quality, &thumbnail);
- if (!thumbnail.empty())
+ ret = encoder_->generateThumbnail(source, thumbnailSize,
+ quality, &thumbnail);
+ if (!ret)
exif.setThumbnail(std::move(thumbnail), Exif::Compression::JPEG);
}
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list