diff options
Diffstat (limited to 'src/android/camera_stream.cpp')
-rw-r--r-- | src/android/camera_stream.cpp | 63 |
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; +} |