summaryrefslogtreecommitdiff
path: root/src/android/camera_stream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/camera_stream.cpp')
-rw-r--r--src/android/camera_stream.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp
index b3d345af..e86a7ba6 100644
--- a/src/android/camera_stream.cpp
+++ b/src/android/camera_stream.cpp
@@ -8,11 +8,15 @@
#include "camera_stream.h"
#include "camera_device.h"
+#include "camera_metadata.h"
#include "jpeg/encoder.h"
#include "jpeg/encoder_libjpeg.h"
+#include "jpeg/exif.h"
using namespace libcamera;
+LOG_DECLARE_CATEGORY(HAL);
+
CameraStream::CameraStream(CameraDevice *cameraDevice,
camera3_stream_t *camera3Stream,
const libcamera::StreamConfiguration &cfg,
@@ -36,3 +40,62 @@ int CameraStream::configure(const libcamera::StreamConfiguration &cfg)
return 0;
}
+
+int CameraStream::process(const libcamera::FrameBuffer &source,
+ MappedCamera3Buffer *dest, CameraMetadata *metadata)
+{
+ if (!encoder_)
+ return 0;
+
+ /* Set EXIF metadata for various tags. */
+ Exif exif;
+ /* \todo Set Make and Model from external vendor tags. */
+ exif.setMake("libcamera");
+ exif.setModel("cameraModel");
+ exif.setOrientation(cameraDevice_->orientation());
+ exif.setSize(size_);
+ /*
+ * We set the frame's EXIF timestamp as the time of encode.
+ * Since the precision we need for EXIF timestamp is only one
+ * second, it is good enough.
+ */
+ exif.setTimestamp(std::time(nullptr));
+ if (exif.generate() != 0)
+ LOG(HAL, Error) << "Failed to generate valid EXIF data";
+
+ int jpeg_size = encoder_->encode(&source, dest->maps()[0], exif.data());
+ if (jpeg_size < 0) {
+ LOG(HAL, Error) << "Failed to encode stream image";
+ return jpeg_size;
+ }
+
+ /*
+ * Fill in the JPEG blob header.
+ *
+ * The mapped size of the buffer is being returned as
+ * substantially larger than the requested JPEG_MAX_SIZE
+ * (which is referenced from maxJpegBufferSize_). Utilise
+ * this static size to ensure the correct offset of the blob is
+ * determined.
+ *
+ * \todo Investigate if the buffer size mismatch is an issue or
+ * expected behaviour.
+ */
+ uint8_t *resultPtr = dest->maps()[0].data() +
+ cameraDevice_->maxJpegBufferSize() -
+ sizeof(struct camera3_jpeg_blob);
+ auto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr);
+ blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
+ blob->jpeg_size = jpeg_size;
+
+ /* Update the JPEG result Metadata. */
+ metadata->addEntry(ANDROID_JPEG_SIZE, &jpeg_size, 1);
+
+ const uint32_t jpeg_quality = 95;
+ metadata->addEntry(ANDROID_JPEG_QUALITY, &jpeg_quality, 1);
+
+ const uint32_t jpeg_orientation = 0;
+ metadata->addEntry(ANDROID_JPEG_ORIENTATION, &jpeg_orientation, 1);
+
+ return 0;
+}