From abaa51d3ca31f0eda99e1d271e6dc64c877dbf58 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 14 Aug 2013 11:37:00 -0700 Subject: Camera2: Add flush support - On HAL2 devices, fall back to wait until idle - On HAL3 devices, call HAL flush method Bug: 9758581 Change-Id: Ie1c570a15f6590a1ee6c271e3b989c48079b468a --- camera/camera2/ICameraDeviceUser.cpp | 17 +++++++++++++ include/camera/camera2/ICameraDeviceUser.h | 3 +++ .../libcameraservice/api2/CameraDeviceClient.cpp | 14 +++++++++++ .../libcameraservice/api2/CameraDeviceClient.h | 4 ++++ .../libcameraservice/common/CameraDeviceBase.h | 7 ++++++ .../libcameraservice/device2/Camera2Device.cpp | 28 +++++++++++++++++++--- .../libcameraservice/device2/Camera2Device.h | 5 ++++ .../libcameraservice/device3/Camera3Device.cpp | 18 ++++++++++++++ .../libcameraservice/device3/Camera3Device.h | 7 ++++++ 9 files changed, 100 insertions(+), 3 deletions(-) diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp index 923f487..ae4cf69 100644 --- a/camera/camera2/ICameraDeviceUser.cpp +++ b/camera/camera2/ICameraDeviceUser.cpp @@ -41,6 +41,7 @@ enum { CREATE_DEFAULT_REQUEST, GET_CAMERA_INFO, WAIT_UNTIL_IDLE, + FLUSH }; class BpCameraDeviceUser : public BpInterface @@ -183,6 +184,16 @@ public: return reply.readInt32(); } + virtual status_t flush() + { + ALOGV("flush"); + Parcel data, reply; + data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor()); + remote()->transact(FLUSH, data, &reply); + reply.readExceptionCode(); + return reply.readInt32(); + } + private: @@ -312,6 +323,12 @@ status_t BnCameraDeviceUser::onTransact( reply->writeInt32(waitUntilIdle()); return NO_ERROR; } break; + case FLUSH: { + CHECK_INTERFACE(ICameraDeviceUser, data, reply); + reply->writeNoException(); + reply->writeInt32(flush()); + return NO_ERROR; + } default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h index 45988d0..f71f302 100644 --- a/include/camera/camera2/ICameraDeviceUser.h +++ b/include/camera/camera2/ICameraDeviceUser.h @@ -63,6 +63,9 @@ public: // Wait until all the submitted requests have finished processing virtual status_t waitUntilIdle() = 0; + + // Flush all pending and in-progress work as quickly as possible. + virtual status_t flush() = 0; }; // ---------------------------------------------------------------------------- diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 414316d..289ba06 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -436,6 +436,20 @@ status_t CameraDeviceClient::waitUntilIdle() return res; } +status_t CameraDeviceClient::flush() { + ATRACE_CALL(); + ALOGV("%s", __FUNCTION__); + + status_t res = OK; + if ( (res = checkPid(__FUNCTION__) ) != OK) return res; + + Mutex::Autolock icl(mBinderSerializationLock); + + if (!mDevice.get()) return DEAD_OBJECT; + + return mDevice->flush(); +} + status_t CameraDeviceClient::dump(int fd, const Vector& args) { String8 result; result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n", diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index 21d633c..c6b6336 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -89,6 +89,10 @@ public: // Wait until all the submitted requests have finished processing virtual status_t waitUntilIdle(); + + // Flush all active and pending requests as fast as possible + virtual status_t flush(); + /** * Interface used by CameraService */ diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h index aa92bec..ebbd4ea 100644 --- a/services/camera/libcameraservice/common/CameraDeviceBase.h +++ b/services/camera/libcameraservice/common/CameraDeviceBase.h @@ -209,6 +209,13 @@ class CameraDeviceBase : public virtual RefBase { */ virtual status_t pushReprocessBuffer(int reprocessStreamId, buffer_handle_t *buffer, wp listener) = 0; + + /** + * Flush all pending and in-flight requests. Blocks until flush is + * complete. + */ + virtual status_t flush() = 0; + }; }; // namespace android diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp index 710d0e9..fe2cd77 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -567,6 +567,13 @@ status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId, return res; } +status_t Camera2Device::flush() { + ATRACE_CALL(); + + mRequestQueue.clear(); + return waitUntilDrained(); +} + /** * Camera2Device::MetadataQueue */ @@ -591,9 +598,7 @@ Camera2Device::MetadataQueue::MetadataQueue(): Camera2Device::MetadataQueue::~MetadataQueue() { ATRACE_CALL(); - Mutex::Autolock l(mMutex); - freeBuffers(mEntries.begin(), mEntries.end()); - freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); + clear(); } // Connect to camera2 HAL as consumer (input requests/reprocessing) @@ -784,6 +789,23 @@ status_t Camera2Device::MetadataQueue::setStreamSlot( return signalConsumerLocked(); } +status_t Camera2Device::MetadataQueue::clear() +{ + ATRACE_CALL(); + ALOGV("%s: E", __FUNCTION__); + + Mutex::Autolock l(mMutex); + + // Clear streaming slot + freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); + mStreamSlotCount = 0; + + // Clear request queue + freeBuffers(mEntries.begin(), mEntries.end()); + mCount = 0; + return OK; +} + status_t Camera2Device::MetadataQueue::dump(int fd, const Vector& /*args*/) { ATRACE_CALL(); diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h index 8945ec2..2aa22a2 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.h +++ b/services/camera/libcameraservice/device2/Camera2Device.h @@ -67,6 +67,8 @@ class Camera2Device: public CameraDeviceBase { virtual status_t triggerPrecaptureMetering(uint32_t id); virtual status_t pushReprocessBuffer(int reprocessStreamId, buffer_handle_t *buffer, wp listener); + // Flush implemented as just a wait + virtual status_t flush(); private: const int mId; camera2_device_t *mHal2Device; @@ -113,6 +115,9 @@ class Camera2Device: public CameraDeviceBase { status_t setStreamSlot(camera_metadata_t *buf); status_t setStreamSlot(const List &bufs); + // Clear the request queue and the streaming slot + status_t clear(); + status_t dump(int fd, const Vector& args); private: diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 0a4a24c..7f2ec7a 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -952,6 +952,16 @@ status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId, return INVALID_OPERATION; } +status_t Camera3Device::flush() { + ATRACE_CALL(); + ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId); + + Mutex::Autolock l(mLock); + + mRequestThread->clear(); + return mHal3Device->ops->flush(mHal3Device); +} + /** * Camera3Device private methods */ @@ -1488,6 +1498,14 @@ status_t Camera3Device::RequestThread::clearRepeatingRequests() { return OK; } +status_t Camera3Device::RequestThread::clear() { + Mutex::Autolock l(mRequestLock); + mRepeatingRequests.clear(); + mRequestQueue.clear(); + mTriggerMap.clear(); + return OK; +} + void Camera3Device::RequestThread::setPaused(bool paused) { Mutex::Autolock l(mPauseLock); mDoPause = paused; diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index 76c08ae..99e1cc8 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -124,6 +124,8 @@ class Camera3Device : virtual status_t pushReprocessBuffer(int reprocessStreamId, buffer_handle_t *buffer, wp listener); + virtual status_t flush(); + private: static const size_t kInFlightWarnLimit = 20; static const nsecs_t kShutdownTimeout = 5000000000; // 5 sec @@ -249,6 +251,11 @@ class Camera3Device : status_t queueRequest(sp request); /** + * Remove all queued and repeating requests, and pending triggers + */ + status_t clear(); + + /** * Queue a trigger to be dispatched with the next outgoing * process_capture_request. The settings for that request only * will be temporarily rewritten to add the trigger tag/value. -- cgit v1.1