Loading services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +71 −41 Original line number Diff line number Diff line Loading @@ -53,7 +53,13 @@ FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device, // Check if lens is fixed-focus if (l.mParameters.focusMode == Parameters::FOCUS_MODE_FIXED) { m3aState.afMode = ANDROID_CONTROL_AF_MODE_OFF; } else { m3aState.afMode = ANDROID_CONTROL_AF_MODE_AUTO; } m3aState.awbMode = ANDROID_CONTROL_AWB_MODE_AUTO; m3aState.aeState = ANDROID_CONTROL_AE_STATE_INACTIVE; m3aState.afState = ANDROID_CONTROL_AF_STATE_INACTIVE; m3aState.awbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; } } Loading Loading @@ -253,80 +259,99 @@ status_t FrameProcessor::process3aState(const CaptureResult &frame, if (frameNumber <= mLast3AFrameNumber) { ALOGV("%s: Already sent 3A for frame number %d, skipping", __FUNCTION__, frameNumber); // Remove the entry if there is one for this frame number in mPending3AStates. mPending3AStates.removeItem(frameNumber); return OK; } mLast3AFrameNumber = frameNumber; AlgState pendingState; // Get 3A states from result metadata bool gotAllStates = true; ssize_t index = mPending3AStates.indexOfKey(frameNumber); if (index != NAME_NOT_FOUND) { pendingState = mPending3AStates.valueAt(index); } AlgState new3aState; // Update 3A states from the result. bool gotAllStates = true; // TODO: Also use AE mode, AE trigger ID gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_MODE, &pendingState.afMode, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AF_MODE, &new3aState.afMode, frameNumber, cameraId); gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_MODE, &pendingState.awbMode, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AWB_MODE, &new3aState.awbMode, frameNumber, cameraId); gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AE_STATE, &pendingState.aeState, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AE_STATE, &new3aState.aeState, frameNumber, cameraId); gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_STATE, &pendingState.afState, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AF_STATE, &new3aState.afState, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AWB_STATE, &new3aState.awbState, frameNumber, cameraId); gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_STATE, &pendingState.awbState, frameNumber, cameraId); if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_2) { new3aState.afTriggerId = frame.mResultExtras.afTriggerId; new3aState.aeTriggerId = frame.mResultExtras.precaptureTriggerId; pendingState.afTriggerId = frame.mResultExtras.afTriggerId; pendingState.aeTriggerId = frame.mResultExtras.precaptureTriggerId; } else { gotAllStates &= get3aResult<int32_t>(metadata, ANDROID_CONTROL_AF_TRIGGER_ID, &new3aState.afTriggerId, frameNumber, cameraId); gotAllStates &= updatePendingState<int32_t>(metadata, ANDROID_CONTROL_AF_TRIGGER_ID, &pendingState.afTriggerId, frameNumber, cameraId); gotAllStates &= get3aResult<int32_t>(metadata, ANDROID_CONTROL_AE_PRECAPTURE_ID, &new3aState.aeTriggerId, frameNumber, cameraId); gotAllStates &= updatePendingState<int32_t>(metadata, ANDROID_CONTROL_AE_PRECAPTURE_ID, &pendingState.aeTriggerId, frameNumber, cameraId); } if (!gotAllStates) return BAD_VALUE; if (!gotAllStates) { // If not all states are received, put the pending state to mPending3AStates. if (index == NAME_NOT_FOUND) { mPending3AStates.add(frameNumber, pendingState); } else { mPending3AStates.replaceValueAt(index, pendingState); } return NOT_ENOUGH_DATA; } if (new3aState.aeState != m3aState.aeState) { // Once all 3A states are received, notify the client about 3A changes. if (pendingState.aeState != m3aState.aeState) { ALOGV("%s: Camera %d: AE state %d->%d", __FUNCTION__, cameraId, m3aState.aeState, new3aState.aeState); client->notifyAutoExposure(new3aState.aeState, new3aState.aeTriggerId); m3aState.aeState, pendingState.aeState); client->notifyAutoExposure(pendingState.aeState, pendingState.aeTriggerId); } if (new3aState.afState != m3aState.afState || new3aState.afMode != m3aState.afMode || new3aState.afTriggerId != m3aState.afTriggerId) { if (pendingState.afState != m3aState.afState || pendingState.afMode != m3aState.afMode || pendingState.afTriggerId != m3aState.afTriggerId) { ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d", __FUNCTION__, cameraId, m3aState.afState, new3aState.afState, m3aState.afMode, new3aState.afMode, m3aState.afTriggerId, new3aState.afTriggerId); client->notifyAutoFocus(new3aState.afState, new3aState.afTriggerId); m3aState.afState, pendingState.afState, m3aState.afMode, pendingState.afMode, m3aState.afTriggerId, pendingState.afTriggerId); client->notifyAutoFocus(pendingState.afState, pendingState.afTriggerId); } if (new3aState.awbState != m3aState.awbState || new3aState.awbMode != m3aState.awbMode) { if (pendingState.awbState != m3aState.awbState || pendingState.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.awbState, pendingState.awbState, m3aState.awbMode, pendingState.awbMode); client->notifyAutoWhitebalance(pendingState.awbState, pendingState.aeTriggerId); } if (index != NAME_NOT_FOUND) { mPending3AStates.removeItemsAt(index); } m3aState = new3aState; m3aState = pendingState; mLast3AFrameNumber = frameNumber; return OK; } template<typename Src, typename T> bool FrameProcessor::get3aResult(const CameraMetadata& result, int32_t tag, bool FrameProcessor::updatePendingState(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId) { camera_metadata_ro_entry_t entry; if (value == NULL) { Loading @@ -335,9 +360,14 @@ bool FrameProcessor::get3aResult(const CameraMetadata& result, int32_t tag, return false; } // Already got the value for this tag. if (*value != static_cast<T>(NOT_SET)) { return true; } entry = result.find(tag); if (entry.count == 0) { ALOGE("%s: Camera %d: No %s provided by HAL for frame %d!", ALOGV("%s: Camera %d: No %s provided by HAL for frame %d in this result!", __FUNCTION__, cameraId, get_camera_metadata_tag_name(tag), frameNumber); return false; Loading services/camera/libcameraservice/api1/client2/FrameProcessor.h +16 −9 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ class FrameProcessor : public FrameProcessorBase { ~FrameProcessor(); private: static const int32_t NOT_SET = -1; wp<Camera2Client> mClient; bool mSynthesize3ANotify; Loading @@ -63,7 +65,7 @@ class FrameProcessor : public FrameProcessorBase { // Helper for process3aState template<typename Src, typename T> bool get3aResult(const CameraMetadata& result, int32_t tag, T* value, bool updatePendingState(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId); Loading @@ -81,15 +83,20 @@ class FrameProcessor : public FrameProcessorBase { // These defaults need to match those in Parameters.cpp AlgState() : afMode(ANDROID_CONTROL_AF_MODE_AUTO), awbMode(ANDROID_CONTROL_AWB_MODE_AUTO), aeState(ANDROID_CONTROL_AE_STATE_INACTIVE), afState(ANDROID_CONTROL_AF_STATE_INACTIVE), awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE), afTriggerId(0), aeTriggerId(0) { afMode((camera_metadata_enum_android_control_af_mode)NOT_SET), awbMode((camera_metadata_enum_android_control_awb_mode)NOT_SET), aeState((camera_metadata_enum_android_control_ae_state)NOT_SET), afState((camera_metadata_enum_android_control_af_state)NOT_SET), awbState((camera_metadata_enum_android_control_awb_state)NOT_SET), afTriggerId(NOT_SET), aeTriggerId(NOT_SET) { } } m3aState; }; AlgState m3aState; // frame number -> pending 3A states that not all data are received yet. KeyedVector<int32_t, AlgState> mPending3AStates; // Whether the partial result is enabled for this device bool mUsePartialResult; Loading services/camera/libcameraservice/device3/Camera3Device.cpp +54 −208 Original line number Diff line number Diff line Loading @@ -2058,176 +2058,6 @@ status_t Camera3Device::registerInFlight(uint32_t frameNumber, return OK; } /** * Check if all 3A fields are ready, and send off a partial 3A-only result * to the output frame queue */ bool Camera3Device::processPartial3AResult( uint32_t frameNumber, const CameraMetadata& partial, const CaptureResultExtras& resultExtras) { // Check if all 3A states are present // The full list of fields is // android.control.afMode // android.control.awbMode // android.control.aeState // android.control.awbState // android.control.afState // android.control.afTriggerID // android.control.aePrecaptureID // TODO: Add android.control.aeMode bool gotAllStates = true; uint8_t afMode; uint8_t awbMode; uint8_t aeState; uint8_t afState; uint8_t awbState; gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE, &afMode, frameNumber); gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE, &awbMode, frameNumber); gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE, &aeState, frameNumber); gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE, &afState, frameNumber); gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE, &awbState, frameNumber); if (!gotAllStates) return false; ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, " "AF state %d, AE state %d, AWB state %d, " "AF trigger %d, AE precapture trigger %d", __FUNCTION__, mId, frameNumber, resultExtras.requestId, afMode, awbMode, afState, aeState, awbState, resultExtras.afTriggerId, resultExtras.precaptureTriggerId); // Got all states, so construct a minimal result to send // In addition to the above fields, this means adding in // android.request.frameCount // android.request.requestId // android.quirks.partialResult (for HAL version below HAL3.2) const size_t kMinimal3AResultEntries = 10; Mutex::Autolock l(mOutputLock); CaptureResult captureResult; captureResult.mResultExtras = resultExtras; captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0); // TODO: change this to sp<CaptureResult>. This will need other changes, including, // but not limited to CameraDeviceBase::getNextResult CaptureResult& min3AResult = *mResultQueue.insert(mResultQueue.end(), captureResult); if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT, // TODO: This is problematic casting. Need to fix CameraMetadata. reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) { return false; } int32_t requestId = resultExtras.requestId; if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID, &requestId, frameNumber)) { return false; } if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) { static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL; if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT, &partialResult, frameNumber)) { return false; } } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE, &afMode, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE, &awbMode, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE, &aeState, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE, &afState, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE, &awbState, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID, &resultExtras.afTriggerId, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID, &resultExtras.precaptureTriggerId, frameNumber)) { return false; } // We only send the aggregated partial when all 3A related metadata are available // For both API1 and API2. // TODO: we probably should pass through all partials to API2 unconditionally. mResultSignal.signal(); return true; } template<typename T> bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag, T* value, uint32_t frameNumber) { (void) frameNumber; camera_metadata_ro_entry_t entry; entry = result.find(tag); if (entry.count == 0) { ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__, mId, frameNumber, get_camera_metadata_tag_name(tag)); return false; } if (sizeof(T) == sizeof(uint8_t)) { *value = entry.data.u8[0]; } else if (sizeof(T) == sizeof(int32_t)) { *value = entry.data.i32[0]; } else { ALOGE("%s: Unexpected type", __FUNCTION__); return false; } return true; } template<typename T> bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag, const T* value, uint32_t frameNumber) { if (result.update(tag, value, 1) != NO_ERROR) { mResultQueue.erase(--mResultQueue.end(), mResultQueue.end()); SET_ERR("Frame %d: Failed to set %s in partial metadata", frameNumber, get_camera_metadata_tag_name(tag)); return false; } return true; } void Camera3Device::returnOutputBuffers( const camera3_stream_buffer_t *outputBuffers, size_t numBuffers, nsecs_t timestamp) { Loading Loading @@ -2295,6 +2125,48 @@ void Camera3Device::removeInFlightRequestIfReadyLocked(int idx) { } } void Camera3Device::insertResultLocked(CaptureResult *result, uint32_t frameNumber, const AeTriggerCancelOverride_t &aeTriggerCancelOverride) { if (result == nullptr) return; if (result->mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, (int32_t*)&frameNumber, 1) != OK) { SET_ERR("Failed to set frame number %d in metadata", frameNumber); return; } if (result->mMetadata.update(ANDROID_REQUEST_ID, &result->mResultExtras.requestId, 1) != OK) { SET_ERR("Failed to set request ID in metadata for frame %d", frameNumber); return; } overrideResultForPrecaptureCancel(&result->mMetadata, aeTriggerCancelOverride); // Valid result, insert into queue List<CaptureResult>::iterator queuedResult = mResultQueue.insert(mResultQueue.end(), CaptureResult(*result)); ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64 ", burstId = %" PRId32, __FUNCTION__, queuedResult->mResultExtras.requestId, queuedResult->mResultExtras.frameNumber, queuedResult->mResultExtras.burstId); mResultSignal.signal(); } void Camera3Device::sendPartialCaptureResult(const camera_metadata_t * partialResult, const CaptureResultExtras &resultExtras, uint32_t frameNumber, const AeTriggerCancelOverride_t &aeTriggerCancelOverride) { Mutex::Autolock l(mOutputLock); CaptureResult captureResult; captureResult.mResultExtras = resultExtras; captureResult.mMetadata = partialResult; insertResultLocked(&captureResult, frameNumber, aeTriggerCancelOverride); } void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, CaptureResultExtras &resultExtras, Loading Loading @@ -2330,16 +2202,6 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, captureResult.mResultExtras = resultExtras; captureResult.mMetadata = pendingMetadata; if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, (int32_t*)&frameNumber, 1) != OK) { SET_ERR("Failed to set frame# in metadata (%d)", frameNumber); return; } else { ALOGVV("%s: Camera %d: Set frame# in metadata (%d)", __FUNCTION__, mId, frameNumber); } // Append any previous partials to form a complete result if (mUsePartialResult && !collectedPartialResult.isEmpty()) { captureResult.mMetadata.append(collectedPartialResult); Loading @@ -2348,26 +2210,14 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, captureResult.mMetadata.sort(); // Check that there's a timestamp in the result metadata camera_metadata_entry entry = captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); camera_metadata_entry entry = captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); if (entry.count == 0) { SET_ERR("No timestamp provided by HAL for frame %d!", frameNumber); return; } overrideResultForPrecaptureCancel(&captureResult.mMetadata, aeTriggerCancelOverride); // Valid result, insert into queue List<CaptureResult>::iterator queuedResult = mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult)); ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64 ", burstId = %" PRId32, __FUNCTION__, queuedResult->mResultExtras.requestId, queuedResult->mResultExtras.frameNumber, queuedResult->mResultExtras.burstId); mResultSignal.signal(); insertResultLocked(&captureResult, frameNumber, aeTriggerCancelOverride); } /** Loading Loading @@ -2444,7 +2294,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { } isPartialResult = (result->partial_result < mNumPartialResults); if (isPartialResult) { request.partialResult.collectedResult.append(result->result); request.collectedPartialResult.append(result->result); } } else { camera_metadata_ro_entry_t partialResultEntry; Loading @@ -2457,21 +2307,17 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { // A partial result. Flag this as such, and collect this // set of metadata into the in-flight entry. isPartialResult = true; request.partialResult.collectedResult.append( request.collectedPartialResult.append( result->result); request.partialResult.collectedResult.erase( request.collectedPartialResult.erase( ANDROID_QUIRKS_PARTIAL_RESULT); } } if (isPartialResult) { // Fire off a 3A-only result if possible if (!request.partialResult.haveSent3A) { request.partialResult.haveSent3A = processPartial3AResult(frameNumber, request.partialResult.collectedResult, request.resultExtras); } // Send partial capture result sendPartialCaptureResult(result->result, request.resultExtras, frameNumber, request.aeTriggerCancelOverride); } } Loading @@ -2486,9 +2332,9 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { return; } if (mUsePartialResult && !request.partialResult.collectedResult.isEmpty()) { !request.collectedPartialResult.isEmpty()) { collectedPartialResult.acquire( request.partialResult.collectedResult); request.collectedPartialResult); } request.haveResultMetadata = true; } Loading Loading @@ -2531,7 +2377,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { if (result->result != NULL && !isPartialResult) { if (shutterTimestamp == 0) { request.pendingMetadata = result->result; request.partialResult.collectedResult = collectedPartialResult; request.collectedPartialResult = collectedPartialResult; } else { CameraMetadata metadata; metadata = result->result; Loading Loading @@ -2709,7 +2555,7 @@ void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg, // send pending result and buffers sendCaptureResult(r.pendingMetadata, r.resultExtras, r.partialResult.collectedResult, msg.frame_number, r.collectedPartialResult, msg.frame_number, r.hasInputBuffer, r.aeTriggerCancelOverride); returnOutputBuffers(r.pendingOutputBuffers.array(), r.pendingOutputBuffers.size(), r.shutterTimestamp); Loading services/camera/libcameraservice/device3/Camera3Device.h +16 −31 Original line number Diff line number Diff line Loading @@ -648,6 +648,10 @@ class Camera3Device : // receives the shutter event. CameraMetadata pendingMetadata; // The metadata of the partial results that framework receives from HAL so far // and has sent out. CameraMetadata collectedPartialResult; // Buffers are added by process_capture_result when output buffers // return from HAL but framework has not yet received the shutter // event. They will be returned to the streams when framework receives Loading @@ -658,19 +662,6 @@ class Camera3Device : // CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL AeTriggerCancelOverride_t aeTriggerCancelOverride; // Fields used by the partial result only struct PartialResultInFlight { // Set by process_capture_result once 3A has been sent to clients bool haveSent3A; // Result metadata collected so far, when partial results are in use CameraMetadata collectedResult; PartialResultInFlight(): haveSent3A(false) { } } partialResult; // Default constructor needed by KeyedVector InFlightRequest() : shutterTimestamp(0), Loading Loading @@ -705,23 +696,6 @@ class Camera3Device : int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); /** * For the partial result, check if all 3A state fields are available * and if so, queue up 3A-only result to the client. Returns true if 3A * is sent. */ bool processPartial3AResult(uint32_t frameNumber, const CameraMetadata& partial, const CaptureResultExtras& resultExtras); // Helpers for reading and writing 3A metadata into to/from partial results template<typename T> bool get3AResult(const CameraMetadata& result, int32_t tag, T* value, uint32_t frameNumber); template<typename T> bool insert3AResult(CameraMetadata &result, int32_t tag, const T* value, uint32_t frameNumber); /** * Override result metadata for cancelling AE precapture trigger applied in * handleAePrecaptureCancelRequest(). Loading Loading @@ -820,13 +794,24 @@ class Camera3Device : void returnOutputBuffers(const camera3_stream_buffer_t *outputBuffers, size_t numBuffers, nsecs_t timestamp); // Insert the capture result given the pending metadata, result extras, // Send a partial capture result. void sendPartialCaptureResult(const camera_metadata_t * partialResult, const CaptureResultExtras &resultExtras, uint32_t frameNumber, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); // Send a total capture result given the pending metadata and result extras, // partial results, and the frame number to the result queue. void sendCaptureResult(CameraMetadata &pendingMetadata, CaptureResultExtras &resultExtras, CameraMetadata &collectedPartialResult, uint32_t frameNumber, bool reprocess, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); // Insert the result to the result queue after updating frame number and overriding AE // trigger cancel. // mOutputLock must be held when calling this function. void insertResultLocked(CaptureResult *result, uint32_t frameNumber, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); /**** Scope for mInFlightLock ****/ // Remove the in-flight request of the given index from mInFlightMap Loading Loading
services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +71 −41 Original line number Diff line number Diff line Loading @@ -53,7 +53,13 @@ FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device, // Check if lens is fixed-focus if (l.mParameters.focusMode == Parameters::FOCUS_MODE_FIXED) { m3aState.afMode = ANDROID_CONTROL_AF_MODE_OFF; } else { m3aState.afMode = ANDROID_CONTROL_AF_MODE_AUTO; } m3aState.awbMode = ANDROID_CONTROL_AWB_MODE_AUTO; m3aState.aeState = ANDROID_CONTROL_AE_STATE_INACTIVE; m3aState.afState = ANDROID_CONTROL_AF_STATE_INACTIVE; m3aState.awbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; } } Loading Loading @@ -253,80 +259,99 @@ status_t FrameProcessor::process3aState(const CaptureResult &frame, if (frameNumber <= mLast3AFrameNumber) { ALOGV("%s: Already sent 3A for frame number %d, skipping", __FUNCTION__, frameNumber); // Remove the entry if there is one for this frame number in mPending3AStates. mPending3AStates.removeItem(frameNumber); return OK; } mLast3AFrameNumber = frameNumber; AlgState pendingState; // Get 3A states from result metadata bool gotAllStates = true; ssize_t index = mPending3AStates.indexOfKey(frameNumber); if (index != NAME_NOT_FOUND) { pendingState = mPending3AStates.valueAt(index); } AlgState new3aState; // Update 3A states from the result. bool gotAllStates = true; // TODO: Also use AE mode, AE trigger ID gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_MODE, &pendingState.afMode, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AF_MODE, &new3aState.afMode, frameNumber, cameraId); gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_MODE, &pendingState.awbMode, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AWB_MODE, &new3aState.awbMode, frameNumber, cameraId); gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AE_STATE, &pendingState.aeState, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AE_STATE, &new3aState.aeState, frameNumber, cameraId); gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AF_STATE, &pendingState.afState, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AF_STATE, &new3aState.afState, frameNumber, cameraId); gotAllStates &= get3aResult<uint8_t>(metadata, ANDROID_CONTROL_AWB_STATE, &new3aState.awbState, frameNumber, cameraId); gotAllStates &= updatePendingState<uint8_t>(metadata, ANDROID_CONTROL_AWB_STATE, &pendingState.awbState, frameNumber, cameraId); if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_2) { new3aState.afTriggerId = frame.mResultExtras.afTriggerId; new3aState.aeTriggerId = frame.mResultExtras.precaptureTriggerId; pendingState.afTriggerId = frame.mResultExtras.afTriggerId; pendingState.aeTriggerId = frame.mResultExtras.precaptureTriggerId; } else { gotAllStates &= get3aResult<int32_t>(metadata, ANDROID_CONTROL_AF_TRIGGER_ID, &new3aState.afTriggerId, frameNumber, cameraId); gotAllStates &= updatePendingState<int32_t>(metadata, ANDROID_CONTROL_AF_TRIGGER_ID, &pendingState.afTriggerId, frameNumber, cameraId); gotAllStates &= get3aResult<int32_t>(metadata, ANDROID_CONTROL_AE_PRECAPTURE_ID, &new3aState.aeTriggerId, frameNumber, cameraId); gotAllStates &= updatePendingState<int32_t>(metadata, ANDROID_CONTROL_AE_PRECAPTURE_ID, &pendingState.aeTriggerId, frameNumber, cameraId); } if (!gotAllStates) return BAD_VALUE; if (!gotAllStates) { // If not all states are received, put the pending state to mPending3AStates. if (index == NAME_NOT_FOUND) { mPending3AStates.add(frameNumber, pendingState); } else { mPending3AStates.replaceValueAt(index, pendingState); } return NOT_ENOUGH_DATA; } if (new3aState.aeState != m3aState.aeState) { // Once all 3A states are received, notify the client about 3A changes. if (pendingState.aeState != m3aState.aeState) { ALOGV("%s: Camera %d: AE state %d->%d", __FUNCTION__, cameraId, m3aState.aeState, new3aState.aeState); client->notifyAutoExposure(new3aState.aeState, new3aState.aeTriggerId); m3aState.aeState, pendingState.aeState); client->notifyAutoExposure(pendingState.aeState, pendingState.aeTriggerId); } if (new3aState.afState != m3aState.afState || new3aState.afMode != m3aState.afMode || new3aState.afTriggerId != m3aState.afTriggerId) { if (pendingState.afState != m3aState.afState || pendingState.afMode != m3aState.afMode || pendingState.afTriggerId != m3aState.afTriggerId) { ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d", __FUNCTION__, cameraId, m3aState.afState, new3aState.afState, m3aState.afMode, new3aState.afMode, m3aState.afTriggerId, new3aState.afTriggerId); client->notifyAutoFocus(new3aState.afState, new3aState.afTriggerId); m3aState.afState, pendingState.afState, m3aState.afMode, pendingState.afMode, m3aState.afTriggerId, pendingState.afTriggerId); client->notifyAutoFocus(pendingState.afState, pendingState.afTriggerId); } if (new3aState.awbState != m3aState.awbState || new3aState.awbMode != m3aState.awbMode) { if (pendingState.awbState != m3aState.awbState || pendingState.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.awbState, pendingState.awbState, m3aState.awbMode, pendingState.awbMode); client->notifyAutoWhitebalance(pendingState.awbState, pendingState.aeTriggerId); } if (index != NAME_NOT_FOUND) { mPending3AStates.removeItemsAt(index); } m3aState = new3aState; m3aState = pendingState; mLast3AFrameNumber = frameNumber; return OK; } template<typename Src, typename T> bool FrameProcessor::get3aResult(const CameraMetadata& result, int32_t tag, bool FrameProcessor::updatePendingState(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId) { camera_metadata_ro_entry_t entry; if (value == NULL) { Loading @@ -335,9 +360,14 @@ bool FrameProcessor::get3aResult(const CameraMetadata& result, int32_t tag, return false; } // Already got the value for this tag. if (*value != static_cast<T>(NOT_SET)) { return true; } entry = result.find(tag); if (entry.count == 0) { ALOGE("%s: Camera %d: No %s provided by HAL for frame %d!", ALOGV("%s: Camera %d: No %s provided by HAL for frame %d in this result!", __FUNCTION__, cameraId, get_camera_metadata_tag_name(tag), frameNumber); return false; Loading
services/camera/libcameraservice/api1/client2/FrameProcessor.h +16 −9 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ class FrameProcessor : public FrameProcessorBase { ~FrameProcessor(); private: static const int32_t NOT_SET = -1; wp<Camera2Client> mClient; bool mSynthesize3ANotify; Loading @@ -63,7 +65,7 @@ class FrameProcessor : public FrameProcessorBase { // Helper for process3aState template<typename Src, typename T> bool get3aResult(const CameraMetadata& result, int32_t tag, T* value, bool updatePendingState(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId); Loading @@ -81,15 +83,20 @@ class FrameProcessor : public FrameProcessorBase { // These defaults need to match those in Parameters.cpp AlgState() : afMode(ANDROID_CONTROL_AF_MODE_AUTO), awbMode(ANDROID_CONTROL_AWB_MODE_AUTO), aeState(ANDROID_CONTROL_AE_STATE_INACTIVE), afState(ANDROID_CONTROL_AF_STATE_INACTIVE), awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE), afTriggerId(0), aeTriggerId(0) { afMode((camera_metadata_enum_android_control_af_mode)NOT_SET), awbMode((camera_metadata_enum_android_control_awb_mode)NOT_SET), aeState((camera_metadata_enum_android_control_ae_state)NOT_SET), afState((camera_metadata_enum_android_control_af_state)NOT_SET), awbState((camera_metadata_enum_android_control_awb_state)NOT_SET), afTriggerId(NOT_SET), aeTriggerId(NOT_SET) { } } m3aState; }; AlgState m3aState; // frame number -> pending 3A states that not all data are received yet. KeyedVector<int32_t, AlgState> mPending3AStates; // Whether the partial result is enabled for this device bool mUsePartialResult; Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +54 −208 Original line number Diff line number Diff line Loading @@ -2058,176 +2058,6 @@ status_t Camera3Device::registerInFlight(uint32_t frameNumber, return OK; } /** * Check if all 3A fields are ready, and send off a partial 3A-only result * to the output frame queue */ bool Camera3Device::processPartial3AResult( uint32_t frameNumber, const CameraMetadata& partial, const CaptureResultExtras& resultExtras) { // Check if all 3A states are present // The full list of fields is // android.control.afMode // android.control.awbMode // android.control.aeState // android.control.awbState // android.control.afState // android.control.afTriggerID // android.control.aePrecaptureID // TODO: Add android.control.aeMode bool gotAllStates = true; uint8_t afMode; uint8_t awbMode; uint8_t aeState; uint8_t afState; uint8_t awbState; gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE, &afMode, frameNumber); gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE, &awbMode, frameNumber); gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE, &aeState, frameNumber); gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE, &afState, frameNumber); gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE, &awbState, frameNumber); if (!gotAllStates) return false; ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, " "AF state %d, AE state %d, AWB state %d, " "AF trigger %d, AE precapture trigger %d", __FUNCTION__, mId, frameNumber, resultExtras.requestId, afMode, awbMode, afState, aeState, awbState, resultExtras.afTriggerId, resultExtras.precaptureTriggerId); // Got all states, so construct a minimal result to send // In addition to the above fields, this means adding in // android.request.frameCount // android.request.requestId // android.quirks.partialResult (for HAL version below HAL3.2) const size_t kMinimal3AResultEntries = 10; Mutex::Autolock l(mOutputLock); CaptureResult captureResult; captureResult.mResultExtras = resultExtras; captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0); // TODO: change this to sp<CaptureResult>. This will need other changes, including, // but not limited to CameraDeviceBase::getNextResult CaptureResult& min3AResult = *mResultQueue.insert(mResultQueue.end(), captureResult); if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT, // TODO: This is problematic casting. Need to fix CameraMetadata. reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) { return false; } int32_t requestId = resultExtras.requestId; if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID, &requestId, frameNumber)) { return false; } if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) { static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL; if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT, &partialResult, frameNumber)) { return false; } } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE, &afMode, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE, &awbMode, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE, &aeState, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE, &afState, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE, &awbState, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID, &resultExtras.afTriggerId, frameNumber)) { return false; } if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID, &resultExtras.precaptureTriggerId, frameNumber)) { return false; } // We only send the aggregated partial when all 3A related metadata are available // For both API1 and API2. // TODO: we probably should pass through all partials to API2 unconditionally. mResultSignal.signal(); return true; } template<typename T> bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag, T* value, uint32_t frameNumber) { (void) frameNumber; camera_metadata_ro_entry_t entry; entry = result.find(tag); if (entry.count == 0) { ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__, mId, frameNumber, get_camera_metadata_tag_name(tag)); return false; } if (sizeof(T) == sizeof(uint8_t)) { *value = entry.data.u8[0]; } else if (sizeof(T) == sizeof(int32_t)) { *value = entry.data.i32[0]; } else { ALOGE("%s: Unexpected type", __FUNCTION__); return false; } return true; } template<typename T> bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag, const T* value, uint32_t frameNumber) { if (result.update(tag, value, 1) != NO_ERROR) { mResultQueue.erase(--mResultQueue.end(), mResultQueue.end()); SET_ERR("Frame %d: Failed to set %s in partial metadata", frameNumber, get_camera_metadata_tag_name(tag)); return false; } return true; } void Camera3Device::returnOutputBuffers( const camera3_stream_buffer_t *outputBuffers, size_t numBuffers, nsecs_t timestamp) { Loading Loading @@ -2295,6 +2125,48 @@ void Camera3Device::removeInFlightRequestIfReadyLocked(int idx) { } } void Camera3Device::insertResultLocked(CaptureResult *result, uint32_t frameNumber, const AeTriggerCancelOverride_t &aeTriggerCancelOverride) { if (result == nullptr) return; if (result->mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, (int32_t*)&frameNumber, 1) != OK) { SET_ERR("Failed to set frame number %d in metadata", frameNumber); return; } if (result->mMetadata.update(ANDROID_REQUEST_ID, &result->mResultExtras.requestId, 1) != OK) { SET_ERR("Failed to set request ID in metadata for frame %d", frameNumber); return; } overrideResultForPrecaptureCancel(&result->mMetadata, aeTriggerCancelOverride); // Valid result, insert into queue List<CaptureResult>::iterator queuedResult = mResultQueue.insert(mResultQueue.end(), CaptureResult(*result)); ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64 ", burstId = %" PRId32, __FUNCTION__, queuedResult->mResultExtras.requestId, queuedResult->mResultExtras.frameNumber, queuedResult->mResultExtras.burstId); mResultSignal.signal(); } void Camera3Device::sendPartialCaptureResult(const camera_metadata_t * partialResult, const CaptureResultExtras &resultExtras, uint32_t frameNumber, const AeTriggerCancelOverride_t &aeTriggerCancelOverride) { Mutex::Autolock l(mOutputLock); CaptureResult captureResult; captureResult.mResultExtras = resultExtras; captureResult.mMetadata = partialResult; insertResultLocked(&captureResult, frameNumber, aeTriggerCancelOverride); } void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, CaptureResultExtras &resultExtras, Loading Loading @@ -2330,16 +2202,6 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, captureResult.mResultExtras = resultExtras; captureResult.mMetadata = pendingMetadata; if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT, (int32_t*)&frameNumber, 1) != OK) { SET_ERR("Failed to set frame# in metadata (%d)", frameNumber); return; } else { ALOGVV("%s: Camera %d: Set frame# in metadata (%d)", __FUNCTION__, mId, frameNumber); } // Append any previous partials to form a complete result if (mUsePartialResult && !collectedPartialResult.isEmpty()) { captureResult.mMetadata.append(collectedPartialResult); Loading @@ -2348,26 +2210,14 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, captureResult.mMetadata.sort(); // Check that there's a timestamp in the result metadata camera_metadata_entry entry = captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); camera_metadata_entry entry = captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP); if (entry.count == 0) { SET_ERR("No timestamp provided by HAL for frame %d!", frameNumber); return; } overrideResultForPrecaptureCancel(&captureResult.mMetadata, aeTriggerCancelOverride); // Valid result, insert into queue List<CaptureResult>::iterator queuedResult = mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult)); ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64 ", burstId = %" PRId32, __FUNCTION__, queuedResult->mResultExtras.requestId, queuedResult->mResultExtras.frameNumber, queuedResult->mResultExtras.burstId); mResultSignal.signal(); insertResultLocked(&captureResult, frameNumber, aeTriggerCancelOverride); } /** Loading Loading @@ -2444,7 +2294,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { } isPartialResult = (result->partial_result < mNumPartialResults); if (isPartialResult) { request.partialResult.collectedResult.append(result->result); request.collectedPartialResult.append(result->result); } } else { camera_metadata_ro_entry_t partialResultEntry; Loading @@ -2457,21 +2307,17 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { // A partial result. Flag this as such, and collect this // set of metadata into the in-flight entry. isPartialResult = true; request.partialResult.collectedResult.append( request.collectedPartialResult.append( result->result); request.partialResult.collectedResult.erase( request.collectedPartialResult.erase( ANDROID_QUIRKS_PARTIAL_RESULT); } } if (isPartialResult) { // Fire off a 3A-only result if possible if (!request.partialResult.haveSent3A) { request.partialResult.haveSent3A = processPartial3AResult(frameNumber, request.partialResult.collectedResult, request.resultExtras); } // Send partial capture result sendPartialCaptureResult(result->result, request.resultExtras, frameNumber, request.aeTriggerCancelOverride); } } Loading @@ -2486,9 +2332,9 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { return; } if (mUsePartialResult && !request.partialResult.collectedResult.isEmpty()) { !request.collectedPartialResult.isEmpty()) { collectedPartialResult.acquire( request.partialResult.collectedResult); request.collectedPartialResult); } request.haveResultMetadata = true; } Loading Loading @@ -2531,7 +2377,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { if (result->result != NULL && !isPartialResult) { if (shutterTimestamp == 0) { request.pendingMetadata = result->result; request.partialResult.collectedResult = collectedPartialResult; request.collectedPartialResult = collectedPartialResult; } else { CameraMetadata metadata; metadata = result->result; Loading Loading @@ -2709,7 +2555,7 @@ void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg, // send pending result and buffers sendCaptureResult(r.pendingMetadata, r.resultExtras, r.partialResult.collectedResult, msg.frame_number, r.collectedPartialResult, msg.frame_number, r.hasInputBuffer, r.aeTriggerCancelOverride); returnOutputBuffers(r.pendingOutputBuffers.array(), r.pendingOutputBuffers.size(), r.shutterTimestamp); Loading
services/camera/libcameraservice/device3/Camera3Device.h +16 −31 Original line number Diff line number Diff line Loading @@ -648,6 +648,10 @@ class Camera3Device : // receives the shutter event. CameraMetadata pendingMetadata; // The metadata of the partial results that framework receives from HAL so far // and has sent out. CameraMetadata collectedPartialResult; // Buffers are added by process_capture_result when output buffers // return from HAL but framework has not yet received the shutter // event. They will be returned to the streams when framework receives Loading @@ -658,19 +662,6 @@ class Camera3Device : // CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL AeTriggerCancelOverride_t aeTriggerCancelOverride; // Fields used by the partial result only struct PartialResultInFlight { // Set by process_capture_result once 3A has been sent to clients bool haveSent3A; // Result metadata collected so far, when partial results are in use CameraMetadata collectedResult; PartialResultInFlight(): haveSent3A(false) { } } partialResult; // Default constructor needed by KeyedVector InFlightRequest() : shutterTimestamp(0), Loading Loading @@ -705,23 +696,6 @@ class Camera3Device : int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); /** * For the partial result, check if all 3A state fields are available * and if so, queue up 3A-only result to the client. Returns true if 3A * is sent. */ bool processPartial3AResult(uint32_t frameNumber, const CameraMetadata& partial, const CaptureResultExtras& resultExtras); // Helpers for reading and writing 3A metadata into to/from partial results template<typename T> bool get3AResult(const CameraMetadata& result, int32_t tag, T* value, uint32_t frameNumber); template<typename T> bool insert3AResult(CameraMetadata &result, int32_t tag, const T* value, uint32_t frameNumber); /** * Override result metadata for cancelling AE precapture trigger applied in * handleAePrecaptureCancelRequest(). Loading Loading @@ -820,13 +794,24 @@ class Camera3Device : void returnOutputBuffers(const camera3_stream_buffer_t *outputBuffers, size_t numBuffers, nsecs_t timestamp); // Insert the capture result given the pending metadata, result extras, // Send a partial capture result. void sendPartialCaptureResult(const camera_metadata_t * partialResult, const CaptureResultExtras &resultExtras, uint32_t frameNumber, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); // Send a total capture result given the pending metadata and result extras, // partial results, and the frame number to the result queue. void sendCaptureResult(CameraMetadata &pendingMetadata, CaptureResultExtras &resultExtras, CameraMetadata &collectedPartialResult, uint32_t frameNumber, bool reprocess, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); // Insert the result to the result queue after updating frame number and overriding AE // trigger cancel. // mOutputLock must be held when calling this function. void insertResultLocked(CaptureResult *result, uint32_t frameNumber, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); /**** Scope for mInFlightLock ****/ // Remove the in-flight request of the given index from mInFlightMap Loading