Make change and version bump to r_aml_300802100 for mainline module file: apex/manifest_codec.json
Change-Id: I66b7034733a224b7bdb395fdf4150a2017419fa0
diff --git a/apex/manifest.json b/apex/manifest.json
index f8d3c79..760095e 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,4 +1,4 @@
{
"name": "com.android.media",
- "version": 300802000
+ "version": 300802100
}
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 1b97232..baf4077 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,4 @@
{
"name": "com.android.media.swcodec",
- "version": 300802000
+ "version": 300802100
}
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
index 9cbfdb0..755051c 100644
--- a/camera/CaptureResult.cpp
+++ b/camera/CaptureResult.cpp
@@ -49,6 +49,9 @@
}
errorPhysicalCameraId = cameraId;
}
+ parcel->readInt64(&lastCompletedRegularFrameNumber);
+ parcel->readInt64(&lastCompletedReprocessFrameNumber);
+ parcel->readInt64(&lastCompletedZslFrameNumber);
return OK;
}
@@ -76,6 +79,9 @@
} else {
parcel->writeBool(false);
}
+ parcel->writeInt64(lastCompletedRegularFrameNumber);
+ parcel->writeInt64(lastCompletedReprocessFrameNumber);
+ parcel->writeInt64(lastCompletedZslFrameNumber);
return OK;
}
diff --git a/camera/include/camera/CaptureResult.h b/camera/include/camera/CaptureResult.h
index dc3d282..f163c1e 100644
--- a/camera/include/camera/CaptureResult.h
+++ b/camera/include/camera/CaptureResult.h
@@ -76,6 +76,34 @@
*/
String16 errorPhysicalCameraId;
+ // The last completed frame numbers shouldn't be checked in onResultReceived() and notifyError()
+ // because the output buffers could be arriving after onResultReceived() and
+ // notifyError(). Given this constraint, we check it for each
+ // onCaptureStarted, and if there is no further onCaptureStarted(),
+ // check for onDeviceIdle() to clear out all pending frame numbers.
+
+ /**
+ * The latest regular request frameNumber for which all buffers and capture result have been
+ * returned or notified as an BUFFER_ERROR/RESULT_ERROR/REQUEST_ERROR. -1 if
+ * none has completed.
+ */
+ int64_t lastCompletedRegularFrameNumber;
+
+ /**
+ * The latest reprocess request frameNumber for which all buffers and capture result have been
+ * returned or notified as an BUFFER_ERROR/RESULT_ERROR/REQUEST_ERROR. -1 if
+ * none has completed.
+ */
+ int64_t lastCompletedReprocessFrameNumber;
+
+ /**
+ * The latest Zsl request frameNumber for which all buffers and capture result have been
+ * returned or notified as an BUFFER_ERROR/RESULT_ERROR/REQUEST_ERROR. -1 if
+ * none has completed.
+ */
+ int64_t lastCompletedZslFrameNumber;
+
+
/**
* Constructor initializes object as invalid by setting requestId to be -1.
*/
@@ -87,7 +115,10 @@
frameNumber(0),
partialResultCount(0),
errorStreamId(-1),
- errorPhysicalCameraId() {
+ errorPhysicalCameraId(),
+ lastCompletedRegularFrameNumber(-1),
+ lastCompletedReprocessFrameNumber(-1),
+ lastCompletedZslFrameNumber(-1) {
}
/**
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 0d7180a..c15c5a5 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -1336,56 +1336,97 @@
void
CameraDevice::checkAndFireSequenceCompleteLocked() {
int64_t completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
- //std::map<int, int64_t> mSequenceLastFrameNumberMap;
auto it = mSequenceLastFrameNumberMap.begin();
while (it != mSequenceLastFrameNumberMap.end()) {
int sequenceId = it->first;
- int64_t lastFrameNumber = it->second;
- bool seqCompleted = false;
- bool hasCallback = true;
+ int64_t lastFrameNumber = it->second.lastFrameNumber;
+ bool hasCallback = true;
+
+ if (mRemote == nullptr) {
+ ALOGW("Camera %s closed while checking sequence complete", getId());
+ return;
+ }
+ ALOGV("%s: seq %d's last frame number %" PRId64 ", completed %" PRId64,
+ __FUNCTION__, sequenceId, lastFrameNumber, completedFrameNumber);
+ if (!it->second.isSequenceCompleted) {
+ // Check if there is callback for this sequence
+ // This should not happen because we always register callback (with nullptr inside)
+ if (mSequenceCallbackMap.count(sequenceId) == 0) {
+ ALOGW("No callback found for sequenceId %d", sequenceId);
+ hasCallback = false;
+ }
+
+ if (lastFrameNumber <= completedFrameNumber) {
+ ALOGV("Mark sequenceId %d as sequence completed", sequenceId);
+ it->second.isSequenceCompleted = true;
+ }
+
+ if (it->second.isSequenceCompleted && hasCallback) {
+ auto cbIt = mSequenceCallbackMap.find(sequenceId);
+ CallbackHolder cbh = cbIt->second;
+
+ // send seq complete callback
+ sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
+ msg->setPointer(kContextKey, cbh.mContext);
+ msg->setObject(kSessionSpKey, cbh.mSession);
+ msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
+ msg->setInt32(kSequenceIdKey, sequenceId);
+ msg->setInt64(kFrameNumberKey, lastFrameNumber);
+
+ // Clear the session sp before we send out the message
+ // This will guarantee the rare case where the message is processed
+ // before cbh goes out of scope and causing we call the session
+ // destructor while holding device lock
+ cbh.mSession.clear();
+ postSessionMsgAndCleanup(msg);
+ }
+ }
+
+ if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
+ if (mSequenceCallbackMap.find(sequenceId) != mSequenceCallbackMap.end()) {
+ mSequenceCallbackMap.erase(sequenceId);
+ }
+ it = mSequenceLastFrameNumberMap.erase(it);
+ ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
+ } else {
+ ++it;
+ }
+ }
+}
+
+void
+CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber) {
+ auto it = mSequenceLastFrameNumberMap.begin();
+ while (it != mSequenceLastFrameNumberMap.end()) {
+ int sequenceId = it->first;
+ int64_t lastFrameNumber = it->second.lastFrameNumber;
if (mRemote == nullptr) {
ALOGW("Camera %s closed while checking sequence complete", getId());
return;
}
- // Check if there is callback for this sequence
- // This should not happen because we always register callback (with nullptr inside)
- if (mSequenceCallbackMap.count(sequenceId) == 0) {
- ALOGW("No callback found for sequenceId %d", sequenceId);
- hasCallback = false;
- }
+ ALOGV("%s: seq %d's last frame number %" PRId64
+ ", completed inflight frame number %" PRId64,
+ __FUNCTION__, sequenceId, lastFrameNumber,
+ lastCompletedRegularFrameNumber);
+ if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
+ if (it->second.isSequenceCompleted) {
+ // Check if there is callback for this sequence
+ // This should not happen because we always register callback (with nullptr inside)
+ if (mSequenceCallbackMap.count(sequenceId) == 0) {
+ ALOGW("No callback found for sequenceId %d", sequenceId);
+ } else {
+ mSequenceCallbackMap.erase(sequenceId);
+ }
- if (lastFrameNumber <= completedFrameNumber) {
- ALOGV("seq %d reached last frame %" PRId64 ", completed %" PRId64,
- sequenceId, lastFrameNumber, completedFrameNumber);
- seqCompleted = true;
- }
-
- if (seqCompleted && hasCallback) {
- // remove callback holder from callback map
- auto cbIt = mSequenceCallbackMap.find(sequenceId);
- CallbackHolder cbh = cbIt->second;
- mSequenceCallbackMap.erase(cbIt);
- // send seq complete callback
- sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
- msg->setPointer(kContextKey, cbh.mContext);
- msg->setObject(kSessionSpKey, cbh.mSession);
- msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
- msg->setInt32(kSequenceIdKey, sequenceId);
- msg->setInt64(kFrameNumberKey, lastFrameNumber);
-
- // Clear the session sp before we send out the message
- // This will guarantee the rare case where the message is processed
- // before cbh goes out of scope and causing we call the session
- // destructor while holding device lock
- cbh.mSession.clear();
- postSessionMsgAndCleanup(msg);
- }
-
- // No need to track sequence complete if there is no callback registered
- if (seqCompleted || !hasCallback) {
- it = mSequenceLastFrameNumberMap.erase(it);
+ it = mSequenceLastFrameNumberMap.erase(it);
+ ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
+ } else {
+ ALOGV("Mark sequenceId %d as inflight completed", sequenceId);
+ it->second.isInflightCompleted = true;
+ ++it;
+ }
} else {
++it;
}
@@ -1480,6 +1521,9 @@
return ret;
}
+ dev->removeCompletedCallbackHolderLocked(
+ std::numeric_limits<int64_t>::max()/*lastCompletedRegularFrameNumber*/);
+
if (dev->mIdle) {
// Already in idle state. Possibly other thread did waitUntilIdle
return ret;
@@ -1522,6 +1566,9 @@
return ret;
}
+ dev->removeCompletedCallbackHolderLocked(
+ resultExtras.lastCompletedRegularFrameNumber);
+
int sequenceId = resultExtras.requestId;
int32_t burstId = resultExtras.burstId;
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 6c2ceb3..d937865 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -267,8 +267,23 @@
static const int REQUEST_ID_NONE = -1;
int mRepeatingSequenceId = REQUEST_ID_NONE;
- // sequence id -> last frame number map
- std::map<int, int64_t> mSequenceLastFrameNumberMap;
+ // sequence id -> last frame number holder map
+ struct RequestLastFrameNumberHolder {
+ int64_t lastFrameNumber;
+ // Whether the current sequence is completed (capture results are
+ // generated). May be set to true, but
+ // not removed from the map if not all inflight requests in the sequence
+ // have been completed.
+ bool isSequenceCompleted = false;
+ // Whether all inflight requests in the sequence are completed
+ // (capture results and buffers are generated). May be
+ // set to true, but not removed from the map yet if the capture results
+ // haven't been delivered to the app yet.
+ bool isInflightCompleted = false;
+ RequestLastFrameNumberHolder(int64_t lastFN) :
+ lastFrameNumber(lastFN) {}
+ };
+ std::map<int, RequestLastFrameNumberHolder> mSequenceLastFrameNumberMap;
struct CallbackHolder {
CallbackHolder(sp<ACameraCaptureSession> session,
@@ -338,6 +353,7 @@
void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber);
void checkAndFireSequenceCompleteLocked();
+ void removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber);
// Misc variables
int32_t mShadingMapSize[2]; // const after constructor
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 1a0881f..a63f402 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -620,7 +620,8 @@
if (mPendingInputFrames.find(mAppSegmentFrameNumbers.front()) == mPendingInputFrames.end()) {
ALOGE("%s: mPendingInputFrames doesn't contain frameNumber %" PRId64, __FUNCTION__,
mAppSegmentFrameNumbers.front());
- mInputYuvBuffers.erase(it);
+ mInputAppSegmentBuffers.erase(it);
+ mAppSegmentFrameNumbers.pop();
continue;
}
@@ -664,6 +665,7 @@
ALOGE("%s: mPendingInputFrames doesn't contain frameNumber %" PRId64, __FUNCTION__,
mMainImageFrameNumbers.front());
mInputYuvBuffers.erase(it);
+ mMainImageFrameNumbers.pop();
continue;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index deeec7e..a898df9 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1043,8 +1043,9 @@
}
CaptureOutputStates states {
mId,
- mInFlightLock, mInFlightMap,
- mOutputLock, mResultQueue, mResultSignal,
+ mInFlightLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
mNextShutterFrameNumber,
mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
mNextResultFrameNumber,
@@ -1100,8 +1101,9 @@
CaptureOutputStates states {
mId,
- mInFlightLock, mInFlightMap,
- mOutputLock, mResultQueue, mResultSignal,
+ mInFlightLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
mNextShutterFrameNumber,
mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
mNextResultFrameNumber,
@@ -1139,8 +1141,9 @@
CaptureOutputStates states {
mId,
- mInFlightLock, mInFlightMap,
- mOutputLock, mResultQueue, mResultSignal,
+ mInFlightLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
mNextShutterFrameNumber,
mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
mNextResultFrameNumber,
@@ -5901,11 +5904,13 @@
// though technically no other thread should be talking to Camera3Device at this point
Camera3OfflineStates offlineStates(
mTagMonitor, mVendorTagId, mUseHalBufManager, mNeedFixupMonochromeTags,
- mUsePartialResult, mNumPartialResults, mNextResultFrameNumber,
- mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
- mNextShutterFrameNumber, mNextReprocessShutterFrameNumber,
- mNextZslStillShutterFrameNumber, mDeviceInfo, mPhysicalDeviceInfoMap,
- mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers);
+ mUsePartialResult, mNumPartialResults, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mNextResultFrameNumber, mNextReprocessResultFrameNumber,
+ mNextZslStillResultFrameNumber, mNextShutterFrameNumber,
+ mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
+ mDeviceInfo, mPhysicalDeviceInfoMap, mDistortionMappers,
+ mZoomRatioMappers, mRotateAndCropMappers);
*session = new Camera3OfflineSession(mId, inputStream, offlineStreamSet,
std::move(bufferRecords), offlineReqs, offlineStates, offlineSession);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 2069841..408f1f9 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1010,6 +1010,9 @@
std::mutex mInFlightLock;
camera3::InFlightRequestMap mInFlightMap;
nsecs_t mExpectedInflightDuration = 0;
+ int64_t mLastCompletedRegularFrameNumber = -1;
+ int64_t mLastCompletedReprocessFrameNumber = -1;
+ int64_t mLastCompletedZslFrameNumber = -1;
// End of mInFlightLock protection scope
int mInFlightStatusId; // const after initialize
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
index 5942868..95f9633 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
@@ -61,6 +61,9 @@
mNeedFixupMonochromeTags(offlineStates.mNeedFixupMonochromeTags),
mUsePartialResult(offlineStates.mUsePartialResult),
mNumPartialResults(offlineStates.mNumPartialResults),
+ mLastCompletedRegularFrameNumber(offlineStates.mLastCompletedRegularFrameNumber),
+ mLastCompletedReprocessFrameNumber(offlineStates.mLastCompletedReprocessFrameNumber),
+ mLastCompletedZslFrameNumber(offlineStates.mLastCompletedZslFrameNumber),
mNextResultFrameNumber(offlineStates.mNextResultFrameNumber),
mNextReprocessResultFrameNumber(offlineStates.mNextReprocessResultFrameNumber),
mNextZslStillResultFrameNumber(offlineStates.mNextZslStillResultFrameNumber),
@@ -247,8 +250,9 @@
CaptureOutputStates states {
mId,
- mOfflineReqsLock, mOfflineReqs,
- mOutputLock, mResultQueue, mResultSignal,
+ mOfflineReqsLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
mNextShutterFrameNumber,
mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
mNextResultFrameNumber,
@@ -285,8 +289,9 @@
CaptureOutputStates states {
mId,
- mOfflineReqsLock, mOfflineReqs,
- mOutputLock, mResultQueue, mResultSignal,
+ mOfflineReqsLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
mNextShutterFrameNumber,
mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
mNextResultFrameNumber,
@@ -318,8 +323,9 @@
CaptureOutputStates states {
mId,
- mOfflineReqsLock, mOfflineReqs,
- mOutputLock, mResultQueue, mResultSignal,
+ mOfflineReqsLock, mLastCompletedRegularFrameNumber,
+ mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
+ mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
mNextShutterFrameNumber,
mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
mNextResultFrameNumber,
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.h b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
index 208f70d..c4c7a85 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
@@ -57,10 +57,11 @@
const TagMonitor& tagMonitor, const metadata_vendor_id_t vendorTagId,
const bool useHalBufManager, const bool needFixupMonochromeTags,
const bool usePartialResult, const uint32_t numPartialResults,
- const uint32_t nextResultFN, const uint32_t nextReprocResultFN,
- const uint32_t nextZslResultFN, const uint32_t nextShutterFN,
- const uint32_t nextReprocShutterFN, const uint32_t nextZslShutterFN,
- const CameraMetadata& deviceInfo,
+ const int64_t lastCompletedRegularFN, const int64_t lastCompletedReprocessFN,
+ const int64_t lastCompletedZslFN, const uint32_t nextResultFN,
+ const uint32_t nextReprocResultFN, const uint32_t nextZslResultFN,
+ const uint32_t nextShutterFN, const uint32_t nextReprocShutterFN,
+ const uint32_t nextZslShutterFN, const CameraMetadata& deviceInfo,
const std::unordered_map<std::string, CameraMetadata>& physicalDeviceInfoMap,
const std::unordered_map<std::string, camera3::DistortionMapper>& distortionMappers,
const std::unordered_map<std::string, camera3::ZoomRatioMapper>& zoomRatioMappers,
@@ -69,6 +70,9 @@
mTagMonitor(tagMonitor), mVendorTagId(vendorTagId),
mUseHalBufManager(useHalBufManager), mNeedFixupMonochromeTags(needFixupMonochromeTags),
mUsePartialResult(usePartialResult), mNumPartialResults(numPartialResults),
+ mLastCompletedRegularFrameNumber(lastCompletedRegularFN),
+ mLastCompletedReprocessFrameNumber(lastCompletedReprocessFN),
+ mLastCompletedZslFrameNumber(lastCompletedZslFN),
mNextResultFrameNumber(nextResultFN),
mNextReprocessResultFrameNumber(nextReprocResultFN),
mNextZslStillResultFrameNumber(nextZslResultFN),
@@ -90,6 +94,15 @@
const bool mUsePartialResult;
const uint32_t mNumPartialResults;
+ // The last completed (buffers, result metadata, and error notify) regular
+ // request frame number
+ const int64_t mLastCompletedRegularFrameNumber;
+ // The last completed (buffers, result metadata, and error notify) reprocess
+ // request frame number
+ const int64_t mLastCompletedReprocessFrameNumber;
+ // The last completed (buffers, result metadata, and error notify) zsl
+ // request frame number
+ const int64_t mLastCompletedZslFrameNumber;
// the minimal frame number of the next non-reprocess result
const uint32_t mNextResultFrameNumber;
// the minimal frame number of the next reprocess result
@@ -214,6 +227,12 @@
std::mutex mOutputLock;
std::list<CaptureResult> mResultQueue;
std::condition_variable mResultSignal;
+ // the last completed frame number of regular requests
+ int64_t mLastCompletedRegularFrameNumber;
+ // the last completed frame number of reprocess requests
+ int64_t mLastCompletedReprocessFrameNumber;
+ // the last completed frame number of ZSL still capture requests
+ int64_t mLastCompletedZslFrameNumber;
// the minimal frame number of the next non-reprocess result
uint32_t mNextResultFrameNumber;
// the minimal frame number of the next reprocess result
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index 603f516..eea5ef1 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -405,8 +405,8 @@
// In the case of a successful request:
// all input and output buffers, all result metadata, shutter callback
// arrived.
- // In the case of a unsuccessful request:
- // all input and output buffers arrived.
+ // In the case of an unsuccessful request:
+ // all input and output buffers, as well as request/result error notifications, arrived.
if (request.numBuffersLeft == 0 &&
(request.skipResultMetadata ||
(request.haveResultMetadata && shutterTimestamp != 0))) {
@@ -434,7 +434,17 @@
states.useHalBufManager, states.listener,
request.pendingOutputBuffers.array(),
request.pendingOutputBuffers.size(), 0, /*timestampIncreasing*/true,
- request.outputSurfaces, request.resultExtras);
+ request.outputSurfaces, request.resultExtras,
+ request.errorBufStrategy);
+
+ // Note down the just completed frame number
+ if (request.hasInputBuffer) {
+ states.lastCompletedReprocessFrameNumber = frameNumber;
+ } else if (request.zslCapture) {
+ states.lastCompletedZslFrameNumber = frameNumber;
+ } else {
+ states.lastCompletedRegularFrameNumber = frameNumber;
+ }
removeInFlightMapEntryLocked(states, idx);
ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
@@ -487,10 +497,13 @@
InFlightRequest &request = states.inflightMap.editValueAt(idx);
ALOGVV("%s: got InFlightRequest requestId = %" PRId32
", frameNumber = %" PRId64 ", burstId = %" PRId32
- ", partialResultCount = %d, hasCallback = %d",
+ ", partialResultCount = %d/%d, hasCallback = %d, num_output_buffers %d"
+ ", usePartialResult = %d",
__FUNCTION__, request.resultExtras.requestId,
request.resultExtras.frameNumber, request.resultExtras.burstId,
- result->partial_result, request.hasCallback);
+ result->partial_result, states.numPartialResults,
+ request.hasCallback, result->num_output_buffers,
+ states.usePartialResult);
// Always update the partial count to the latest one if it's not 0
// (buffers only). When framework aggregates adjacent partial results
// into one, the latest partial count will be used.
@@ -555,6 +568,7 @@
request.collectedPartialResult);
}
request.haveResultMetadata = true;
+ request.errorBufStrategy = ERROR_BUF_RETURN_NOTIFY;
}
uint32_t numBuffersReturned = result->num_output_buffers;
@@ -581,18 +595,14 @@
request.sensorTimestamp = entry.data.i64[0];
}
- // If shutter event isn't received yet, append the output buffers to
- // the in-flight request. Otherwise, return the output buffers to
- // streams.
- if (shutterTimestamp == 0) {
- request.pendingOutputBuffers.appendArray(result->output_buffers,
+ // If shutter event isn't received yet, do not return the pending output
+ // buffers.
+ request.pendingOutputBuffers.appendArray(result->output_buffers,
result->num_output_buffers);
- } else {
- bool timestampIncreasing = !(request.zslCapture || request.hasInputBuffer);
- returnOutputBuffers(states.useHalBufManager, states.listener,
- result->output_buffers, result->num_output_buffers,
- shutterTimestamp, timestampIncreasing,
- request.outputSurfaces, request.resultExtras);
+ if (shutterTimestamp != 0) {
+ returnAndRemovePendingOutputBuffers(
+ states.useHalBufManager, states.listener,
+ request);
}
if (result->result != NULL && !isPartialResult) {
@@ -791,10 +801,26 @@
const camera3_stream_buffer_t *outputBuffers, size_t numBuffers,
nsecs_t timestamp, bool timestampIncreasing,
const SurfaceMap& outputSurfaces,
- const CaptureResultExtras &inResultExtras) {
+ const CaptureResultExtras &inResultExtras,
+ ERROR_BUF_STRATEGY errorBufStrategy) {
for (size_t i = 0; i < numBuffers; i++)
{
+ Camera3StreamInterface *stream = Camera3Stream::cast(outputBuffers[i].stream);
+ int streamId = stream->getId();
+
+ // Call notify(ERROR_BUFFER) if necessary.
+ if (outputBuffers[i].status == CAMERA3_BUFFER_STATUS_ERROR &&
+ errorBufStrategy == ERROR_BUF_RETURN_NOTIFY) {
+ if (listener != nullptr) {
+ CaptureResultExtras extras = inResultExtras;
+ extras.errorStreamId = streamId;
+ listener->notifyError(
+ hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER,
+ extras);
+ }
+ }
+
if (outputBuffers[i].buffer == nullptr) {
if (!useHalBufManager) {
// With HAL buffer management API, HAL sometimes will have to return buffers that
@@ -805,20 +831,23 @@
continue;
}
- Camera3StreamInterface *stream = Camera3Stream::cast(outputBuffers[i].stream);
- int streamId = stream->getId();
const auto& it = outputSurfaces.find(streamId);
status_t res = OK;
- if (it != outputSurfaces.end()) {
- res = stream->returnBuffer(
- outputBuffers[i], timestamp, timestampIncreasing, it->second,
- inResultExtras.frameNumber);
- } else {
- res = stream->returnBuffer(
- outputBuffers[i], timestamp, timestampIncreasing, std::vector<size_t> (),
- inResultExtras.frameNumber);
- }
+ // Do not return the buffer if the buffer status is error, and the error
+ // buffer strategy is CACHE.
+ if (outputBuffers[i].status != CAMERA3_BUFFER_STATUS_ERROR ||
+ errorBufStrategy != ERROR_BUF_CACHE) {
+ if (it != outputSurfaces.end()) {
+ res = stream->returnBuffer(
+ outputBuffers[i], timestamp, timestampIncreasing, it->second,
+ inResultExtras.frameNumber);
+ } else {
+ res = stream->returnBuffer(
+ outputBuffers[i], timestamp, timestampIncreasing, std::vector<size_t> (),
+ inResultExtras.frameNumber);
+ }
+ }
// Note: stream may be deallocated at this point, if this buffer was
// the last reference to it.
if (res == NO_INIT || res == DEAD_OBJECT) {
@@ -848,6 +877,28 @@
}
}
+void returnAndRemovePendingOutputBuffers(bool useHalBufManager,
+ sp<NotificationListener> listener, InFlightRequest& request) {
+ bool timestampIncreasing = !(request.zslCapture || request.hasInputBuffer);
+ returnOutputBuffers(useHalBufManager, listener,
+ request.pendingOutputBuffers.array(),
+ request.pendingOutputBuffers.size(),
+ request.shutterTimestamp, timestampIncreasing,
+ request.outputSurfaces, request.resultExtras,
+ request.errorBufStrategy);
+
+ // Remove error buffers that are not cached.
+ for (auto iter = request.pendingOutputBuffers.begin();
+ iter != request.pendingOutputBuffers.end(); ) {
+ if (request.errorBufStrategy != ERROR_BUF_CACHE ||
+ iter->status != CAMERA3_BUFFER_STATUS_ERROR) {
+ iter = request.pendingOutputBuffers.erase(iter);
+ } else {
+ iter++;
+ }
+ }
+}
+
void notifyShutter(CaptureOutputStates& states, const camera3_shutter_msg_t &msg) {
ATRACE_CALL();
ssize_t idx;
@@ -899,6 +950,12 @@
msg.frame_number, r.resultExtras.requestId, msg.timestamp);
// Call listener, if any
if (states.listener != nullptr) {
+ r.resultExtras.lastCompletedRegularFrameNumber =
+ states.lastCompletedRegularFrameNumber;
+ r.resultExtras.lastCompletedReprocessFrameNumber =
+ states.lastCompletedReprocessFrameNumber;
+ r.resultExtras.lastCompletedZslFrameNumber =
+ states.lastCompletedZslFrameNumber;
states.listener->notifyShutter(r.resultExtras, msg.timestamp);
}
// send pending result and buffers
@@ -908,13 +965,8 @@
r.hasInputBuffer, r.zslCapture && r.stillCapture,
r.rotateAndCropAuto, r.cameraIdsWithZoom, r.physicalMetadatas);
}
- bool timestampIncreasing = !(r.zslCapture || r.hasInputBuffer);
- returnOutputBuffers(
- states.useHalBufManager, states.listener,
- r.pendingOutputBuffers.array(),
- r.pendingOutputBuffers.size(), r.shutterTimestamp, timestampIncreasing,
- r.outputSurfaces, r.resultExtras);
- r.pendingOutputBuffers.clear();
+ returnAndRemovePendingOutputBuffers(
+ states.useHalBufManager, states.listener, r);
removeInFlightRequestIfReadyLocked(states, idx);
}
@@ -968,7 +1020,6 @@
break;
case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
- case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
{
std::lock_guard<std::mutex> l(states.inflightLock);
ssize_t idx = states.inflightMap.indexOfKey(msg.frame_number);
@@ -976,7 +1027,7 @@
InFlightRequest &r = states.inflightMap.editValueAt(idx);
r.requestStatus = msg.error_code;
resultExtras = r.resultExtras;
- bool logicalDeviceResultError = false;
+ bool physicalDeviceResultError = false;
if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT ==
errorCode) {
if (physicalCameraId.size() > 0) {
@@ -990,23 +1041,22 @@
}
r.physicalCameraIds.erase(iter);
resultExtras.errorPhysicalCameraId = physicalCameraId;
- } else {
- logicalDeviceResultError = true;
+ physicalDeviceResultError = true;
}
}
- if (logicalDeviceResultError
- || hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST ==
- errorCode) {
+ if (!physicalDeviceResultError) {
r.skipResultMetadata = true;
- }
- if (logicalDeviceResultError) {
- // In case of missing result check whether the buffers
- // returned. If they returned, then remove inflight
- // request.
- // TODO: should we call this for ERROR_CAMERA_REQUEST as well?
- // otherwise we are depending on HAL to send the buffers back after
- // calling notifyError. Not sure if that's in the spec.
+ if (hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_RESULT
+ == errorCode) {
+ r.errorBufStrategy = ERROR_BUF_RETURN_NOTIFY;
+ } else {
+ // errorCode is ERROR_CAMERA_REQUEST
+ r.errorBufStrategy = ERROR_BUF_RETURN;
+ }
+
+ // Check whether the buffers returned. If they returned,
+ // remove inflight request.
removeInFlightRequestIfReadyLocked(states, idx);
}
} else {
@@ -1024,6 +1074,10 @@
states.cameraId.string(), __FUNCTION__);
}
break;
+ case hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
+ // Do not depend on HAL ERROR_CAMERA_BUFFER to send buffer error
+ // callback to the app. Rather, use STATUS_ERROR of image buffers.
+ break;
default:
// SET_ERR calls notifyError
SET_ERR("Unknown error message from HAL: %d", msg.error_code);
@@ -1338,8 +1392,14 @@
request.pendingOutputBuffers.array(),
request.pendingOutputBuffers.size(), 0,
/*timestampIncreasing*/true, request.outputSurfaces,
- request.resultExtras);
+ request.resultExtras, request.errorBufStrategy);
+ ALOGW("%s: Frame %d | Timestamp: %" PRId64 ", metadata"
+ " arrived: %s, buffers left: %d.\n", __FUNCTION__,
+ states.inflightMap.keyAt(idx), request.shutterTimestamp,
+ request.haveResultMetadata ? "true" : "false",
+ request.numBuffersLeft);
}
+
states.inflightMap.clear();
states.inflightIntf.onInflightMapFlushedLocked();
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index fbb47f8..9946312 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -44,7 +44,9 @@
/**
* Helper methods shared between Camera3Device/Camera3OfflineSession for HAL callbacks
*/
- // helper function to return the output buffers to output streams.
+
+ // helper function to return the output buffers to output streams. The
+ // function also optionally calls notify(ERROR_BUFFER).
void returnOutputBuffers(
bool useHalBufManager,
sp<NotificationListener> listener, // Only needed when outputSurfaces is not empty
@@ -53,13 +55,25 @@
// The following arguments are only meant for surface sharing use case
const SurfaceMap& outputSurfaces = SurfaceMap{},
// Used to send buffer error callback when failing to return buffer
- const CaptureResultExtras &resultExtras = CaptureResultExtras{});
+ const CaptureResultExtras &resultExtras = CaptureResultExtras{},
+ ERROR_BUF_STRATEGY errorBufStrategy = ERROR_BUF_RETURN);
+
+ // helper function to return the output buffers to output streams, and
+ // remove the returned buffers from the inflight request's pending buffers
+ // vector.
+ void returnAndRemovePendingOutputBuffers(
+ bool useHalBufManager,
+ sp<NotificationListener> listener, // Only needed when outputSurfaces is not empty
+ InFlightRequest& request);
// Camera3Device/Camera3OfflineSession internal states used in notify/processCaptureResult
// callbacks
struct CaptureOutputStates {
const String8& cameraId;
std::mutex& inflightLock;
+ int64_t& lastCompletedRegularFrameNumber;
+ int64_t& lastCompletedZslFrameNumber;
+ int64_t& lastCompletedReprocessFrameNumber;
InFlightRequestMap& inflightMap; // end of inflightLock scope
std::mutex& outputLock;
std::list<CaptureResult>& resultQueue;
diff --git a/services/camera/libcameraservice/device3/InFlightRequest.h b/services/camera/libcameraservice/device3/InFlightRequest.h
index 424043b..da4f228 100644
--- a/services/camera/libcameraservice/device3/InFlightRequest.h
+++ b/services/camera/libcameraservice/device3/InFlightRequest.h
@@ -32,7 +32,18 @@
namespace camera3 {
+typedef enum {
+ // Cache the buffers with STATUS_ERROR within InFlightRequest
+ ERROR_BUF_CACHE,
+ // Return the buffers with STATUS_ERROR to the buffer queue
+ ERROR_BUF_RETURN,
+ // Return the buffers with STATUS_ERROR to the buffer queue, and call
+ // notify(ERROR_BUFFER) as well
+ ERROR_BUF_RETURN_NOTIFY
+} ERROR_BUF_STRATEGY;
+
struct InFlightRequest {
+
// Set by notify() SHUTTER call.
nsecs_t shutterTimestamp;
// Set by process_capture_result().
@@ -43,6 +54,9 @@
// Decremented by calls to process_capture_result with valid output
// and input buffers
int numBuffersLeft;
+
+ // The inflight request is considered complete if all buffers are returned
+
CaptureResultExtras resultExtras;
// If this request has any input buffer
bool hasInputBuffer;
@@ -79,6 +93,10 @@
// REQUEST/RESULT error.
bool skipResultMetadata;
+ // Whether the buffers with STATUS_ERROR should be cached as pending buffers,
+ // returned to the buffer queue, or returned to the buffer queue and notify with ERROR_BUFFER.
+ ERROR_BUF_STRATEGY errorBufStrategy;
+
// The physical camera ids being requested.
std::set<String8> physicalCameraIds;
@@ -114,6 +132,7 @@
hasCallback(true),
maxExpectedDuration(kDefaultExpectedDuration),
skipResultMetadata(false),
+ errorBufStrategy(ERROR_BUF_CACHE),
stillCapture(false),
zslCapture(false),
rotateAndCropAuto(false) {
@@ -134,6 +153,7 @@
hasCallback(hasAppCallback),
maxExpectedDuration(maxDuration),
skipResultMetadata(false),
+ errorBufStrategy(ERROR_BUF_CACHE),
physicalCameraIds(physicalCameraIdSet),
stillCapture(isStillCapture),
zslCapture(isZslCapture),