@@ -103,9 +103,10 @@ int EncoderLibJpeg::configure(const StreamConfiguration &cfg)
return 0;
}
-void EncoderLibJpeg::compressRGB(Span<const uint8_t> frame)
+void EncoderLibJpeg::compressRGB(const MappedBuffer &frame)
{
- unsigned char *src = const_cast<unsigned char *>(frame.data());
+ ASSERT(frame.planes().size() == 1);
+ unsigned char *src = const_cast<unsigned char *>(frame.planes()[0].data());
/* \todo Stride information should come from buffer configuration. */
unsigned int stride = pixelFormatInfo_->stride(compress_.image_width, 0);
@@ -121,7 +122,7 @@ void EncoderLibJpeg::compressRGB(Span<const uint8_t> frame)
* 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(Span<const uint8_t> frame)
+void EncoderLibJpeg::compressNV(const MappedBuffer &frame)
{
uint8_t tmprowbuf[compress_.image_width * 3];
@@ -143,8 +144,9 @@ void EncoderLibJpeg::compressNV(Span<const uint8_t> frame)
unsigned int cb_pos = nvSwap_ ? 1 : 0;
unsigned int cr_pos = nvSwap_ ? 0 : 1;
- const unsigned char *src = frame.data();
- const unsigned char *src_c = src + y_stride * compress_.image_height;
+ ASSERT(frame.planes().size() == 2);
+ const unsigned char *src = frame.planes()[0].data();
+ const unsigned char *src_c = frame.planes()[1].data();
JSAMPROW row_pointer[1];
row_pointer[0] = &tmprowbuf[0];
@@ -152,7 +154,7 @@ void EncoderLibJpeg::compressNV(Span<const uint8_t> frame)
for (unsigned int y = 0; y < compress_.image_height; y++) {
unsigned char *dst = &tmprowbuf[0];
- const unsigned char *src_y = src + y * compress_.image_width;
+ const unsigned char *src_y = src + y * y_stride;
const unsigned char *src_cb = src_c + (y / vertSubSample) * c_stride + cb_pos;
const unsigned char *src_cr = src_c + (y / vertSubSample) * c_stride + cr_pos;
@@ -178,8 +180,10 @@ void EncoderLibJpeg::compressNV(Span<const uint8_t> frame)
}
}
-int EncoderLibJpeg::encode(const FrameBuffer &source, Span<uint8_t> dest,
- Span<const uint8_t> exifData, unsigned int quality)
+int EncoderLibJpeg::encode(const libcamera::FrameBuffer &source,
+ libcamera::Span<uint8_t> destination,
+ libcamera::Span<const uint8_t> exifData,
+ unsigned int quality)
{
MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);
if (!frame.isValid()) {
@@ -188,10 +192,10 @@ int EncoderLibJpeg::encode(const FrameBuffer &source, Span<uint8_t> dest,
return frame.error();
}
- return encode(frame.planes()[0], dest, exifData, quality);
+ return encode(frame, destination, exifData, quality);
}
-int EncoderLibJpeg::encode(Span<const uint8_t> src, Span<uint8_t> dest,
+int EncoderLibJpeg::encode(const MappedBuffer &source, Span<uint8_t> dest,
Span<const uint8_t> exifData, unsigned int quality)
{
unsigned char *destination = dest.data();
@@ -221,9 +225,9 @@ int EncoderLibJpeg::encode(Span<const uint8_t> src, Span<uint8_t> dest,
<< "x" << compress_.image_height;
if (nv_)
- compressNV(src);
+ compressNV(source);
else
- compressRGB(src);
+ compressRGB(source);
jpeg_finish_compress(&compress_);
@@ -10,6 +10,7 @@
#include "encoder.h"
#include "libcamera/internal/formats.h"
+#include "libcamera/internal/mapped_framebuffer.h"
#include <jpeglib.h>
@@ -24,14 +25,14 @@ public:
libcamera::Span<uint8_t> destination,
libcamera::Span<const uint8_t> exifData,
unsigned int quality) override;
- int encode(libcamera::Span<const uint8_t> source,
+ int encode(const libcamera::MappedBuffer &source,
libcamera::Span<uint8_t> destination,
libcamera::Span<const uint8_t> exifData,
unsigned int quality);
private:
- void compressRGB(libcamera::Span<const uint8_t> frame);
- void compressNV(libcamera::Span<const uint8_t> frame);
+ void compressRGB(const libcamera::MappedBuffer &frame);
+ void compressNV(const libcamera::MappedBuffer &frame);
struct jpeg_compress_struct compress_;
struct jpeg_error_mgr jerr_;
@@ -75,8 +75,7 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source,
bufferSize += plane.size();
thumbnail->resize(bufferSize);
- libcamera::Span rawThumbnailData(rawThumbnail->planes()[0].data(), bufferSize);
- int jpeg_size = thumbnailEncoder_.encode(rawThumbnailData,
+ int jpeg_size = thumbnailEncoder_.encode(*rawThumbnail,
*thumbnail, {}, quality);
thumbnail->resize(jpeg_size);
@@ -181,7 +180,8 @@ int PostProcessorJpeg::process(const FrameBuffer &source,
const uint8_t quality = ret ? *entry.data.u8 : 95;
resultMetadata->addEntry(ANDROID_JPEG_QUALITY, quality);
- int jpeg_size = encoder_->encode(source, destination->plane(0),
+ int jpeg_size = encoder_->encode(source,
+ destination->plane(0),
exif.data(), quality);
if (jpeg_size < 0) {
LOG(JPEG, Error) << "Failed to encode stream image";
EncoderLibJpeg handles the source frame with Span<const uint8_t>. Since it is plane, MappedBuffer should be more appropriate interface for it. So this changes its type to MappedBuffer. Signed-off-by: Hirokazu Honda <hiroh@chromium.org> --- src/android/jpeg/encoder_libjpeg.cpp | 28 ++++++++++++++---------- src/android/jpeg/encoder_libjpeg.h | 7 +++--- src/android/jpeg/post_processor_jpeg.cpp | 6 ++--- 3 files changed, 23 insertions(+), 18 deletions(-)