Camera: Pass system health metrics to ServiceProxy
- Measure session statistics:
- Camera open, close, and session creation latency
- Session information such as camera id, is_ndk, operating mode,
and reconfiguration count.
- Measure stream statistics:
- width, height, format, dataspace, usage
- max buffer count
- buffer loss count
- startup latency.
Test: ./out/host/linux-x86/bin/statsd_testdrive 227
Test: Camera CTS, VNDK test
Bug: 154159000
Change-Id: I082ef26a312bddbfd4abcc2148728a4b7bf8a9f6
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index d27f11f..50ef953 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -61,6 +61,7 @@
#include "CameraService.h"
#include "utils/CameraThreadState.h"
#include "utils/TraceHFR.h"
+#include "utils/CameraServiceProxyWrapper.h"
#include <algorithm>
#include <tuple>
@@ -867,7 +868,7 @@
status_t Camera3Device::convertMetadataListToRequestListLocked(
const List<const PhysicalCameraSettingsList> &metadataList,
const std::list<const SurfaceMap> &surfaceMaps,
- bool repeating,
+ bool repeating, nsecs_t requestTimeNs,
RequestList *requestList) {
if (requestList == NULL) {
CLOGE("requestList cannot be NULL.");
@@ -886,6 +887,7 @@
}
newRequest->mRepeating = repeating;
+ newRequest->mRequestTimeNs = requestTimeNs;
// Setup burst Id and request Id
newRequest->mResultExtras.burstId = burstId++;
@@ -953,6 +955,8 @@
/*out*/
int64_t *lastFrameNumber) {
ATRACE_CALL();
+ nsecs_t requestTimeNs = systemTime();
+
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
@@ -965,7 +969,7 @@
RequestList requestList;
res = convertMetadataListToRequestListLocked(requests, surfaceMaps,
- repeating, /*out*/&requestList);
+ repeating, requestTimeNs, /*out*/&requestList);
if (res != OK) {
// error logged by previous call
return res;
@@ -997,7 +1001,7 @@
const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
requestStreamBuffers_cb _hidl_cb) {
RequestBufferStates states {
- mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams,
+ mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
*this, *mInterface, *this};
camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
return hardware::Void();
@@ -1006,7 +1010,7 @@
hardware::Return<void> Camera3Device::returnStreamBuffers(
const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
ReturnBufferStates states {
- mId, mUseHalBufManager, mOutputStreams, *mInterface};
+ mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder, *mInterface};
camera3::returnStreamBuffers(states, buffers);
return hardware::Void();
}
@@ -1054,7 +1058,8 @@
mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
- mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+ *mInterface
};
for (const auto& result : results) {
@@ -1112,7 +1117,8 @@
mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
- mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+ *mInterface
};
for (const auto& result : results) {
@@ -1152,7 +1158,8 @@
mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
- mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, *mInterface
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+ *mInterface
};
for (const auto& msg : msgs) {
camera3::notify(states, msg);
@@ -1455,6 +1462,8 @@
return res;
}
+ mSessionStatsBuilder.addStream(mNextStreamId);
+
*id = mNextStreamId++;
mNeedConfig = true;
@@ -1578,6 +1587,7 @@
CLOGE("Stream %d does not exist", id);
return BAD_VALUE;
}
+ mSessionStatsBuilder.removeStream(id);
}
// Delete output stream or the output part of a bi-directional stream.
@@ -2010,6 +2020,9 @@
}
mRequestThread->clear(/*out*/frameNumber);
+
+ // Stop session and stream counter
+ mSessionStatsBuilder.stopCounter();
}
return mRequestThread->flush();
@@ -2087,6 +2100,9 @@
void Camera3Device::notifyStatus(bool idle) {
ATRACE_CALL();
+ std::vector<int> streamIds;
+ std::vector<hardware::CameraStreamStats> streamStats;
+
{
// Need mLock to safely update state and synchronize to current
// state of methods in flight.
@@ -2104,6 +2120,24 @@
// Skip notifying listener if we're doing some user-transparent
// state changes
if (mPauseStateNotify) return;
+
+ // Populate stream statistics in case of Idle
+ if (idle) {
+ for (size_t i = 0; i < mOutputStreams.size(); i++) {
+ auto stream = mOutputStreams[i];
+ if (stream.get() == nullptr) continue;
+ streamIds.push_back(stream->getId());
+ Camera3Stream* camera3Stream = Camera3Stream::cast(stream->asHalStream());
+ int64_t usage = 0LL;
+ if (camera3Stream != nullptr) {
+ usage = camera3Stream->getUsage();
+ }
+ streamStats.emplace_back(stream->getWidth(), stream->getHeight(),
+ stream->getFormat(), stream->getDataSpace(), usage,
+ stream->getMaxHalBuffers(),
+ stream->getMaxTotalBuffers() - stream->getMaxHalBuffers());
+ }
+ }
}
sp<NotificationListener> listener;
@@ -2112,7 +2146,22 @@
listener = mListener.promote();
}
if (idle && listener != NULL) {
- listener->notifyIdle();
+ // Get session stats from the builder, and notify the listener.
+ int64_t requestCount, resultErrorCount;
+ bool deviceError;
+ std::map<int, StreamStats> streamStatsMap;
+ mSessionStatsBuilder.buildAndReset(&requestCount, &resultErrorCount,
+ &deviceError, &streamStatsMap);
+ for (size_t i = 0; i < streamIds.size(); i++) {
+ int streamId = streamIds[i];
+ auto stats = streamStatsMap.find(streamId);
+ if (stats != streamStatsMap.end()) {
+ streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
+ streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
+ streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
+ }
+ }
+ listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
}
}
@@ -2222,6 +2271,12 @@
ALOGE("%s: Stream %d is not found.", __FUNCTION__, streamId);
return BAD_VALUE;
}
+
+ if (dropping) {
+ mSessionStatsBuilder.stopCounter(streamId);
+ } else {
+ mSessionStatsBuilder.startCounter(streamId);
+ }
return stream->dropBuffers(dropping);
}
@@ -2376,6 +2431,8 @@
ATRACE_CALL();
bool ret = false;
+ nsecs_t startTime = systemTime();
+
Mutex::Autolock il(mInterfaceLock);
nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
@@ -2423,6 +2480,9 @@
ALOGE("%s: Failed to pause streaming: %d", __FUNCTION__, rc);
}
+ CameraServiceProxyWrapper::logStreamConfigured(mId, mOperatingMode, true /*internalReconfig*/,
+ ns2ms(systemTime() - startTime));
+
if (markClientActive) {
mStatusTracker->markComponentActive(clientStatusId);
}
@@ -2776,6 +2836,7 @@
if (listener != NULL) {
listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
CaptureResultExtras());
+ mSessionStatsBuilder.onDeviceError();
}
// Save stack trace. View by dumping it later.
@@ -2792,14 +2853,14 @@
bool hasAppCallback, nsecs_t maxExpectedDuration,
std::set<String8>& physicalCameraIds, bool isStillCapture,
bool isZslCapture, bool rotateAndCropAuto, const std::set<std::string>& cameraIdsWithZoom,
- const SurfaceMap& outputSurfaces) {
+ const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
ATRACE_CALL();
std::lock_guard<std::mutex> l(mInFlightLock);
ssize_t res;
res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture,
- rotateAndCropAuto, cameraIdsWithZoom, outputSurfaces));
+ rotateAndCropAuto, cameraIdsWithZoom, requestTimeNs, outputSurfaces));
if (res < 0) return res;
if (mInFlightMap.size() == 1) {
@@ -2869,7 +2930,7 @@
FlushInflightReqStates states {
mId, mInFlightLock, mInFlightMap, mUseHalBufManager,
- listener, *this, *mInterface, *this};
+ listener, *this, *mInterface, *this, mSessionStatsBuilder};
camera3::flushInflightRequests(states);
}
@@ -3778,6 +3839,7 @@
mInterface(interface),
mListener(nullptr),
mId(getId(parent)),
+ mFirstRepeating(false),
mReconfigured(false),
mDoPause(false),
mPaused(true),
@@ -3908,6 +3970,7 @@
*lastFrameNumber = mRepeatingLastFrameNumber;
}
mRepeatingRequests.clear();
+ mFirstRepeating = true;
mRepeatingRequests.insert(mRepeatingRequests.begin(),
requests.begin(), requests.end());
@@ -4697,7 +4760,7 @@
requestedPhysicalCameras, isStillCapture, isZslCapture,
captureRequest->mRotateAndCropAuto, mPrevCameraIdsWithZoom,
(mUseHalBufManager) ? uniqueSurfaceIdMap :
- SurfaceMap{});
+ SurfaceMap{}, captureRequest->mRequestTimeNs);
ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
", burstId = %" PRId32 ".",
__FUNCTION__,
@@ -5019,6 +5082,17 @@
// list. Guarantees a complete in-sequence set of captures to
// application.
const RequestList &requests = mRepeatingRequests;
+ if (mFirstRepeating) {
+ mFirstRepeating = false;
+ } else {
+ for (auto& request : requests) {
+ // For repeating requests, override timestamp request using
+ // the time a request is inserted into the request queue,
+ // because the original repeating request will have an old
+ // fixed timestamp.
+ request->mRequestTimeNs = systemTime();
+ }
+ }
RequestList::const_iterator firstRequest =
requests.begin();
nextRequest = *firstRequest;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index c579071..de7df81 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -471,6 +471,8 @@
camera3::StreamSet mOutputStreams;
sp<camera3::Camera3Stream> mInputStream;
+ SessionStatsBuilder mSessionStatsBuilder;
+
int mNextStreamId;
bool mNeedConfig;
@@ -520,6 +522,8 @@
// Whether this capture request has its zoom ratio set to 1.0x before
// the framework overrides it for camera HAL consumption.
bool mZoomRatioIs1x;
+ // The systemTime timestamp when the request is created.
+ nsecs_t mRequestTimeNs;
// Whether this capture request's distortion correction update has
@@ -538,7 +542,7 @@
status_t convertMetadataListToRequestListLocked(
const List<const PhysicalCameraSettingsList> &metadataList,
const std::list<const SurfaceMap> &surfaceMaps,
- bool repeating,
+ bool repeating, nsecs_t requestTimeNs,
/*out*/
RequestList *requestList);
@@ -961,6 +965,7 @@
Condition mRequestSubmittedSignal;
RequestList mRequestQueue;
RequestList mRepeatingRequests;
+ bool mFirstRepeating;
// The next batch of requests being prepped for submission to the HAL, no longer
// on the request queue. Read-only even with mRequestLock held, outside
// of threadLoop
@@ -1035,7 +1040,8 @@
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
bool callback, nsecs_t maxExpectedDuration, std::set<String8>& physicalCameraIds,
bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto,
- const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces);
+ const std::set<std::string>& cameraIdsWithZoom, const SurfaceMap& outputSurfaces,
+ nsecs_t requestTimeNs);
/**
* Tracking for idle detection
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 448379c..ca62239 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -48,6 +48,7 @@
virtual void dump(int fd, const Vector<String16> &args) const;
+ int getMaxTotalBuffers() const { return mTotalBufferCount; }
protected:
size_t mTotalBufferCount;
// sum of input and output buffers that are currently acquired by HAL
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
index 95f9633..a7e64ce 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.cpp
@@ -176,7 +176,7 @@
FlushInflightReqStates states {
mId, mOfflineReqsLock, mOfflineReqs, mUseHalBufManager,
- listener, *this, mBufferRecords, *this};
+ listener, *this, mBufferRecords, *this, mSessionStatsBuilder};
camera3::flushInflightRequests(states);
@@ -260,7 +260,8 @@
mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
- mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, mBufferRecords
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+ mBufferRecords
};
std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
@@ -299,7 +300,8 @@
mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
- mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, mBufferRecords
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+ mBufferRecords
};
std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
@@ -333,7 +335,8 @@
mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
- mTagMonitor, mInputStream, mOutputStreams, listener, *this, *this, mBufferRecords
+ mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
+ mBufferRecords
};
for (const auto& msg : msgs) {
camera3::notify(states, msg);
@@ -353,7 +356,7 @@
}
RequestBufferStates states {
- mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams,
+ mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
*this, mBufferRecords, *this};
camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
return hardware::Void();
@@ -370,7 +373,7 @@
}
ReturnBufferStates states {
- mId, mUseHalBufManager, mOutputStreams, mBufferRecords};
+ mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder, mBufferRecords};
camera3::returnStreamBuffers(states, buffers);
return hardware::Void();
}
diff --git a/services/camera/libcameraservice/device3/Camera3OfflineSession.h b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
index ee9ed25..5581964 100644
--- a/services/camera/libcameraservice/device3/Camera3OfflineSession.h
+++ b/services/camera/libcameraservice/device3/Camera3OfflineSession.h
@@ -208,6 +208,7 @@
sp<camera3::Camera3Stream> mInputStream;
camera3::StreamSet mOutputStreams;
camera3::BufferRecords mBufferRecords;
+ SessionStatsBuilder mSessionStatsBuilder;
std::mutex mOfflineReqsLock;
camera3::InFlightRequestMap mOfflineReqs;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index 90f6216..f88b062 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -423,6 +423,7 @@
InFlightRequestMap& inflightMap = states.inflightMap;
const InFlightRequest &request = inflightMap.valueAt(idx);
const uint32_t frameNumber = inflightMap.keyAt(idx);
+ SessionStatsBuilder& sessionStatsBuilder = states.sessionStatsBuilder;
nsecs_t sensorTimestamp = request.sensorTimestamp;
nsecs_t shutterTimestamp = request.shutterTimestamp;
@@ -459,7 +460,9 @@
returnOutputBuffers(
states.useHalBufManager, states.listener,
request.pendingOutputBuffers.array(),
- request.pendingOutputBuffers.size(), 0, /*timestampIncreasing*/true,
+ request.pendingOutputBuffers.size(), 0,
+ /*requested*/true, request.requestTimeNs, states.sessionStatsBuilder,
+ /*timestampIncreasing*/true,
request.outputSurfaces, request.resultExtras,
request.errorBufStrategy);
@@ -472,6 +475,8 @@
states.lastCompletedRegularFrameNumber = frameNumber;
}
+ sessionStatsBuilder.incResultCounter(request.skipResultMetadata);
+
removeInFlightMapEntryLocked(states, idx);
ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
}
@@ -628,7 +633,7 @@
if (shutterTimestamp != 0) {
returnAndRemovePendingOutputBuffers(
states.useHalBufManager, states.listener,
- request);
+ request, states.sessionStatsBuilder);
}
if (result->result != NULL && !isPartialResult) {
@@ -825,7 +830,8 @@
bool useHalBufManager,
sp<NotificationListener> listener,
const camera3_stream_buffer_t *outputBuffers, size_t numBuffers,
- nsecs_t timestamp, bool timestampIncreasing,
+ nsecs_t timestamp, bool requested, nsecs_t requestTimeNs,
+ SessionStatsBuilder& sessionStatsBuilder, bool timestampIncreasing,
const SurfaceMap& outputSurfaces,
const CaptureResultExtras &inResultExtras,
ERROR_BUF_STRATEGY errorBufStrategy) {
@@ -853,6 +859,10 @@
// has not got a output buffer handle filled yet. This is though illegal if HAL
// buffer management API is not being used.
ALOGE("%s: cannot return a null buffer!", __FUNCTION__);
+ } else {
+ if (requested) {
+ sessionStatsBuilder.incCounter(streamId, /*dropped*/true, 0);
+ }
}
continue;
}
@@ -876,10 +886,22 @@
}
// Note: stream may be deallocated at this point, if this buffer was
// the last reference to it.
+ bool dropped = false;
if (res == NO_INIT || res == DEAD_OBJECT) {
ALOGV("Can't return buffer to its stream: %s (%d)", strerror(-res), res);
+ sessionStatsBuilder.stopCounter(streamId);
} else if (res != OK) {
ALOGE("Can't return buffer to its stream: %s (%d)", strerror(-res), res);
+ dropped = true;
+ } else {
+ if (outputBuffers[i].status == CAMERA3_BUFFER_STATUS_ERROR || timestamp == 0) {
+ dropped = true;
+ }
+ }
+ if (requested) {
+ nsecs_t bufferTimeNs = systemTime();
+ int32_t captureLatencyMs = ns2ms(bufferTimeNs - requestTimeNs);
+ sessionStatsBuilder.incCounter(streamId, dropped, captureLatencyMs);
}
// Long processing consumers can cause returnBuffer timeout for shared stream
@@ -889,7 +911,8 @@
// cancel the buffer
camera3_stream_buffer_t sb = outputBuffers[i];
sb.status = CAMERA3_BUFFER_STATUS_ERROR;
- stream->returnBuffer(sb, /*timestamp*/0, timestampIncreasing, std::vector<size_t> (),
+ stream->returnBuffer(sb, /*timestamp*/0,
+ timestampIncreasing, std::vector<size_t> (),
inResultExtras.frameNumber);
if (listener != nullptr) {
@@ -904,12 +927,14 @@
}
void returnAndRemovePendingOutputBuffers(bool useHalBufManager,
- sp<NotificationListener> listener, InFlightRequest& request) {
+ sp<NotificationListener> listener, InFlightRequest& request,
+ SessionStatsBuilder& sessionStatsBuilder) {
bool timestampIncreasing = !(request.zslCapture || request.hasInputBuffer);
returnOutputBuffers(useHalBufManager, listener,
request.pendingOutputBuffers.array(),
request.pendingOutputBuffers.size(),
- request.shutterTimestamp, timestampIncreasing,
+ request.shutterTimestamp, /*requested*/true,
+ request.requestTimeNs, sessionStatsBuilder, timestampIncreasing,
request.outputSurfaces, request.resultExtras,
request.errorBufStrategy);
@@ -992,7 +1017,7 @@
r.rotateAndCropAuto, r.cameraIdsWithZoom, r.physicalMetadatas);
}
returnAndRemovePendingOutputBuffers(
- states.useHalBufManager, states.listener, r);
+ states.useHalBufManager, states.listener, r, states.sessionStatsBuilder);
removeInFlightRequestIfReadyLocked(states, idx);
}
@@ -1281,6 +1306,7 @@
ALOGV("%s: Can't get output buffer for stream %d: %s (%d)",
__FUNCTION__, streamId, strerror(-res), res);
bufRet.val.error(StreamBufferRequestError::STREAM_DISCONNECTED);
+ states.sessionStatsBuilder.stopCounter(streamId);
} else {
ALOGE("%s: Can't get output buffer for stream %d: %s (%d)",
__FUNCTION__, streamId, strerror(-res), res);
@@ -1346,7 +1372,8 @@
sb.status = CAMERA3_BUFFER_STATUS_ERROR;
}
returnOutputBuffers(states.useHalBufManager, /*listener*/nullptr,
- streamBuffers.data(), numAllocatedBuffers, 0);
+ streamBuffers.data(), numAllocatedBuffers, 0, /*requested*/false,
+ /*requestTimeNs*/0, states.sessionStatsBuilder);
}
}
@@ -1403,22 +1430,23 @@
}
streamBuffer.stream = stream->asHalStream();
returnOutputBuffers(states.useHalBufManager, /*listener*/nullptr,
- &streamBuffer, /*size*/1, /*timestamp*/ 0);
+ &streamBuffer, /*size*/1, /*timestamp*/ 0, /*requested*/false,
+ /*requestTimeNs*/0, states.sessionStatsBuilder);
}
}
void flushInflightRequests(FlushInflightReqStates& states) {
ATRACE_CALL();
- { // First return buffers cached in mInFlightMap
+ { // First return buffers cached in inFlightMap
std::lock_guard<std::mutex> l(states.inflightLock);
for (size_t idx = 0; idx < states.inflightMap.size(); idx++) {
const InFlightRequest &request = states.inflightMap.valueAt(idx);
returnOutputBuffers(
states.useHalBufManager, states.listener,
request.pendingOutputBuffers.array(),
- request.pendingOutputBuffers.size(), 0,
- /*timestampIncreasing*/true, request.outputSurfaces,
- request.resultExtras, request.errorBufStrategy);
+ request.pendingOutputBuffers.size(), 0, /*requested*/true,
+ request.requestTimeNs, states.sessionStatsBuilder, /*timestampIncreasing*/true,
+ request.outputSurfaces, request.resultExtras, request.errorBufStrategy);
ALOGW("%s: Frame %d | Timestamp: %" PRId64 ", metadata"
" arrived: %s, buffers left: %d.\n", __FUNCTION__,
states.inflightMap.keyAt(idx), request.shutterTimestamp,
@@ -1490,7 +1518,8 @@
switch (halStream->stream_type) {
case CAMERA3_STREAM_OUTPUT:
res = stream->returnBuffer(streamBuffer, /*timestamp*/ 0,
- /*timestampIncreasing*/true, std::vector<size_t> (), frameNumber);
+ /*timestampIncreasing*/true,
+ std::vector<size_t> (), frameNumber);
if (res != OK) {
ALOGE("%s: Can't return output buffer for frame %d to"
" stream %d: %s (%d)", __FUNCTION__,
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index 3ebbc17..45c8a43 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -33,6 +33,7 @@
#include "device3/InFlightRequest.h"
#include "device3/Camera3Stream.h"
#include "device3/Camera3OutputStreamInterface.h"
+#include "utils/SessionStatsBuilder.h"
#include "utils/TagMonitor.h"
namespace android {
@@ -51,7 +52,8 @@
bool useHalBufManager,
sp<NotificationListener> listener, // Only needed when outputSurfaces is not empty
const camera3_stream_buffer_t *outputBuffers,
- size_t numBuffers, nsecs_t timestamp, bool timestampIncreasing = true,
+ size_t numBuffers, nsecs_t timestamp, bool requested, nsecs_t requestTimeNs,
+ SessionStatsBuilder& sessionStatsBuilder, bool timestampIncreasing = true,
// 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
@@ -64,7 +66,7 @@
void returnAndRemovePendingOutputBuffers(
bool useHalBufManager,
sp<NotificationListener> listener, // Only needed when outputSurfaces is not empty
- InFlightRequest& request);
+ InFlightRequest& request, SessionStatsBuilder& sessionStatsBuilder);
// Camera3Device/Camera3OfflineSession internal states used in notify/processCaptureResult
// callbacks
@@ -98,6 +100,7 @@
TagMonitor& tagMonitor;
sp<Camera3Stream> inputStream;
StreamSet& outputStreams;
+ SessionStatsBuilder& sessionStatsBuilder;
sp<NotificationListener> listener;
SetErrorInterface& setErrIntf;
InflightRequestUpdateInterface& inflightIntf;
@@ -121,6 +124,7 @@
std::mutex& reqBufferLock; // lock to serialize request buffer calls
const bool useHalBufManager;
StreamSet& outputStreams;
+ SessionStatsBuilder& sessionStatsBuilder;
SetErrorInterface& setErrIntf;
BufferRecordsInterface& bufferRecordsIntf;
RequestBufferInterface& reqBufferIntf;
@@ -134,6 +138,7 @@
const String8& cameraId;
const bool useHalBufManager;
StreamSet& outputStreams;
+ SessionStatsBuilder& sessionStatsBuilder;
BufferRecordsInterface& bufferRecordsIntf;
};
@@ -149,6 +154,7 @@
InflightRequestUpdateInterface& inflightIntf;
BufferRecordsInterface& bufferRecordsIntf;
FlushBufferInterface& flushBufferIntf;
+ SessionStatsBuilder& sessionStatsBuilder;
};
void flushInflightRequests(FlushInflightReqStates& states);
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index f208561..9a8f6fe 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -152,6 +152,10 @@
return mPhysicalCameraId;
}
+int Camera3Stream::getMaxHalBuffers() const {
+ return camera3_stream::max_buffers;
+}
+
void Camera3Stream::setOfflineProcessingSupport(bool support) {
mSupportOfflineProcessing = support;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index d768d3d..3654f89 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -165,6 +165,7 @@
void setDataSpaceOverride(bool dataSpaceOverriden);
bool isDataSpaceOverridden() const;
android_dataspace getOriginalDataSpace() const;
+ int getMaxHalBuffers() const;
const String8& physicalCameraId() const;
void setOfflineProcessingSupport(bool) override;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 667e3bb..a053262 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -99,6 +99,8 @@
virtual void setDataSpaceOverride(bool dataSpaceOverriden) = 0;
virtual bool isDataSpaceOverridden() const = 0;
virtual android_dataspace getOriginalDataSpace() const = 0;
+ virtual int getMaxHalBuffers() const = 0;
+ virtual int getMaxTotalBuffers() const = 0;
/**
* Offline processing
diff --git a/services/camera/libcameraservice/device3/InFlightRequest.h b/services/camera/libcameraservice/device3/InFlightRequest.h
index da4f228..c7b7475 100644
--- a/services/camera/libcameraservice/device3/InFlightRequest.h
+++ b/services/camera/libcameraservice/device3/InFlightRequest.h
@@ -115,6 +115,9 @@
// Requested camera ids (both logical and physical) with zoomRatio != 1.0f
std::set<std::string> cameraIdsWithZoom;
+ // Time of capture request (from systemTime) in Ns
+ nsecs_t requestTimeNs;
+
// What shared surfaces an output should go to
SurfaceMap outputSurfaces;
@@ -135,14 +138,15 @@
errorBufStrategy(ERROR_BUF_CACHE),
stillCapture(false),
zslCapture(false),
- rotateAndCropAuto(false) {
+ rotateAndCropAuto(false),
+ requestTimeNs(0) {
}
InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
bool hasAppCallback, nsecs_t maxDuration,
const std::set<String8>& physicalCameraIdSet, bool isStillCapture,
bool isZslCapture, bool rotateAndCropAuto, const std::set<std::string>& idsWithZoom,
- const SurfaceMap& outSurfaces = SurfaceMap{}) :
+ nsecs_t requestNs, const SurfaceMap& outSurfaces = SurfaceMap{}) :
shutterTimestamp(0),
sensorTimestamp(0),
requestStatus(OK),
@@ -159,6 +163,7 @@
zslCapture(isZslCapture),
rotateAndCropAuto(rotateAndCropAuto),
cameraIdsWithZoom(idsWithZoom),
+ requestTimeNs(requestNs),
outputSurfaces(outSurfaces) {
}
};