CameraService: Add support for burst capture and repeating burst.
Bug: 10749500
Change-Id: I292a485b222e5cf97388d76bf0d956a6ac54bb2f
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index da3e121..a700f30 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -388,6 +388,45 @@
return mDeviceInfo;
}
+status_t Camera3Device::checkStatusOkToCaptureLocked() {
+ switch (mStatus) {
+ case STATUS_ERROR:
+ CLOGE("Device has encountered a serious error");
+ return INVALID_OPERATION;
+ case STATUS_UNINITIALIZED:
+ CLOGE("Device not initialized");
+ return INVALID_OPERATION;
+ case STATUS_UNCONFIGURED:
+ case STATUS_CONFIGURED:
+ case STATUS_ACTIVE:
+ // OK
+ break;
+ default:
+ SET_ERR_L("Unexpected status: %d", mStatus);
+ return INVALID_OPERATION;
+ }
+ return OK;
+}
+
+status_t Camera3Device::convertMetadataListToRequestListLocked(
+ const List<const CameraMetadata> &metadataList, RequestList *requestList) {
+ if (requestList == NULL) {
+ CLOGE("requestList cannot be NULL.");
+ return BAD_VALUE;
+ }
+
+ for (List<const CameraMetadata>::const_iterator it = metadataList.begin();
+ it != metadataList.end(); ++it) {
+ sp<CaptureRequest> newRequest = setUpRequestLocked(*it);
+ if (newRequest == 0) {
+ CLOGE("Can't create capture request");
+ return BAD_VALUE;
+ }
+ requestList->push_back(newRequest);
+ }
+ return OK;
+}
+
status_t Camera3Device::capture(CameraMetadata &request) {
ATRACE_CALL();
status_t res;
@@ -428,10 +467,59 @@
kActiveTimeout/1e9);
}
ALOGV("Camera %d: Capture request enqueued", mId);
+ } else {
+ CLOGE("Cannot queue request. Impossible."); // queueRequest always returns OK.
+ return BAD_VALUE;
}
return res;
}
+status_t Camera3Device::submitRequestsHelper(
+ const List<const CameraMetadata> &requests, bool repeating) {
+ ATRACE_CALL();
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+
+ status_t res = checkStatusOkToCaptureLocked();
+ if (res != OK) {
+ // error logged by previous call
+ return res;
+ }
+
+ RequestList requestList;
+
+ res = convertMetadataListToRequestListLocked(requests, /*out*/&requestList);
+ if (res != OK) {
+ // error logged by previous call
+ return res;
+ }
+
+ if (repeating) {
+ res = mRequestThread->setRepeatingRequests(requestList);
+ } else {
+ res = mRequestThread->queueRequestList(requestList);
+ }
+
+ if (res == OK) {
+ waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
+ if (res != OK) {
+ SET_ERR_L("Can't transition to active in %f seconds!",
+ kActiveTimeout/1e9);
+ }
+ ALOGV("Camera %d: Capture request enqueued", mId);
+ } else {
+ CLOGE("Cannot queue request. Impossible.");
+ return BAD_VALUE;
+ }
+
+ return res;
+}
+
+status_t Camera3Device::captureList(const List<const CameraMetadata> &requests) {
+ ATRACE_CALL();
+
+ return submitRequestsHelper(requests, /*repeating*/false);
+}
status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
ATRACE_CALL();
@@ -478,6 +566,11 @@
return res;
}
+status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests) {
+ ATRACE_CALL();
+
+ return submitRequestsHelper(requests, /*repeating*/true);
+}
sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
const CameraMetadata &request) {
@@ -1913,6 +2006,19 @@
return OK;
}
+status_t Camera3Device::RequestThread::queueRequestList(
+ List<sp<CaptureRequest> > &requests) {
+ Mutex::Autolock l(mRequestLock);
+ for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
+ ++it) {
+ mRequestQueue.push_back(*it);
+ }
+
+ unpauseForNewRequests();
+
+ return OK;
+}
+
status_t Camera3Device::RequestThread::queueTrigger(
RequestTrigger trigger[],