summaryrefslogtreecommitdiff
path: root/src/android/camera_stream.cpp
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2020-10-03 11:28:47 +0200
committerJacopo Mondi <jacopo@jmondi.org>2020-10-07 16:07:44 +0200
commit9e95d5e4531039f8e21c65ea88be9ad6aaa1ced0 (patch)
treeddfafef1ab03c7fe27e181233a8ccd4e9ea56f63 /src/android/camera_stream.cpp
parent160bb0998bc47abefeb876be1ecbff9534960dbc (diff)
android: camera_device: Move processing to CameraStream
Move the JPEG processing procedure to the individual CameraStream by augmenting the class with a CameraStream::process() method. This allows removing the CameraStream::encoder() method. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
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;
+}