@@ -9,8 +9,11 @@
#include "../camera_hal_manager.h"
+cros::CameraMojoChannelManagerToken *g_cros_camera_token = nullptr;
+
static void set_up([[maybe_unused]] cros::CameraMojoChannelManagerToken *token)
{
+ g_cros_camera_token = token;
}
static void tear_down()
new file mode 100644
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * cros_post_processor_jpeg.cpp - CrOS JPEG Post Processor
+ */
+
+#include "encoder_jea.h"
+#include "post_processor_jpeg.h"
+
+void PostProcessorJpeg::SetEncoder()
+{
+ encoder_ = std::make_unique<EncoderJea>();
+}
new file mode 100644
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * encoder_jea.cpp - JPEG encoding using CrOS JEA
+ */
+
+#include "encoder_jea.h"
+
+#include <libcamera/base/log.h>
+
+#include "libcamera/internal/mapped_framebuffer.h"
+
+#include <cros-camera/camera_mojo_channel_manager_token.h>
+
+#include "../android_framebuffer.h"
+
+extern cros::CameraMojoChannelManagerToken *g_cros_camera_token;
+
+EncoderJea::EncoderJea() = default;
+
+EncoderJea::~EncoderJea() = default;
+
+int EncoderJea::configure(const libcamera::StreamConfiguration &cfg)
+{
+ size_ = cfg.size;
+
+ if (jpeg_compressor_.get())
+ return 0;
+
+ if (g_cros_camera_token == nullptr)
+ return -ENOTSUP;
+
+ jpeg_compressor_ = cros::JpegCompressor::GetInstance(g_cros_camera_token);
+
+ return 0;
+}
+
+int EncoderJea::encode(Camera3RequestDescriptor::StreamBuffer *streamBuffer,
+ libcamera::Span<const uint8_t> exifData,
+ unsigned int quality)
+{
+ if (!jpeg_compressor_.get())
+ return -1;
+
+ uint32_t out_data_size = 0;
+
+ if (!jpeg_compressor_->CompressImageFromHandle(
+ dynamic_cast<const AndroidFrameBuffer *>(
+ streamBuffer->srcBuffer)
+ ->getHandle(),
+ *streamBuffer->camera3Buffer, size_.width, size_.height, quality,
+ exifData.data(), exifData.size(), &out_data_size)) {
+ return -1;
+ }
+
+ return out_data_size;
+}
+
+int EncoderJea::generateThumbnail(const libcamera::FrameBuffer &source,
+ const libcamera::Size &targetSize,
+ unsigned int quality,
+ std::vector<unsigned char> *thumbnail)
+{
+ if (!jpeg_compressor_.get())
+ return -1;
+
+ libcamera::MappedFrameBuffer frame(&source, libcamera::MappedFrameBuffer::MapFlag::Read);
+
+ if (frame.planes().empty())
+ return 0;
+
+ uint32_t out_data_size = 0;
+
+ if (!jpeg_compressor_->GenerateThumbnail(frame.planes()[0].data(),
+ size_.width, size_.height, targetSize.width, targetSize.height,
+ quality, thumbnail->size(), thumbnail->data(), &out_data_size)) {
+ return -1;
+ }
+
+ return out_data_size;
+}
new file mode 100644
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Google Inc.
+ *
+ * encoder_jea.h - JPEG encoding using CrOS JEA
+ */
+
+#pragma once
+
+#include <libcamera/geometry.h>
+
+#include <cros-camera/jpeg_compressor.h>
+
+#include "encoder.h"
+
+class EncoderJea : public Encoder
+{
+public:
+ EncoderJea();
+ ~EncoderJea();
+
+ int configure(const libcamera::StreamConfiguration &cfg) override;
+ int encode(Camera3RequestDescriptor::StreamBuffer *streamBuffer,
+ libcamera::Span<const uint8_t> exifData,
+ unsigned int quality) override;
+ int generateThumbnail(const libcamera::FrameBuffer &source,
+ const libcamera::Size &targetSize,
+ unsigned int quality,
+ std::vector<unsigned char> *thumbnail) override;
+
+private:
+ libcamera::Size size_;
+
+ std::unique_ptr<cros::JpegCompressor> jpeg_compressor_;
+};
@@ -4,6 +4,13 @@ android_hal_sources += files([
'exif.cpp',
'post_processor_jpeg.cpp'])
-android_hal_sources += files(['encoder_libjpeg.cpp',
- 'generic_post_processor_jpeg.cpp',
- 'thumbnailer.cpp'])
+platform = get_option('android_platform')
+if platform == 'generic'
+ android_hal_sources += files(['encoder_libjpeg.cpp',
+ 'generic_post_processor_jpeg.cpp',
+ 'thumbnailer.cpp'])
+elif platform == 'cros'
+ android_hal_sources += files(['cros_post_processor_jpeg.cpp',
+ 'encoder_jea.cpp'])
+ android_deps += [dependency('libcros_camera')]
+endif