From abfabdd6e769a58ccd9ff1e884528211904888d8 Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Sat, 23 Jan 2021 13:54:28 +0900 Subject: android: Set result metadata and EXIF fields based on request metadata Set the following android result metadata: - ANDROID_LENS_FOCAL_LENGTH - ANDROID_LENS_APERTURE - ANDROID_JPEG_GPS_TIMESTAMP - ANDROID_JPEG_GPS_COORDINATES - ANDROID_JPEG_GPS_PROCESSING_METHOD And the following EXIF fields: - GPSDatestamp - GPSTimestamp - GPSLocation - GPSLatitudeRef - GPSLatitude - GPSLongitudeRef - GPSLongitude - GPSAltitudeRef - GPSAltitude - GPSProcessingMethod - FocalLength - ExposureTime - FNumber - ISO - Flash - WhiteBalance - SubsecTime - SubsecTimeOriginal - SubsecTimeDigitized Based on android request metadata. This allows the following CTS tests to pass: - android.hardware.camera2.cts.StillCaptureTest#testFocalLengths - android.hardware.camera2.cts.StillCaptureTest#testJpegExif Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- src/android/jpeg/post_processor_jpeg.cpp | 63 ++++++++++++++++++++++++++------ src/android/jpeg/post_processor_jpeg.h | 3 +- 2 files changed, 54 insertions(+), 12 deletions(-) (limited to 'src/android/jpeg') diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index aa0f783d..7e49e9d9 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -83,17 +83,26 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source, int PostProcessorJpeg::process(const FrameBuffer &source, Span destination, - CameraMetadata *metadata) + const CameraMetadata &requestMetadata, + CameraMetadata *resultMetadata) { if (!encoder_) return 0; + camera_metadata_ro_entry_t entry; + int ret; + /* 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.setMake(cameraDevice_->maker()); + exif.setModel(cameraDevice_->model()); + + ret = requestMetadata.getEntry(ANDROID_JPEG_ORIENTATION, &entry); + + const uint32_t jpegOrientation = ret ? *entry.data.i32 : 0; + resultMetadata->addEntry(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1); + exif.setOrientation(jpegOrientation); + exif.setSize(streamSize_); /* * We set the frame's EXIF timestamp as the time of encode. @@ -102,6 +111,39 @@ int PostProcessorJpeg::process(const FrameBuffer &source, */ exif.setTimestamp(std::time(nullptr), 0ms); + /* \todo Get this information from libcamera::Request::metadata */ + exif.setExposureTime(0); + ret = requestMetadata.getEntry(ANDROID_LENS_APERTURE, &entry); + if (ret) + exif.setAperture(*entry.data.f); + exif.setISO(100); + exif.setFlash(Exif::Flash::FlashNotPresent); + exif.setWhiteBalance(Exif::WhiteBalance::Auto); + + exif.setFocalLength(1.0); + + ret = requestMetadata.getEntry(ANDROID_JPEG_GPS_TIMESTAMP, &entry); + if (ret) { + exif.setGPSDateTimestamp(*entry.data.i64); + resultMetadata->addEntry(ANDROID_JPEG_GPS_TIMESTAMP, + entry.data.i64, 1); + } + + ret = requestMetadata.getEntry(ANDROID_JPEG_GPS_COORDINATES, &entry); + if (ret) { + exif.setGPSLocation(entry.data.d); + resultMetadata->addEntry(ANDROID_JPEG_GPS_COORDINATES, + entry.data.d, 3); + } + + ret = requestMetadata.getEntry(ANDROID_JPEG_GPS_PROCESSING_METHOD, &entry); + if (ret) { + std::string method(entry.data.u8, entry.data.u8 + entry.count); + exif.setGPSMethod(method); + resultMetadata->addEntry(ANDROID_JPEG_GPS_PROCESSING_METHOD, + entry.data.u8, entry.count); + } + std::vector thumbnail; generateThumbnail(source, &thumbnail); if (!thumbnail.empty()) @@ -136,13 +178,12 @@ int PostProcessorJpeg::process(const FrameBuffer &source, 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); + resultMetadata->addEntry(ANDROID_JPEG_SIZE, &jpeg_size, 1); - const uint32_t jpeg_orientation = 0; - metadata->addEntry(ANDROID_JPEG_ORIENTATION, &jpeg_orientation, 1); + /* \todo Configure JPEG encoder with this */ + ret = requestMetadata.getEntry(ANDROID_JPEG_QUALITY, &entry); + const uint8_t jpegQuality = ret ? *entry.data.u8 : 95; + resultMetadata->addEntry(ANDROID_JPEG_QUALITY, &jpegQuality, 1); return 0; } diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h index 5afa831c..d721d1b9 100644 --- a/src/android/jpeg/post_processor_jpeg.h +++ b/src/android/jpeg/post_processor_jpeg.h @@ -26,7 +26,8 @@ public: const libcamera::StreamConfiguration &outcfg) override; int process(const libcamera::FrameBuffer &source, libcamera::Span destination, - CameraMetadata *metadata) override; + const CameraMetadata &requestMetadata, + CameraMetadata *resultMetadata) override; private: void generateThumbnail(const libcamera::FrameBuffer &source, -- cgit v1.2.1