Camera: Use capture result metadata to override EXIF

Use static and dynamic metadata to override Exif tags.

Also added back a missing ATRACE_ASYNC_ENDs statement.

Test: Camera CTS
Test: ERROR_BUFFER of internal streams is propagated to app
Test: ERROR_RESULT only results in EXIF not being overridden
Bug: 124066183
Change-Id: Id2c69c6bee04ae724ff5f190b2dd96d0159700c9
gugelfrei
Shuzhen Wang 5 years ago
parent c6aa503951
commit e7f4b46a57

@ -136,6 +136,8 @@ status_t HeicCompositeStream::createInternalStreams(const std::vector<sp<Surface
mAppSegmentConsumer->setName(String8("Camera3-HeicComposite-AppSegmentStream"));
mAppSegmentSurface = new Surface(producer);
mStaticInfo = device->info();
res = device->createStream(mAppSegmentSurface, mAppSegmentMaxSize, 1, format,
kAppSegmentDataSpace, rotation, &mAppSegmentStreamId, physicalCameraId, surfaceIds);
if (res == OK) {
@ -606,9 +608,42 @@ void HeicCompositeStream::compilePendingInputLocked() {
mFrameNumberMap.erase(it);
}
// Heic composition doesn't depend on capture result, so no need to check
// mErrorFrameNumbers. Just remove them.
mErrorFrameNumbers.clear();
while (!mCaptureResults.empty()) {
auto it = mCaptureResults.begin();
// Negative timestamp indicates that something went wrong during the capture result
// collection process.
if (it->first >= 0) {
if (mPendingInputFrames[it->first].frameNumber == std::get<0>(it->second)) {
mPendingInputFrames[it->first].result =
std::make_unique<CameraMetadata>(std::get<1>(it->second));
} else {
ALOGE("%s: Capture result frameNumber/timestamp mapping changed between "
"shutter and capture result!", __FUNCTION__);
}
}
mCaptureResults.erase(it);
}
// mErrorFrameNumbers stores frame number of dropped buffers.
auto it = mErrorFrameNumbers.begin();
while (it != mErrorFrameNumbers.end()) {
bool frameFound = false;
for (auto &inputFrame : mPendingInputFrames) {
if (inputFrame.second.frameNumber == *it) {
inputFrame.second.error = true;
frameFound = true;
break;
}
}
if (frameFound) {
it = mErrorFrameNumbers.erase(it);
} else {
ALOGW("%s: Not able to find failing input with frame number: %" PRId64, __FUNCTION__,
*it);
it++;
}
}
// Distribute codec input buffers to be filled out from YUV output
for (auto it = mPendingInputFrames.begin();
@ -639,14 +674,14 @@ bool HeicCompositeStream::getNextReadyInputLocked(int64_t *currentTs /*out*/) {
bool newInputAvailable = false;
for (const auto& it : mPendingInputFrames) {
bool appSegmentBufferReady = (it.second.appSegmentBuffer.data != nullptr) &&
!it.second.appSegmentWritten;
bool appSegmentReady = (it.second.appSegmentBuffer.data != nullptr) &&
!it.second.appSegmentWritten && it.second.result != nullptr;
bool codecOutputReady = !it.second.codecOutputBuffers.empty();
bool codecInputReady = (it.second.yuvBuffer.data != nullptr) &&
(!it.second.codecInputBuffers.empty());
if ((!it.second.error) &&
(it.first < *currentTs) &&
(appSegmentBufferReady || codecOutputReady || codecInputReady)) {
(appSegmentReady || codecOutputReady || codecInputReady)) {
*currentTs = it.first;
newInputAvailable = true;
break;
@ -678,13 +713,13 @@ status_t HeicCompositeStream::processInputFrame(nsecs_t timestamp,
ATRACE_CALL();
status_t res = OK;
bool appSegmentBufferReady = inputFrame.appSegmentBuffer.data != nullptr &&
!inputFrame.appSegmentWritten;
bool appSegmentReady = inputFrame.appSegmentBuffer.data != nullptr &&
!inputFrame.appSegmentWritten && inputFrame.result != nullptr;
bool codecOutputReady = inputFrame.codecOutputBuffers.size() > 0;
bool codecInputReady = inputFrame.yuvBuffer.data != nullptr &&
!inputFrame.codecInputBuffers.empty();
if (!appSegmentBufferReady && !codecOutputReady && !codecInputReady) {
if (!appSegmentReady && !codecOutputReady && !codecInputReady) {
ALOGW("%s: No valid appSegmentBuffer/codec input/outputBuffer available!", __FUNCTION__);
return OK;
}
@ -710,7 +745,7 @@ status_t HeicCompositeStream::processInputFrame(nsecs_t timestamp,
}
// Write JPEG APP segments data to the muxer.
if (appSegmentBufferReady && inputFrame.muxer != nullptr) {
if (appSegmentReady && inputFrame.muxer != nullptr) {
res = processAppSegment(timestamp, inputFrame);
if (res != OK) {
ALOGE("%s: Failed to process JPEG APP segments: %s (%d)", __FUNCTION__,
@ -829,10 +864,8 @@ status_t HeicCompositeStream::processAppSegment(nsecs_t timestamp, InputFrame &i
ALOGE("%s: Failed to initialize ExifUtils object!", __FUNCTION__);
return BAD_VALUE;
}
//TODO: Use capture result metadata and static metadata to fill out the
//rest.
CameraMetadata dummyMeta;
exifRes = exifUtils->setFromMetadata(dummyMeta, mOutputWidth, mOutputHeight);
exifRes = exifUtils->setFromMetadata(*inputFrame.result, mStaticInfo,
mOutputWidth, mOutputHeight);
if (!exifRes) {
ALOGE("%s: Failed to set Exif tags using metadata and main image sizes", __FUNCTION__);
return BAD_VALUE;
@ -1012,6 +1045,7 @@ status_t HeicCompositeStream::processCompletedInputFrame(nsecs_t timestamp,
}
inputFrame.anb = nullptr;
ATRACE_ASYNC_END("HEIC capture", inputFrame.frameNumber);
return OK;
}
@ -1497,6 +1531,36 @@ bool HeicCompositeStream::onStreamBufferError(const CaptureResultExtras& resultE
return res;
}
void HeicCompositeStream::onResultError(const CaptureResultExtras& resultExtras) {
// For result error, since the APPS_SEGMENT buffer already contains EXIF,
// simply skip using the capture result metadata to override EXIF.
Mutex::Autolock l(mMutex);
int64_t timestamp = -1;
for (const auto& fn : mFrameNumberMap) {
if (fn.first == resultExtras.frameNumber) {
timestamp = fn.second;
break;
}
}
if (timestamp == -1) {
for (const auto& inputFrame : mPendingInputFrames) {
if (inputFrame.second.frameNumber == resultExtras.frameNumber) {
timestamp = inputFrame.first;
break;
}
}
}
if (timestamp == -1) {
ALOGE("%s: Failed to find shutter timestamp for result error!", __FUNCTION__);
return;
}
mCaptureResults.emplace(timestamp, std::make_tuple(resultExtras.frameNumber, CameraMetadata()));
mInputReadyCondition.signal();
}
void HeicCompositeStream::CodecCallbackHandler::onMessageReceived(const sp<AMessage> &msg) {
sp<HeicCompositeStream> parent = mParent.promote();
if (parent == nullptr) return;

@ -77,7 +77,7 @@ protected:
bool threadLoop() override;
bool onStreamBufferError(const CaptureResultExtras& resultExtras) override;
void onResultError(const CaptureResultExtras& /*resultExtras*/) override {}
void onResultError(const CaptureResultExtras& resultExtras) override;
private:
//
@ -145,12 +145,13 @@ private:
int32_t orientation;
int32_t quality;
CpuConsumer::LockedBuffer appSegmentBuffer;
CpuConsumer::LockedBuffer appSegmentBuffer;
std::vector<CodecOutputBufferInfo> codecOutputBuffers;
std::unique_ptr<CameraMetadata> result;
// Fields that are only applicable to HEVC tiling.
CpuConsumer::LockedBuffer yuvBuffer;
std::vector<CodecInputBufferInfo> codecInputBuffers;
CpuConsumer::LockedBuffer yuvBuffer;
std::vector<CodecInputBufferInfo> codecInputBuffers;
bool error;
bool errorNotified;
@ -209,6 +210,7 @@ private:
sp<Surface> mAppSegmentSurface;
bool mAppSegmentBufferAcquired;
size_t mAppSegmentMaxSize;
CameraMetadata mStaticInfo;
int mMainImageStreamId, mMainImageSurfaceId;
sp<Surface> mMainImageSurface;

@ -58,79 +58,59 @@ public:
// set all known fields from a metadata structure
virtual bool setFromMetadata(const CameraMetadata& metadata,
const CameraMetadata& staticInfo,
const size_t imageWidth,
const size_t imageHeight);
// sets the len aperture.
// Returns false if memory allocation fails.
virtual bool setAperture(uint32_t numerator, uint32_t denominator);
// sets the value of brightness.
// Returns false if memory allocation fails.
virtual bool setBrightness(int32_t numerator, int32_t denominator);
virtual bool setAperture(float aperture);
// sets the color space.
// Returns false if memory allocation fails.
virtual bool setColorSpace(uint16_t color_space);
// sets the information to compressed data.
// Returns false if memory allocation fails.
virtual bool setComponentsConfiguration(const std::string& components_configuration);
// sets the compression scheme used for the image data.
// Returns false if memory allocation fails.
virtual bool setCompression(uint16_t compression);
// sets image contrast.
// Returns false if memory allocation fails.
virtual bool setContrast(uint16_t contrast);
// sets the date and time of image last modified. It takes local time. The
// name of the tag is DateTime in IFD0.
// Returns false if memory allocation fails.
virtual bool setDateTime(const struct tm& t);
// sets the image description.
// Returns false if memory allocation fails.
virtual bool setDescription(const std::string& description);
// sets the digital zoom ratio. If the numerator is 0, it means digital zoom
// was not used.
// Returns false if memory allocation fails.
virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator);
virtual bool setDigitalZoomRatio(
uint32_t crop_width, uint32_t crop_height,
uint32_t sensor_width, uint32_t sensor_height);
// sets the exposure bias.
// Sets the exposure bias.
// Returns false if memory allocation fails.
virtual bool setExposureBias(int32_t numerator, int32_t denominator);
virtual bool setExposureBias(int32_t ev,
uint32_t ev_step_numerator, uint32_t ev_step_denominator);
// sets the exposure mode set when the image was shot.
// Returns false if memory allocation fails.
virtual bool setExposureMode(uint16_t exposure_mode);
// sets the program used by the camera to set exposure when the picture is
// taken.
// Returns false if memory allocation fails.
virtual bool setExposureProgram(uint16_t exposure_program);
virtual bool setExposureMode(uint8_t exposure_mode);
// sets the exposure time, given in seconds.
// Returns false if memory allocation fails.
virtual bool setExposureTime(uint32_t numerator, uint32_t denominator);
virtual bool setExposureTime(float exposure_time);
// sets the status of flash.
// Returns false if memory allocation fails.
virtual bool setFlash(uint16_t flash);
virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode);
// sets the F number.
// Returns false if memory allocation fails.
virtual bool setFNumber(uint32_t numerator, uint32_t denominator);
virtual bool setFNumber(float f_number);
// sets the focal length of lens used to take the image in millimeters.
// Returns false if memory allocation fails.
virtual bool setFocalLength(uint32_t numerator, uint32_t denominator);
virtual bool setFocalLength(float focal_length);
// sets the degree of overall image gain adjustment.
// sets the focal length of lens for 35mm film used to take the image in millimeters.
// Returns false if memory allocation fails.
virtual bool setGainControl(uint16_t gain_control);
virtual bool setFocalLengthIn35mmFilm(float focal_length,
float sensor_size_x, float sensor_size_y);
// sets the altitude in meters.
// Returns false if memory allocation fails.
@ -164,45 +144,21 @@ public:
// Returns false if memory allocation fails.
virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
// sets the kind of light source.
// Returns false if memory allocation fails.
virtual bool setLightSource(uint16_t light_source);
// sets the smallest F number of the lens.
// Returns false if memory allocation fails.
virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator);
// sets the metering mode.
// Returns false if memory allocation fails.
virtual bool setMeteringMode(uint16_t metering_mode);
virtual bool setMaxAperture(float aperture);
// sets image orientation.
// Returns false if memory allocation fails.
virtual bool setOrientation(uint16_t orientation);
// sets the unit for measuring XResolution and YResolution.
// Returns false if memory allocation fails.
virtual bool setResolutionUnit(uint16_t resolution_unit);
// sets image saturation.
// Returns false if memory allocation fails.
virtual bool setSaturation(uint16_t saturation);
// sets the type of scene that was shot.
// Returns false if memory allocation fails.
virtual bool setSceneCaptureType(uint16_t type);
// sets image sharpness.
// Returns false if memory allocation fails.
virtual bool setSharpness(uint16_t sharpness);
// sets the shutter speed.
// Returns false if memory allocation fails.
virtual bool setShutterSpeed(int32_t numerator, int32_t denominator);
virtual bool setShutterSpeed(float exposure_time);
// sets the distance to the subject, given in meters.
// Returns false if memory allocation fails.
virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator);
virtual bool setSubjectDistance(float diopters);
// sets the fractions of seconds for the <DateTime> tag.
// Returns false if memory allocation fails.
@ -210,28 +166,7 @@ public:
// sets the white balance mode set when the image was shot.
// Returns false if memory allocation fails.
virtual bool setWhiteBalance(uint16_t white_balance);
// sets the number of pixels per resolution unit in the image width.
// Returns false if memory allocation fails.
virtual bool setXResolution(uint32_t numerator, uint32_t denominator);
// sets the position of chrominance components in relation to the luminance
// component.
// Returns false if memory allocation fails.
virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning);
// sets the number of pixels per resolution unit in the image length.
// Returns false if memory allocation fails.
virtual bool setYResolution(uint32_t numerator, uint32_t denominator);
// sets the manufacturer of camera.
// Returns false if memory allocation fails.
virtual bool setMake(const std::string& make);
// sets the model number of camera.
// Returns false if memory allocation fails.
virtual bool setModel(const std::string& model);
virtual bool setWhiteBalance(uint8_t white_balance);
// Generates APP1 segment.
// Returns false if generating APP1 segment fails.
@ -280,6 +215,10 @@ public:
virtual bool setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
const std::string& buffer, const std::string& msg);
float convertToApex(float val) {
return 2.0f * log2f(val);
}
// Destroys the buffer of APP1 segment if exists.
virtual void destroyApp1();
@ -291,6 +230,8 @@ public:
// The length of |app1_buffer_|.
unsigned int app1_length_;
// How precise the float-to-rational conversion for EXIF tags would be.
const static int kRationalPrecision = 10000;
};
#define SET_SHORT(ifd, tag, value) \
@ -373,13 +314,11 @@ bool ExifUtilsImpl::initialize(const unsigned char *app1Segment, size_t app1Segm
return true;
}
bool ExifUtilsImpl::setAperture(uint32_t numerator, uint32_t denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, numerator, denominator);
return true;
}
bool ExifUtilsImpl::setBrightness(int32_t numerator, int32_t denominator) {
SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE, numerator, denominator);
bool ExifUtilsImpl::setAperture(float aperture) {
float apexValue = convertToApex(aperture);
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE,
static_cast<uint32_t>(std::round(apexValue * kRationalPrecision)),
kRationalPrecision);
return true;
}
@ -388,23 +327,6 @@ bool ExifUtilsImpl::setColorSpace(uint16_t color_space) {
return true;
}
bool ExifUtilsImpl::setComponentsConfiguration(
const std::string& components_configuration) {
SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION,
EXIF_FORMAT_UNDEFINED, components_configuration);
return true;
}
bool ExifUtilsImpl::setCompression(uint16_t compression) {
SET_SHORT(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);
return true;
}
bool ExifUtilsImpl::setContrast(uint16_t contrast) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_CONTRAST, contrast);
return true;
}
bool ExifUtilsImpl::setDateTime(const struct tm& t) {
// The length is 20 bytes including NULL for termination in Exif standard.
char str[20];
@ -421,53 +343,111 @@ bool ExifUtilsImpl::setDateTime(const struct tm& t) {
return true;
}
bool ExifUtilsImpl::setDescription(const std::string& description) {
SET_STRING(EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_FORMAT_ASCII, description);
return true;
}
bool ExifUtilsImpl::setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, numerator, denominator);
return true;
}
bool ExifUtilsImpl::setDigitalZoomRatio(
uint32_t crop_width, uint32_t crop_height,
uint32_t sensor_width, uint32_t sensor_height) {
float zoomRatioX = (crop_width == 0) ? 1.0 : 1.0 * sensor_width / crop_width;
float zoomRatioY = (crop_height == 0) ? 1.0 : 1.0 * sensor_height / crop_height;
float zoomRatio = std::max(zoomRatioX, zoomRatioY);
const static float noZoomThreshold = 1.02f;
bool ExifUtilsImpl::setExposureBias(int32_t numerator, int32_t denominator) {
SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, numerator, denominator);
if (zoomRatio <= noZoomThreshold) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, 0, 1);
} else {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO,
static_cast<uint32_t>(std::round(zoomRatio * kRationalPrecision)),
kRationalPrecision);
}
return true;
}
bool ExifUtilsImpl::setExposureMode(uint16_t exposure_mode) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposure_mode);
bool ExifUtilsImpl::setExposureMode(uint8_t exposure_mode) {
uint16_t exposureMode = (exposure_mode == ANDROID_CONTROL_AE_MODE_OFF) ? 1 : 0;
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposureMode);
return true;
}
bool ExifUtilsImpl::setExposureProgram(uint16_t exposure_program) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, exposure_program);
bool ExifUtilsImpl::setExposureTime(float exposure_time) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME,
static_cast<uint32_t>(std::round(exposure_time * kRationalPrecision)),
kRationalPrecision);
return true;
}
bool ExifUtilsImpl::setExposureTime(uint32_t numerator, uint32_t denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, numerator, denominator);
return true;
}
bool ExifUtilsImpl::setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) {
// EXIF_TAG_FLASH bits layout per EXIF standard:
// Bit 0: 0 - did not fire
// 1 - fired
// Bit 1-2: status of return light
// Bit 3-4: 0 - unknown
// 1 - compulsory flash firing
// 2 - compulsory flash suppression
// 3 - auto mode
// Bit 5: 0 - flash function present
// 1 - no flash function
// Bit 6: 0 - no red-eye reduction mode or unknown
// 1 - red-eye reduction supported
uint16_t flash = 0x20;
if (flash_available == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
flash = 0x00;
if (flash_state == ANDROID_FLASH_STATE_FIRED) {
flash |= 0x1;
}
if (ae_mode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
flash |= 0x40;
}
bool ExifUtilsImpl::setFlash(uint16_t flash) {
uint16_t flashMode = 0;
switch (ae_mode) {
case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
flashMode = 3; // AUTO
break;
case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
case ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH:
flashMode = 1; // ON
break;
case ANDROID_CONTROL_AE_MODE_OFF:
case ANDROID_CONTROL_AE_MODE_ON:
flashMode = 2; // OFF
break;
default:
flashMode = 0; // UNKNOWN
break;
}
flash |= (flashMode << 3);
}
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
return true;
}
bool ExifUtilsImpl::setFNumber(uint32_t numerator, uint32_t denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, numerator, denominator);
bool ExifUtilsImpl::setFNumber(float f_number) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER,
static_cast<uint32_t>(std::round(f_number * kRationalPrecision)),
kRationalPrecision);
return true;
}
bool ExifUtilsImpl::setFocalLength(uint32_t numerator, uint32_t denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, denominator);
bool ExifUtilsImpl::setFocalLength(float focal_length) {
uint32_t numerator = static_cast<uint32_t>(std::round(focal_length * kRationalPrecision));
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, kRationalPrecision);
return true;
}
bool ExifUtilsImpl::setGainControl(uint16_t gain_control) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL, gain_control);
bool ExifUtilsImpl::setFocalLengthIn35mmFilm(
float focal_length, float sensor_size_x, float sensor_size_y) {
static const float filmDiagonal = 43.27; // diagonal of 35mm film
static const float minSensorDiagonal = 0.01;
float sensorDiagonal = std::sqrt(
sensor_size_x * sensor_size_x + sensor_size_y * sensor_size_y);
sensorDiagonal = std::max(sensorDiagonal, minSensorDiagonal);
float focalLength35mmFilm = std::round(focal_length * filmDiagonal / sensorDiagonal);
focalLength35mmFilm = std::min(1.0f * 65535, focalLength35mmFilm);
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM,
static_cast<uint16_t>(focalLength35mmFilm));
return true;
}
@ -614,18 +594,18 @@ bool ExifUtilsImpl::setIsoSpeedRating(uint16_t iso_speed_ratings) {
return true;
}
bool ExifUtilsImpl::setLightSource(uint16_t light_source) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_LIGHT_SOURCE, light_source);
bool ExifUtilsImpl::setMaxAperture(float aperture) {
float maxAperture = convertToApex(aperture);
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE,
static_cast<uint32_t>(std::round(maxAperture * kRationalPrecision)),
kRationalPrecision);
return true;
}
bool ExifUtilsImpl::setMaxAperture(uint32_t numerator, uint32_t denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE, numerator, denominator);
return true;
}
bool ExifUtilsImpl::setMeteringMode(uint16_t metering_mode) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE, metering_mode);
bool ExifUtilsImpl::setExposureBias(int32_t ev,
uint32_t ev_step_numerator, uint32_t ev_step_denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE,
ev * ev_step_numerator, ev_step_denominator);
return true;
}
@ -658,33 +638,36 @@ bool ExifUtilsImpl::setOrientation(uint16_t orientation) {
return true;
}
bool ExifUtilsImpl::setResolutionUnit(uint16_t resolution_unit) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_RESOLUTION_UNIT, resolution_unit);
return true;
}
bool ExifUtilsImpl::setSaturation(uint16_t saturation) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SATURATION, saturation);
return true;
}
bool ExifUtilsImpl::setSceneCaptureType(uint16_t type) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, type);
bool ExifUtilsImpl::setShutterSpeed(float exposure_time) {
float shutterSpeed = -log2f(exposure_time);
SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE,
static_cast<uint32_t>(shutterSpeed * kRationalPrecision), kRationalPrecision);
return true;
}
bool ExifUtilsImpl::setSharpness(uint16_t sharpness) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS, sharpness);
return true;
}
bool ExifUtilsImpl::setShutterSpeed(int32_t numerator, int32_t denominator) {
SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, numerator, denominator);
return true;
}
bool ExifUtilsImpl::setSubjectDistance(uint32_t numerator, uint32_t denominator) {
bool ExifUtilsImpl::setSubjectDistance(float diopters) {
const static float kInfinityDiopters = 1.0e-6;
uint32_t numerator, denominator;
uint16_t distanceRange;
if (diopters > kInfinityDiopters) {
float focusDistance = 1.0f / diopters;
numerator = static_cast<uint32_t>(std::round(focusDistance * kRationalPrecision));
denominator = kRationalPrecision;
if (focusDistance < 1.0f) {
distanceRange = 1; // Macro
} else if (focusDistance < 3.0f) {
distanceRange = 2; // Close
} else {
distanceRange = 3; // Distant
}
} else {
numerator = 0xFFFFFFFF;
denominator = 1;
distanceRange = 3; // Distant
}
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator, denominator);
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE_RANGE, distanceRange);
return true;
}
@ -695,23 +678,9 @@ bool ExifUtilsImpl::setSubsecTime(const std::string& subsec_time) {
return true;
}
bool ExifUtilsImpl::setWhiteBalance(uint16_t white_balance) {
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, white_balance);
return true;
}
bool ExifUtilsImpl::setXResolution(uint32_t numerator, uint32_t denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_X_RESOLUTION, numerator, denominator);
return true;
}
bool ExifUtilsImpl::setYCbCrPositioning(uint16_t ycbcr_positioning) {
SET_SHORT(EXIF_IFD_0, EXIF_TAG_YCBCR_POSITIONING, ycbcr_positioning);
return true;
}
bool ExifUtilsImpl::setYResolution(uint32_t numerator, uint32_t denominator) {
SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_Y_RESOLUTION, numerator, denominator);
bool ExifUtilsImpl::setWhiteBalance(uint8_t white_balance) {
uint16_t whiteBalance = (white_balance == ANDROID_CONTROL_AWB_MODE_AUTO) ? 0 : 1;
SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, whiteBalance);
return true;
}
@ -748,16 +717,6 @@ bool ExifUtilsImpl::setExifVersion(const std::string& exif_version) {
return true;
}
bool ExifUtilsImpl::setMake(const std::string& make) {
SET_STRING(EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, make);
return true;
}
bool ExifUtilsImpl::setModel(const std::string& model) {
SET_STRING(EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, model);
return true;
}
void ExifUtilsImpl::reset() {
destroyApp1();
if (exif_data_) {
@ -898,9 +857,8 @@ void ExifUtilsImpl::destroyApp1() {
}
bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
const CameraMetadata& staticInfo,
const size_t imageWidth, const size_t imageHeight) {
// How precise the float-to-rational conversion for EXIF tags would be.
constexpr int kRationalPrecision = 10000;
if (!setImageWidth(imageWidth) ||
!setImageHeight(imageHeight)) {
ALOGE("%s: setting image resolution failed.", __FUNCTION__);
@ -921,15 +879,37 @@ bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
if (entry.count) {
focal_length = entry.data.f[0];
if (!setFocalLength(
static_cast<uint32_t>(focal_length * kRationalPrecision), kRationalPrecision)) {
if (!setFocalLength(focal_length)) {
ALOGE("%s: setting focal length failed.", __FUNCTION__);
return false;
}
camera_metadata_ro_entry sensorSizeEntry =
staticInfo.find(ANDROID_SENSOR_INFO_PHYSICAL_SIZE);
if (sensorSizeEntry.count == 2) {
if (!setFocalLengthIn35mmFilm(
focal_length, sensorSizeEntry.data.f[0], sensorSizeEntry.data.f[1])) {
ALOGE("%s: setting focal length in 35mm failed.", __FUNCTION__);
return false;
}
}
} else {
ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
}
if (metadata.exists(ANDROID_SCALER_CROP_REGION) &&
staticInfo.exists(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE)) {
entry = metadata.find(ANDROID_SCALER_CROP_REGION);
camera_metadata_ro_entry activeArrayEntry =
staticInfo.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
if (!setDigitalZoomRatio(entry.data.i32[2], entry.data.i32[3],
activeArrayEntry.data.i32[2], activeArrayEntry.data.i32[3])) {
ALOGE("%s: setting digital zoom ratio failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
if (entry.count < 3) {
@ -973,6 +953,18 @@ bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
}
}
if (staticInfo.exists(ANDROID_CONTROL_AE_COMPENSATION_STEP) &&
metadata.exists(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION)) {
entry = metadata.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION);
camera_metadata_ro_entry stepEntry =
staticInfo.find(ANDROID_CONTROL_AE_COMPENSATION_STEP);
if (!setExposureBias(entry.data.i32[0], stepEntry.data.r[0].numerator,
stepEntry.data.r[0].denominator)) {
ALOGE("%s: setting exposure bias failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
entry = metadata.find(ANDROID_JPEG_ORIENTATION);
if (!setOrientation(entry.data.i32[0])) {
@ -983,50 +975,97 @@ bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
// int64_t of nanoseconds
if (!setExposureTime(entry.data.i64[0],1000000000u)) {
float exposure_time = 1.0f * entry.data.i64[0] / 1e9;
if (!setExposureTime(exposure_time)) {
ALOGE("%s: setting exposure time failed.", __FUNCTION__);
return false;
}
if (!setShutterSpeed(exposure_time)) {
ALOGE("%s: setting shutter speed failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_LENS_FOCUS_DISTANCE)) {
entry = metadata.find(ANDROID_LENS_FOCUS_DISTANCE);
if (!setSubjectDistance(entry.data.f[0])) {
ALOGE("%s: setting subject distance failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_SENSOR_SENSITIVITY)) {
entry = metadata.find(ANDROID_SENSOR_SENSITIVITY);
int32_t iso = entry.data.i32[0];
camera_metadata_ro_entry postRawSensEntry =
metadata.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
if (postRawSensEntry.count > 0) {
iso = iso * postRawSensEntry.data.i32[0] / 100;
}
if (!setIsoSpeedRating(static_cast<uint16_t>(iso))) {
ALOGE("%s: setting iso rating failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_LENS_APERTURE)) {
const int kAperturePrecision = 10000;
entry = metadata.find(ANDROID_LENS_APERTURE);
if (!setFNumber(entry.data.f[0] * kAperturePrecision, kAperturePrecision)) {
if (!setFNumber(entry.data.f[0])) {
ALOGE("%s: setting F number failed.", __FUNCTION__);
return false;
}
if (!setAperture(entry.data.f[0])) {
ALOGE("%s: setting aperture failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
if (entry.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_FALSE) {
const uint32_t kNoFlashFunction = 0x20;
if (!setFlash(kNoFlashFunction)) {
ALOGE("%s: setting flash failed.", __FUNCTION__);
return false;
}
} else {
ALOGE("%s: Unsupported flash info: %d",__FUNCTION__, entry.data.u8[0]);
static const uint16_t kSRGBColorSpace = 1;
if (!setColorSpace(kSRGBColorSpace)) {
ALOGE("%s: setting color space failed.", __FUNCTION__);
return false;
}
if (staticInfo.exists(ANDROID_LENS_INFO_AVAILABLE_APERTURES)) {
entry = staticInfo.find(ANDROID_LENS_INFO_AVAILABLE_APERTURES);
if (!setMaxAperture(entry.data.f[0])) {
ALOGE("%s: setting max aperture failed.", __FUNCTION__);
return false;
}
}
if (staticInfo.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
entry = staticInfo.find(ANDROID_FLASH_INFO_AVAILABLE);
camera_metadata_ro_entry flashStateEntry = metadata.find(ANDROID_FLASH_STATE);
camera_metadata_ro_entry aeModeEntry = metadata.find(ANDROID_CONTROL_AE_MODE);
uint8_t flashState = flashStateEntry.count > 0 ?
flashStateEntry.data.u8[0] : ANDROID_FLASH_STATE_UNAVAILABLE;
uint8_t aeMode = aeModeEntry.count > 0 ?
aeModeEntry.data.u8[0] : ANDROID_CONTROL_AE_MODE_OFF;
if (!setFlash(entry.data.u8[0], flashState, aeMode)) {
ALOGE("%s: setting flash failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
if (entry.data.u8[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
const uint16_t kAutoWhiteBalance = 0;
if (!setWhiteBalance(kAutoWhiteBalance)) {
ALOGE("%s: setting white balance failed.", __FUNCTION__);
return false;
}
} else {
ALOGE("%s: Unsupported awb mode: %d", __FUNCTION__, entry.data.u8[0]);
if (!setWhiteBalance(entry.data.u8[0])) {
ALOGE("%s: setting white balance failed.", __FUNCTION__);
return false;
}
}
if (metadata.exists(ANDROID_CONTROL_AE_MODE)) {
entry = metadata.find(ANDROID_CONTROL_AE_MODE);
if (!setExposureMode(entry.data.u8[0])) {
ALOGE("%s: setting exposure mode failed.", __FUNCTION__);
return false;
}
}
if (time_available) {
char str[4];
if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {

@ -52,78 +52,57 @@ public:
// Set all known fields from a metadata structure
virtual bool setFromMetadata(const CameraMetadata& metadata,
const CameraMetadata& staticInfo,
const size_t imageWidth, const size_t imageHeight) = 0;
// Sets the len aperture.
// Returns false if memory allocation fails.
virtual bool setAperture(uint32_t numerator, uint32_t denominator) = 0;
virtual bool setAperture(float aperture) = 0;
// Sets the value of brightness.
// Returns false if memory allocation fails.
virtual bool setBrightness(int32_t numerator, int32_t denominator) = 0;
// Sets the color space.
// sets the color space.
// Returns false if memory allocation fails.
virtual bool setColorSpace(uint16_t color_space) = 0;
// Sets the information to compressed data.
// Returns false if memory allocation fails.
virtual bool setComponentsConfiguration(const std::string& components_configuration) = 0;
// Sets the compression scheme used for the image data.
// Returns false if memory allocation fails.
virtual bool setCompression(uint16_t compression) = 0;
// Sets image contrast.
// Returns false if memory allocation fails.
virtual bool setContrast(uint16_t contrast) = 0;
// Sets the date and time of image last modified. It takes local time. The
// name of the tag is DateTime in IFD0.
// Returns false if memory allocation fails.
virtual bool setDateTime(const struct tm& t) = 0;
// Sets the image description.
// Returns false if memory allocation fails.
virtual bool setDescription(const std::string& description) = 0;
// Sets the digital zoom ratio. If the numerator is 0, it means digital zoom
// was not used.
// Returns false if memory allocation fails.
virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) = 0;
virtual bool setDigitalZoomRatio(uint32_t crop_width, uint32_t crop_height,
uint32_t sensor_width, uint32_t sensor_height) = 0;
// Sets the exposure bias.
// Returns false if memory allocation fails.
virtual bool setExposureBias(int32_t numerator, int32_t denominator) = 0;
virtual bool setExposureBias(int32_t ev,
uint32_t ev_step_numerator, uint32_t ev_step_denominator) = 0;
// Sets the exposure mode set when the image was shot.
// Returns false if memory allocation fails.
virtual bool setExposureMode(uint16_t exposure_mode) = 0;
// Sets the program used by the camera to set exposure when the picture is
// taken.
// Returns false if memory allocation fails.
virtual bool setExposureProgram(uint16_t exposure_program) = 0;
virtual bool setExposureMode(uint8_t exposure_mode) = 0;
// Sets the exposure time, given in seconds.
// Returns false if memory allocation fails.
virtual bool setExposureTime(uint32_t numerator, uint32_t denominator) = 0;
virtual bool setExposureTime(float exposure_time) = 0;
// Sets the status of flash.
// Returns false if memory allocation fails.
virtual bool setFlash(uint16_t flash) = 0;
virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) = 0;
// Sets the F number.
// Returns false if memory allocation fails.
virtual bool setFNumber(uint32_t numerator, uint32_t denominator) = 0;
virtual bool setFNumber(float f_number) = 0;
// Sets the focal length of lens used to take the image in millimeters.
// Returns false if memory allocation fails.
virtual bool setFocalLength(uint32_t numerator, uint32_t denominator) = 0;
virtual bool setFocalLength(float focal_length) = 0;
// Sets the degree of overall image gain adjustment.
// Sets the focal length of lens for 35mm film used to take the image in millimeters.
// Returns false if memory allocation fails.
virtual bool setGainControl(uint16_t gain_control) = 0;
virtual bool setFocalLengthIn35mmFilm(float focal_length,
float sensor_size_x, float sensor_size_y) = 0;
// Sets the altitude in meters.
// Returns false if memory allocation fails.
@ -157,45 +136,21 @@ public:
// Returns false if memory allocation fails.
virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings) = 0;
// Sets the kind of light source.
// Returns false if memory allocation fails.
virtual bool setLightSource(uint16_t light_source) = 0;
// Sets the smallest F number of the lens.
// Returns false if memory allocation fails.
virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator) = 0;
// Sets the metering mode.
// Returns false if memory allocation fails.
virtual bool setMeteringMode(uint16_t metering_mode) = 0;
virtual bool setMaxAperture(float aperture) = 0;
// Sets image orientation.
// Returns false if memory allocation fails.
virtual bool setOrientation(uint16_t orientation) = 0;
// Sets the unit for measuring XResolution and YResolution.
// Returns false if memory allocation fails.
virtual bool setResolutionUnit(uint16_t resolution_unit) = 0;
// Sets image saturation.
// Returns false if memory allocation fails.
virtual bool setSaturation(uint16_t saturation) = 0;
// Sets the type of scene that was shot.
// Returns false if memory allocation fails.
virtual bool setSceneCaptureType(uint16_t type) = 0;
// Sets image sharpness.
// Returns false if memory allocation fails.
virtual bool setSharpness(uint16_t sharpness) = 0;
// Sets the shutter speed.
// Returns false if memory allocation fails.
virtual bool setShutterSpeed(int32_t numerator, int32_t denominator) = 0;
virtual bool setShutterSpeed(float exposure_time) = 0;
// Sets the distance to the subject, given in meters.
// Returns false if memory allocation fails.
virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator) = 0;
virtual bool setSubjectDistance(float diopters) = 0;
// Sets the fractions of seconds for the <DateTime> tag.
// Returns false if memory allocation fails.
@ -203,28 +158,7 @@ public:
// Sets the white balance mode set when the image was shot.
// Returns false if memory allocation fails.
virtual bool setWhiteBalance(uint16_t white_balance) = 0;
// Sets the number of pixels per resolution unit in the image width.
// Returns false if memory allocation fails.
virtual bool setXResolution(uint32_t numerator, uint32_t denominator) = 0;
// Sets the position of chrominance components in relation to the luminance
// component.
// Returns false if memory allocation fails.
virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning) = 0;
// Sets the number of pixels per resolution unit in the image length.
// Returns false if memory allocation fails.
virtual bool setYResolution(uint32_t numerator, uint32_t denominator) = 0;
// Sets the manufacturer of camera.
// Returns false if memory allocation fails.
virtual bool setMake(const std::string& make) = 0;
// Sets the model number of camera.
// Returns false if memory allocation fails.
virtual bool setModel(const std::string& model) = 0;
virtual bool setWhiteBalance(uint8_t white_blanace) = 0;
// Generates APP1 segment.
// Returns false if generating APP1 segment fails.

Loading…
Cancel
Save