Loading camera/CameraMetadata.cpp +9 −1 Original line number Original line Diff line number Diff line Loading @@ -133,11 +133,19 @@ void CameraMetadata::acquire(CameraMetadata &other) { } } status_t CameraMetadata::append(const CameraMetadata &other) { status_t CameraMetadata::append(const CameraMetadata &other) { return append(other.mBuffer); } status_t CameraMetadata::append(const camera_metadata_t* other) { if (mLocked) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; return INVALID_OPERATION; } } return append_camera_metadata(mBuffer, other.mBuffer); size_t extraEntries = get_camera_metadata_entry_count(other); size_t extraData = get_camera_metadata_data_count(other); resizeIfNeeded(extraEntries, extraData); return append_camera_metadata(mBuffer, other); } } size_t CameraMetadata::entryCount() const { size_t CameraMetadata::entryCount() const { Loading include/camera/CameraMetadata.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -98,6 +98,11 @@ class CameraMetadata { */ */ status_t append(const CameraMetadata &other); status_t append(const CameraMetadata &other); /** * Append metadata from a raw camera_metadata buffer */ status_t append(const camera_metadata* other); /** /** * Number of metadata entries. * Number of metadata entries. */ */ Loading services/camera/libcameraservice/api1/Camera2Client.cpp +13 −6 Original line number Original line Diff line number Diff line Loading @@ -76,6 +76,7 @@ status_t Camera2Client::initialize(camera_module_t *module) return res; return res; } } { SharedParameters::Lock l(mParameters); SharedParameters::Lock l(mParameters); res = l.mParameters.initialize(&(mDevice->info())); res = l.mParameters.initialize(&(mDevice->info())); Loading @@ -84,6 +85,7 @@ status_t Camera2Client::initialize(camera_module_t *module) __FUNCTION__, mCameraId, strerror(-res), res); __FUNCTION__, mCameraId, strerror(-res), res); return NO_INIT; return NO_INIT; } } } String8 threadName; String8 threadName; Loading Loading @@ -135,6 +137,7 @@ status_t Camera2Client::initialize(camera_module_t *module) mCallbackProcessor->run(threadName.string()); mCallbackProcessor->run(threadName.string()); if (gLogLevel >= 1) { if (gLogLevel >= 1) { SharedParameters::Lock l(mParameters); ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__, ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__, mCameraId); mCameraId); ALOGD("%s", l.mParameters.paramsFlattened.string()); ALOGD("%s", l.mParameters.paramsFlattened.string()); Loading Loading @@ -353,6 +356,10 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) { result.appendFormat(" meteringCropRegion\n"); result.appendFormat(" meteringCropRegion\n"); haveQuirk = true; haveQuirk = true; } } if (p.quirks.partialResults) { result.appendFormat(" usePartialResult\n"); haveQuirk = true; } if (!haveQuirk) { if (!haveQuirk) { result.appendFormat(" none\n"); result.appendFormat(" none\n"); } } Loading services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +111 −70 Original line number Original line Diff line number Diff line Loading @@ -29,13 +29,27 @@ namespace android { namespace camera2 { namespace camera2 { FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device, FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device, wp<Camera2Client> client) : sp<Camera2Client> client) : FrameProcessorBase(device), FrameProcessorBase(device), mClient(client), mClient(client), mLastFrameNumberOfFaces(0) { mLastFrameNumberOfFaces(0), mLast3AFrameNumber(-1) { sp<CameraDeviceBase> d = device.promote(); sp<CameraDeviceBase> d = device.promote(); mSynthesize3ANotify = !(d->willNotify3A()); mSynthesize3ANotify = !(d->willNotify3A()); { SharedParameters::Lock l(client->getParameters()); mUsePartialQuirk = l.mParameters.quirks.partialResults; // Initialize starting 3A state m3aState.afTriggerId = l.mParameters.afTriggerCounter; m3aState.aeTriggerId = l.mParameters.precaptureTriggerCounter; // Check if lens is fixed-focus if (l.mParameters.focusMode == Parameters::FOCUS_MODE_FIXED) { m3aState.afMode = ANDROID_CONTROL_AF_MODE_OFF; } } } } FrameProcessor::~FrameProcessor() { FrameProcessor::~FrameProcessor() { Loading @@ -49,20 +63,25 @@ bool FrameProcessor::processSingleFrame(CameraMetadata &frame, return false; return false; } } if (processFaceDetect(frame, client) != OK) { bool partialResult = false; if (mUsePartialQuirk) { camera_metadata_entry_t entry; entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT); if (entry.count > 0 && entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { partialResult = true; } } if (!partialResult && processFaceDetect(frame, client) != OK) { return false; return false; } } if (mSynthesize3ANotify) { if (mSynthesize3ANotify) { // Ignoring missing fields for now process3aState(frame, client); process3aState(frame, client); } } if (!FrameProcessorBase::processSingleFrame(frame, device)) { return FrameProcessorBase::processSingleFrame(frame, device); return false; } return true; } } status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, Loading Loading @@ -198,86 +217,75 @@ status_t FrameProcessor::process3aState(const CameraMetadata &frame, ATRACE_CALL(); ATRACE_CALL(); camera_metadata_ro_entry_t entry; camera_metadata_ro_entry_t entry; int mId = client->getCameraId(); int cameraId = client->getCameraId(); entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); int32_t frameNumber = entry.data.i32[0]; int32_t frameNumber = entry.data.i32[0]; // Don't send 3A notifications for the same frame number twice if (frameNumber <= mLast3AFrameNumber) { ALOGV("%s: Already sent 3A for frame number %d, skipping", __FUNCTION__, frameNumber); return OK; } mLast3AFrameNumber = frameNumber; // Get 3A states from result metadata // Get 3A states from result metadata bool gotAllStates = true; bool gotAllStates = true; AlgState new3aState; AlgState new3aState; entry = frame.find(ANDROID_CONTROL_AE_STATE); // TODO: Also use AE mode, AE trigger ID if (entry.count == 0) { ALOGE("%s: Camera %d: No AE state provided by HAL for frame %d!", __FUNCTION__, mId, frameNumber); gotAllStates = false; } else { new3aState.aeState = static_cast<camera_metadata_enum_android_control_ae_state>( entry.data.u8[0]); } entry = frame.find(ANDROID_CONTROL_AF_STATE); gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AF_MODE, if (entry.count == 0) { &new3aState.afMode, frameNumber, cameraId); ALOGE("%s: Camera %d: No AF state provided by HAL for frame %d!", __FUNCTION__, mId, frameNumber); gotAllStates = false; } else { new3aState.afState = static_cast<camera_metadata_enum_android_control_af_state>( entry.data.u8[0]); } entry = frame.find(ANDROID_CONTROL_AWB_STATE); gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AWB_MODE, if (entry.count == 0) { &new3aState.awbMode, frameNumber, cameraId); ALOGE("%s: Camera %d: No AWB state provided by HAL for frame %d!", __FUNCTION__, mId, frameNumber); gotAllStates = false; } else { new3aState.awbState = static_cast<camera_metadata_enum_android_control_awb_state>( entry.data.u8[0]); } int32_t afTriggerId = 0; gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AE_STATE, entry = frame.find(ANDROID_CONTROL_AF_TRIGGER_ID); &new3aState.aeState, frameNumber, cameraId); if (entry.count == 0) { ALOGE("%s: Camera %d: No AF trigger ID provided by HAL for frame %d!", __FUNCTION__, mId, frameNumber); gotAllStates = false; } else { afTriggerId = entry.data.i32[0]; } int32_t aeTriggerId = 0; gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AF_STATE, entry = frame.find(ANDROID_CONTROL_AE_PRECAPTURE_ID); &new3aState.afState, frameNumber, cameraId); if (entry.count == 0) { ALOGE("%s: Camera %d: No AE precapture trigger ID provided by HAL" gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AWB_STATE, " for frame %d!", &new3aState.awbState, frameNumber, cameraId); __FUNCTION__, mId, frameNumber); gotAllStates = false; gotAllStates &= get3aResult<int32_t>(frame, ANDROID_CONTROL_AF_TRIGGER_ID, } else { &new3aState.afTriggerId, frameNumber, cameraId); aeTriggerId = entry.data.i32[0]; } gotAllStates &= get3aResult<int32_t>(frame, ANDROID_CONTROL_AE_PRECAPTURE_ID, &new3aState.aeTriggerId, frameNumber, cameraId); if (!gotAllStates) return BAD_VALUE; if (!gotAllStates) return BAD_VALUE; if (new3aState.aeState != m3aState.aeState) { if (new3aState.aeState != m3aState.aeState) { ALOGV("%s: AE state changed from 0x%x to 0x%x", ALOGV("%s: Camera %d: AE state %d->%d", __FUNCTION__, m3aState.aeState, new3aState.aeState); __FUNCTION__, cameraId, client->notifyAutoExposure(new3aState.aeState, aeTriggerId); m3aState.aeState, new3aState.aeState); } client->notifyAutoExposure(new3aState.aeState, new3aState.aeTriggerId); if (new3aState.afState != m3aState.afState) { } ALOGV("%s: AF state changed from 0x%x to 0x%x", __FUNCTION__, m3aState.afState, new3aState.afState); if (new3aState.afState != m3aState.afState || client->notifyAutoFocus(new3aState.afState, afTriggerId); new3aState.afMode != m3aState.afMode || } new3aState.afTriggerId != m3aState.afTriggerId) { if (new3aState.awbState != m3aState.awbState) { ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d", ALOGV("%s: AWB state changed from 0x%x to 0x%x", __FUNCTION__, cameraId, __FUNCTION__, m3aState.awbState, new3aState.awbState); m3aState.afState, new3aState.afState, client->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId); m3aState.afMode, new3aState.afMode, m3aState.afTriggerId, new3aState.afTriggerId); client->notifyAutoFocus(new3aState.afState, new3aState.afTriggerId); } if (new3aState.awbState != m3aState.awbState || new3aState.awbMode != m3aState.awbMode) { ALOGV("%s: Camera %d: AWB state %d->%d. AWB mode %d->%d", __FUNCTION__, cameraId, m3aState.awbState, new3aState.awbState, m3aState.awbMode, new3aState.awbMode); client->notifyAutoWhitebalance(new3aState.awbState, new3aState.aeTriggerId); } } m3aState = new3aState; m3aState = new3aState; Loading @@ -285,6 +293,39 @@ status_t FrameProcessor::process3aState(const CameraMetadata &frame, return OK; return OK; } } template<typename Src, typename T> bool FrameProcessor::get3aResult(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId) { camera_metadata_ro_entry_t entry; if (value == NULL) { ALOGE("%s: Camera %d: Value to write to is NULL", __FUNCTION__, cameraId); return false; } entry = result.find(tag); if (entry.count == 0) { ALOGE("%s: Camera %d: No %s provided by HAL for frame %d!", __FUNCTION__, cameraId, get_camera_metadata_tag_name(tag), frameNumber); return false; } else { switch(sizeof(Src)){ case sizeof(uint8_t): *value = static_cast<T>(entry.data.u8[0]); break; case sizeof(int32_t): *value = static_cast<T>(entry.data.i32[0]); break; default: ALOGE("%s: Camera %d: Unsupported source", __FUNCTION__, cameraId); return false; } } return true; } void FrameProcessor::callbackFaceDetection(sp<Camera2Client> client, void FrameProcessor::callbackFaceDetection(sp<Camera2Client> client, const camera_frame_metadata &metadata) { const camera_frame_metadata &metadata) { Loading services/camera/libcameraservice/api1/client2/FrameProcessor.h +28 −2 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,7 @@ namespace camera2 { */ */ class FrameProcessor : public FrameProcessorBase { class FrameProcessor : public FrameProcessorBase { public: public: FrameProcessor(wp<CameraDeviceBase> device, wp<Camera2Client> client); FrameProcessor(wp<CameraDeviceBase> device, sp<Camera2Client> client); ~FrameProcessor(); ~FrameProcessor(); private: private: Loading @@ -61,18 +61,44 @@ class FrameProcessor : public FrameProcessorBase { status_t process3aState(const CameraMetadata &frame, status_t process3aState(const CameraMetadata &frame, const sp<Camera2Client> &client); const sp<Camera2Client> &client); // Helper for process3aState template<typename Src, typename T> bool get3aResult(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId); struct AlgState { struct AlgState { // TODO: also track AE mode camera_metadata_enum_android_control_af_mode afMode; camera_metadata_enum_android_control_awb_mode awbMode; camera_metadata_enum_android_control_ae_state aeState; camera_metadata_enum_android_control_ae_state aeState; camera_metadata_enum_android_control_af_state afState; camera_metadata_enum_android_control_af_state afState; camera_metadata_enum_android_control_awb_state awbState; camera_metadata_enum_android_control_awb_state awbState; int32_t afTriggerId; int32_t aeTriggerId; // These defaults need to match those in Parameters.cpp AlgState() : AlgState() : afMode(ANDROID_CONTROL_AF_MODE_AUTO), awbMode(ANDROID_CONTROL_AWB_MODE_AUTO), aeState(ANDROID_CONTROL_AE_STATE_INACTIVE), aeState(ANDROID_CONTROL_AE_STATE_INACTIVE), afState(ANDROID_CONTROL_AF_STATE_INACTIVE), afState(ANDROID_CONTROL_AF_STATE_INACTIVE), awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE) { awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE), afTriggerId(0), aeTriggerId(0) { } } } m3aState; } m3aState; // Whether the partial result quirk is enabled for this device bool mUsePartialQuirk; // Track most recent frame number for which 3A notifications were sent for. // Used to filter against sending 3A notifications for the same frame // several times. int32_t mLast3AFrameNumber; // Emit FaceDetection event to java if faces changed // Emit FaceDetection event to java if faces changed void callbackFaceDetection(sp<Camera2Client> client, void callbackFaceDetection(sp<Camera2Client> client, const camera_frame_metadata &metadata); const camera_frame_metadata &metadata); Loading Loading
camera/CameraMetadata.cpp +9 −1 Original line number Original line Diff line number Diff line Loading @@ -133,11 +133,19 @@ void CameraMetadata::acquire(CameraMetadata &other) { } } status_t CameraMetadata::append(const CameraMetadata &other) { status_t CameraMetadata::append(const CameraMetadata &other) { return append(other.mBuffer); } status_t CameraMetadata::append(const camera_metadata_t* other) { if (mLocked) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; return INVALID_OPERATION; } } return append_camera_metadata(mBuffer, other.mBuffer); size_t extraEntries = get_camera_metadata_entry_count(other); size_t extraData = get_camera_metadata_data_count(other); resizeIfNeeded(extraEntries, extraData); return append_camera_metadata(mBuffer, other); } } size_t CameraMetadata::entryCount() const { size_t CameraMetadata::entryCount() const { Loading
include/camera/CameraMetadata.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -98,6 +98,11 @@ class CameraMetadata { */ */ status_t append(const CameraMetadata &other); status_t append(const CameraMetadata &other); /** * Append metadata from a raw camera_metadata buffer */ status_t append(const camera_metadata* other); /** /** * Number of metadata entries. * Number of metadata entries. */ */ Loading
services/camera/libcameraservice/api1/Camera2Client.cpp +13 −6 Original line number Original line Diff line number Diff line Loading @@ -76,6 +76,7 @@ status_t Camera2Client::initialize(camera_module_t *module) return res; return res; } } { SharedParameters::Lock l(mParameters); SharedParameters::Lock l(mParameters); res = l.mParameters.initialize(&(mDevice->info())); res = l.mParameters.initialize(&(mDevice->info())); Loading @@ -84,6 +85,7 @@ status_t Camera2Client::initialize(camera_module_t *module) __FUNCTION__, mCameraId, strerror(-res), res); __FUNCTION__, mCameraId, strerror(-res), res); return NO_INIT; return NO_INIT; } } } String8 threadName; String8 threadName; Loading Loading @@ -135,6 +137,7 @@ status_t Camera2Client::initialize(camera_module_t *module) mCallbackProcessor->run(threadName.string()); mCallbackProcessor->run(threadName.string()); if (gLogLevel >= 1) { if (gLogLevel >= 1) { SharedParameters::Lock l(mParameters); ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__, ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__, mCameraId); mCameraId); ALOGD("%s", l.mParameters.paramsFlattened.string()); ALOGD("%s", l.mParameters.paramsFlattened.string()); Loading Loading @@ -353,6 +356,10 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) { result.appendFormat(" meteringCropRegion\n"); result.appendFormat(" meteringCropRegion\n"); haveQuirk = true; haveQuirk = true; } } if (p.quirks.partialResults) { result.appendFormat(" usePartialResult\n"); haveQuirk = true; } if (!haveQuirk) { if (!haveQuirk) { result.appendFormat(" none\n"); result.appendFormat(" none\n"); } } Loading
services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +111 −70 Original line number Original line Diff line number Diff line Loading @@ -29,13 +29,27 @@ namespace android { namespace camera2 { namespace camera2 { FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device, FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device, wp<Camera2Client> client) : sp<Camera2Client> client) : FrameProcessorBase(device), FrameProcessorBase(device), mClient(client), mClient(client), mLastFrameNumberOfFaces(0) { mLastFrameNumberOfFaces(0), mLast3AFrameNumber(-1) { sp<CameraDeviceBase> d = device.promote(); sp<CameraDeviceBase> d = device.promote(); mSynthesize3ANotify = !(d->willNotify3A()); mSynthesize3ANotify = !(d->willNotify3A()); { SharedParameters::Lock l(client->getParameters()); mUsePartialQuirk = l.mParameters.quirks.partialResults; // Initialize starting 3A state m3aState.afTriggerId = l.mParameters.afTriggerCounter; m3aState.aeTriggerId = l.mParameters.precaptureTriggerCounter; // Check if lens is fixed-focus if (l.mParameters.focusMode == Parameters::FOCUS_MODE_FIXED) { m3aState.afMode = ANDROID_CONTROL_AF_MODE_OFF; } } } } FrameProcessor::~FrameProcessor() { FrameProcessor::~FrameProcessor() { Loading @@ -49,20 +63,25 @@ bool FrameProcessor::processSingleFrame(CameraMetadata &frame, return false; return false; } } if (processFaceDetect(frame, client) != OK) { bool partialResult = false; if (mUsePartialQuirk) { camera_metadata_entry_t entry; entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT); if (entry.count > 0 && entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { partialResult = true; } } if (!partialResult && processFaceDetect(frame, client) != OK) { return false; return false; } } if (mSynthesize3ANotify) { if (mSynthesize3ANotify) { // Ignoring missing fields for now process3aState(frame, client); process3aState(frame, client); } } if (!FrameProcessorBase::processSingleFrame(frame, device)) { return FrameProcessorBase::processSingleFrame(frame, device); return false; } return true; } } status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, Loading Loading @@ -198,86 +217,75 @@ status_t FrameProcessor::process3aState(const CameraMetadata &frame, ATRACE_CALL(); ATRACE_CALL(); camera_metadata_ro_entry_t entry; camera_metadata_ro_entry_t entry; int mId = client->getCameraId(); int cameraId = client->getCameraId(); entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); int32_t frameNumber = entry.data.i32[0]; int32_t frameNumber = entry.data.i32[0]; // Don't send 3A notifications for the same frame number twice if (frameNumber <= mLast3AFrameNumber) { ALOGV("%s: Already sent 3A for frame number %d, skipping", __FUNCTION__, frameNumber); return OK; } mLast3AFrameNumber = frameNumber; // Get 3A states from result metadata // Get 3A states from result metadata bool gotAllStates = true; bool gotAllStates = true; AlgState new3aState; AlgState new3aState; entry = frame.find(ANDROID_CONTROL_AE_STATE); // TODO: Also use AE mode, AE trigger ID if (entry.count == 0) { ALOGE("%s: Camera %d: No AE state provided by HAL for frame %d!", __FUNCTION__, mId, frameNumber); gotAllStates = false; } else { new3aState.aeState = static_cast<camera_metadata_enum_android_control_ae_state>( entry.data.u8[0]); } entry = frame.find(ANDROID_CONTROL_AF_STATE); gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AF_MODE, if (entry.count == 0) { &new3aState.afMode, frameNumber, cameraId); ALOGE("%s: Camera %d: No AF state provided by HAL for frame %d!", __FUNCTION__, mId, frameNumber); gotAllStates = false; } else { new3aState.afState = static_cast<camera_metadata_enum_android_control_af_state>( entry.data.u8[0]); } entry = frame.find(ANDROID_CONTROL_AWB_STATE); gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AWB_MODE, if (entry.count == 0) { &new3aState.awbMode, frameNumber, cameraId); ALOGE("%s: Camera %d: No AWB state provided by HAL for frame %d!", __FUNCTION__, mId, frameNumber); gotAllStates = false; } else { new3aState.awbState = static_cast<camera_metadata_enum_android_control_awb_state>( entry.data.u8[0]); } int32_t afTriggerId = 0; gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AE_STATE, entry = frame.find(ANDROID_CONTROL_AF_TRIGGER_ID); &new3aState.aeState, frameNumber, cameraId); if (entry.count == 0) { ALOGE("%s: Camera %d: No AF trigger ID provided by HAL for frame %d!", __FUNCTION__, mId, frameNumber); gotAllStates = false; } else { afTriggerId = entry.data.i32[0]; } int32_t aeTriggerId = 0; gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AF_STATE, entry = frame.find(ANDROID_CONTROL_AE_PRECAPTURE_ID); &new3aState.afState, frameNumber, cameraId); if (entry.count == 0) { ALOGE("%s: Camera %d: No AE precapture trigger ID provided by HAL" gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AWB_STATE, " for frame %d!", &new3aState.awbState, frameNumber, cameraId); __FUNCTION__, mId, frameNumber); gotAllStates = false; gotAllStates &= get3aResult<int32_t>(frame, ANDROID_CONTROL_AF_TRIGGER_ID, } else { &new3aState.afTriggerId, frameNumber, cameraId); aeTriggerId = entry.data.i32[0]; } gotAllStates &= get3aResult<int32_t>(frame, ANDROID_CONTROL_AE_PRECAPTURE_ID, &new3aState.aeTriggerId, frameNumber, cameraId); if (!gotAllStates) return BAD_VALUE; if (!gotAllStates) return BAD_VALUE; if (new3aState.aeState != m3aState.aeState) { if (new3aState.aeState != m3aState.aeState) { ALOGV("%s: AE state changed from 0x%x to 0x%x", ALOGV("%s: Camera %d: AE state %d->%d", __FUNCTION__, m3aState.aeState, new3aState.aeState); __FUNCTION__, cameraId, client->notifyAutoExposure(new3aState.aeState, aeTriggerId); m3aState.aeState, new3aState.aeState); } client->notifyAutoExposure(new3aState.aeState, new3aState.aeTriggerId); if (new3aState.afState != m3aState.afState) { } ALOGV("%s: AF state changed from 0x%x to 0x%x", __FUNCTION__, m3aState.afState, new3aState.afState); if (new3aState.afState != m3aState.afState || client->notifyAutoFocus(new3aState.afState, afTriggerId); new3aState.afMode != m3aState.afMode || } new3aState.afTriggerId != m3aState.afTriggerId) { if (new3aState.awbState != m3aState.awbState) { ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d", ALOGV("%s: AWB state changed from 0x%x to 0x%x", __FUNCTION__, cameraId, __FUNCTION__, m3aState.awbState, new3aState.awbState); m3aState.afState, new3aState.afState, client->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId); m3aState.afMode, new3aState.afMode, m3aState.afTriggerId, new3aState.afTriggerId); client->notifyAutoFocus(new3aState.afState, new3aState.afTriggerId); } if (new3aState.awbState != m3aState.awbState || new3aState.awbMode != m3aState.awbMode) { ALOGV("%s: Camera %d: AWB state %d->%d. AWB mode %d->%d", __FUNCTION__, cameraId, m3aState.awbState, new3aState.awbState, m3aState.awbMode, new3aState.awbMode); client->notifyAutoWhitebalance(new3aState.awbState, new3aState.aeTriggerId); } } m3aState = new3aState; m3aState = new3aState; Loading @@ -285,6 +293,39 @@ status_t FrameProcessor::process3aState(const CameraMetadata &frame, return OK; return OK; } } template<typename Src, typename T> bool FrameProcessor::get3aResult(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId) { camera_metadata_ro_entry_t entry; if (value == NULL) { ALOGE("%s: Camera %d: Value to write to is NULL", __FUNCTION__, cameraId); return false; } entry = result.find(tag); if (entry.count == 0) { ALOGE("%s: Camera %d: No %s provided by HAL for frame %d!", __FUNCTION__, cameraId, get_camera_metadata_tag_name(tag), frameNumber); return false; } else { switch(sizeof(Src)){ case sizeof(uint8_t): *value = static_cast<T>(entry.data.u8[0]); break; case sizeof(int32_t): *value = static_cast<T>(entry.data.i32[0]); break; default: ALOGE("%s: Camera %d: Unsupported source", __FUNCTION__, cameraId); return false; } } return true; } void FrameProcessor::callbackFaceDetection(sp<Camera2Client> client, void FrameProcessor::callbackFaceDetection(sp<Camera2Client> client, const camera_frame_metadata &metadata) { const camera_frame_metadata &metadata) { Loading
services/camera/libcameraservice/api1/client2/FrameProcessor.h +28 −2 Original line number Original line Diff line number Diff line Loading @@ -39,7 +39,7 @@ namespace camera2 { */ */ class FrameProcessor : public FrameProcessorBase { class FrameProcessor : public FrameProcessorBase { public: public: FrameProcessor(wp<CameraDeviceBase> device, wp<Camera2Client> client); FrameProcessor(wp<CameraDeviceBase> device, sp<Camera2Client> client); ~FrameProcessor(); ~FrameProcessor(); private: private: Loading @@ -61,18 +61,44 @@ class FrameProcessor : public FrameProcessorBase { status_t process3aState(const CameraMetadata &frame, status_t process3aState(const CameraMetadata &frame, const sp<Camera2Client> &client); const sp<Camera2Client> &client); // Helper for process3aState template<typename Src, typename T> bool get3aResult(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId); struct AlgState { struct AlgState { // TODO: also track AE mode camera_metadata_enum_android_control_af_mode afMode; camera_metadata_enum_android_control_awb_mode awbMode; camera_metadata_enum_android_control_ae_state aeState; camera_metadata_enum_android_control_ae_state aeState; camera_metadata_enum_android_control_af_state afState; camera_metadata_enum_android_control_af_state afState; camera_metadata_enum_android_control_awb_state awbState; camera_metadata_enum_android_control_awb_state awbState; int32_t afTriggerId; int32_t aeTriggerId; // These defaults need to match those in Parameters.cpp AlgState() : AlgState() : afMode(ANDROID_CONTROL_AF_MODE_AUTO), awbMode(ANDROID_CONTROL_AWB_MODE_AUTO), aeState(ANDROID_CONTROL_AE_STATE_INACTIVE), aeState(ANDROID_CONTROL_AE_STATE_INACTIVE), afState(ANDROID_CONTROL_AF_STATE_INACTIVE), afState(ANDROID_CONTROL_AF_STATE_INACTIVE), awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE) { awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE), afTriggerId(0), aeTriggerId(0) { } } } m3aState; } m3aState; // Whether the partial result quirk is enabled for this device bool mUsePartialQuirk; // Track most recent frame number for which 3A notifications were sent for. // Used to filter against sending 3A notifications for the same frame // several times. int32_t mLast3AFrameNumber; // Emit FaceDetection event to java if faces changed // Emit FaceDetection event to java if faces changed void callbackFaceDetection(sp<Camera2Client> client, void callbackFaceDetection(sp<Camera2Client> client, const camera_frame_metadata &metadata); const camera_frame_metadata &metadata); Loading