summaryrefslogtreecommitdiffstats
path: root/services/camera
diff options
context:
space:
mode:
authorJianing Wei <jianingwei@google.com>2014-03-22 00:04:19 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-03-22 00:04:20 +0000
commitcfe09079608d78a0a358f01bb49f279859e38664 (patch)
tree9a1b044149726ec242d3a5e948029d71803aaf7e /services/camera
parent55d15957bc44d11052e1cb3eea3340ec00f70bae (diff)
parent90e59c98c343e941b1a75307ffa4b4b5f1eb50d6 (diff)
downloadframeworks_av-cfe09079608d78a0a358f01bb49f279859e38664.zip
frameworks_av-cfe09079608d78a0a358f01bb49f279859e38664.tar.gz
frameworks_av-cfe09079608d78a0a358f01bb49f279859e38664.tar.bz2
Merge "CameraService: Add support for burst capture and repeating burst."
Diffstat (limited to 'services/camera')
-rw-r--r--services/camera/libcameraservice/api2/CameraDeviceClient.cpp112
-rw-r--r--services/camera/libcameraservice/api2/CameraDeviceClient.h7
-rw-r--r--services/camera/libcameraservice/common/CameraDeviceBase.h11
-rw-r--r--services/camera/libcameraservice/device2/Camera2Device.cpp12
-rw-r--r--services/camera/libcameraservice/device2/Camera2Device.h2
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp106
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.h12
7 files changed, 259 insertions, 3 deletions
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 187220e..a02381d 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -159,7 +159,7 @@ status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
int32_t requestId = mRequestIdCounter++;
metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
- ALOGV("%s: Camera %d: Submitting request with ID %d",
+ ALOGV("%s: Camera %d: Creating request with ID %d",
__FUNCTION__, mCameraId, requestId);
if (streaming) {
@@ -186,6 +186,116 @@ status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
return res;
}
+status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
+ bool streaming) {
+ ATRACE_CALL();
+ ALOGV("%s-start of function", __FUNCTION__);
+
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
+ Mutex::Autolock icl(mBinderSerializationLock);
+
+ if (!mDevice.get()) return DEAD_OBJECT;
+
+ if (requests.empty()) {
+ ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
+ __FUNCTION__, mCameraId);
+ return BAD_VALUE;
+ }
+
+ List<const CameraMetadata> metadataRequestList;
+ int32_t requestId = mRequestIdCounter;
+ uint32_t loopCounter = 0;
+
+ for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
+ sp<CaptureRequest> request = *it;
+ if (request == 0) {
+ ALOGE("%s: Camera %d: Sent null request.",
+ __FUNCTION__, mCameraId);
+ return BAD_VALUE;
+ }
+
+ CameraMetadata metadata(request->mMetadata);
+ if (metadata.isEmpty()) {
+ ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
+ __FUNCTION__, mCameraId);
+ return BAD_VALUE;
+ } else if (request->mSurfaceList.isEmpty()) {
+ ALOGE("%s: Camera %d: Requests must have at least one surface target. "
+ "Rejecting request.", __FUNCTION__, mCameraId);
+ return BAD_VALUE;
+ }
+
+ if (!enforceRequestPermissions(metadata)) {
+ // Callee logs
+ return PERMISSION_DENIED;
+ }
+
+ /**
+ * Write in the output stream IDs which we calculate from
+ * the capture request's list of surface targets
+ */
+ Vector<int32_t> outputStreamIds;
+ outputStreamIds.setCapacity(request->mSurfaceList.size());
+ for (Vector<sp<Surface> >::iterator surfaceIt = 0;
+ surfaceIt != request->mSurfaceList.end(); ++surfaceIt) {
+ sp<Surface> surface = *surfaceIt;
+ if (surface == 0) continue;
+
+ sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
+ int idx = mStreamMap.indexOfKey(gbp->asBinder());
+
+ // Trying to submit request with surface that wasn't created
+ if (idx == NAME_NOT_FOUND) {
+ ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
+ " we have not called createStream on",
+ __FUNCTION__, mCameraId);
+ return BAD_VALUE;
+ }
+
+ int streamId = mStreamMap.valueAt(idx);
+ outputStreamIds.push_back(streamId);
+ ALOGV("%s: Camera %d: Appending output stream %d to request",
+ __FUNCTION__, mCameraId, streamId);
+ }
+
+ metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
+ outputStreamIds.size());
+
+ metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
+ loopCounter++; // loopCounter starts from 1
+ ALOGV("%s: Camera %d: Creating request with ID %d (%d of %d)",
+ __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());
+
+ metadataRequestList.push_back(metadata);
+ }
+ mRequestIdCounter++;
+
+ if (streaming) {
+ res = mDevice->setStreamingRequestList(metadataRequestList);
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
+ "request", __FUNCTION__, mCameraId, res);
+ } else {
+ mStreamingRequestList.push_back(requestId);
+ }
+ } else {
+ res = mDevice->captureList(metadataRequestList);
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Got error %d after trying to set capture",
+ __FUNCTION__, mCameraId, res);
+ }
+ }
+
+ ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
+ if (res == OK) {
+ return requestId;
+ }
+
+ return res;
+}
+
status_t CameraDeviceClient::cancelRequest(int requestId) {
ATRACE_CALL();
ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index b9c16aa..e96e1ae 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -63,8 +63,11 @@ public:
*/
// Note that the callee gets a copy of the metadata.
- virtual int submitRequest(sp<CaptureRequest> request,
- bool streaming = false);
+ virtual status_t submitRequest(sp<CaptureRequest> request,
+ bool streaming = false);
+ // List of requests are copied.
+ virtual status_t submitRequestList(List<sp<CaptureRequest> > requests,
+ bool streaming = false);
virtual status_t cancelRequest(int requestId);
// Returns -EBUSY if device is not idle
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index e80abf1..a4ae179 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -22,6 +22,7 @@
#include <utils/String16.h>
#include <utils/Vector.h>
#include <utils/Timers.h>
+#include <utils/List.h>
#include "hardware/camera2.h"
#include "camera/CameraMetadata.h"
@@ -58,12 +59,22 @@ class CameraDeviceBase : public virtual RefBase {
virtual status_t capture(CameraMetadata &request) = 0;
/**
+ * Submit a list of requests.
+ */
+ virtual status_t captureList(const List<const CameraMetadata> &requests) = 0;
+
+ /**
* Submit request for streaming. The CameraDevice makes a copy of the
* passed-in buffer and the caller retains ownership.
*/
virtual status_t setStreamingRequest(const CameraMetadata &request) = 0;
/**
+ * Submit a list of requests for streaming.
+ */
+ virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests) = 0;
+
+ /**
* Clear the streaming request slot.
*/
virtual status_t clearStreamingRequest() = 0;
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index f60ca98..9b0ad91 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -207,6 +207,12 @@ status_t Camera2Device::capture(CameraMetadata &request) {
return OK;
}
+status_t Camera2Device::captureList(const List<const CameraMetadata> &requests) {
+ ATRACE_CALL();
+ ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
+ return INVALID_OPERATION;
+}
+
status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
ATRACE_CALL();
@@ -215,6 +221,12 @@ status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
return mRequestQueue.setStreamSlot(streamRequest.release());
}
+status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests) {
+ ATRACE_CALL();
+ ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
+ return INVALID_OPERATION;
+}
+
status_t Camera2Device::clearStreamingRequest() {
ATRACE_CALL();
return mRequestQueue.setStreamSlot(NULL);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h
index 5b91f88..61bfd1a 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.h
+++ b/services/camera/libcameraservice/device2/Camera2Device.h
@@ -48,7 +48,9 @@ class Camera2Device: public CameraDeviceBase {
virtual status_t dump(int fd, const Vector<String16>& args);
virtual const CameraMetadata& info() const;
virtual status_t capture(CameraMetadata &request);
+ virtual status_t captureList(const List<const CameraMetadata> &requests);
virtual status_t setStreamingRequest(const CameraMetadata &request);
+ virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests);
virtual status_t clearStreamingRequest();
virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout);
virtual status_t createStream(sp<ANativeWindow> consumer,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 08e03ce..e5ac037 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -370,6 +370,45 @@ const CameraMetadata& Camera3Device::info() const {
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;
@@ -410,10 +449,59 @@ status_t Camera3Device::capture(CameraMetadata &request) {
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();
@@ -460,6 +548,11 @@ status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
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) {
@@ -1895,6 +1988,19 @@ status_t Camera3Device::RequestThread::queueRequest(
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[],
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 9007a9b..44c6260 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -79,7 +79,9 @@ class Camera3Device :
// Capture and setStreamingRequest will configure streams if currently in
// idle state
virtual status_t capture(CameraMetadata &request);
+ virtual status_t captureList(const List<const CameraMetadata> &requests);
virtual status_t setStreamingRequest(const CameraMetadata &request);
+ virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests);
virtual status_t clearStreamingRequest();
virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout);
@@ -201,6 +203,14 @@ class Camera3Device :
};
typedef List<sp<CaptureRequest> > RequestList;
+ status_t checkStatusOkToCaptureLocked();
+
+ status_t convertMetadataListToRequestListLocked(
+ const List<const CameraMetadata> &metadataList,
+ /*out*/RequestList *requestList);
+
+ status_t submitRequestsHelper(const List<const CameraMetadata> &requests, bool repeating);
+
/**
* Get the last request submitted to the hal by the request thread.
*
@@ -312,6 +322,8 @@ class Camera3Device :
status_t queueRequest(sp<CaptureRequest> request);
+ status_t queueRequestList(List<sp<CaptureRequest> > &requests);
+
/**
* Remove all queued and repeating requests, and pending triggers
*/