diff options
Diffstat (limited to 'services')
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 dc97c47..3e58c4b 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -221,6 +221,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(); @@ -229,6 +235,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 1f53c56..933c5f7 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 da3e121..a700f30 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -388,6 +388,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; @@ -428,10 +467,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(); @@ -478,6 +566,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) { @@ -1913,6 +2006,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 468f641..bbdb65d 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); @@ -202,6 +204,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. * @@ -313,6 +323,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 */ |