OSDN Git Service

Camera2: Add flush support
authorEino-Ville Talvala <etalvala@google.com>
Wed, 14 Aug 2013 18:37:00 +0000 (11:37 -0700)
committerEino-Ville Talvala <etalvala@google.com>
Fri, 23 Aug 2013 21:08:27 +0000 (14:08 -0700)
- 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
include/camera/camera2/ICameraDeviceUser.h
services/camera/libcameraservice/api2/CameraDeviceClient.cpp
services/camera/libcameraservice/api2/CameraDeviceClient.h
services/camera/libcameraservice/common/CameraDeviceBase.h
services/camera/libcameraservice/device2/Camera2Device.cpp
services/camera/libcameraservice/device2/Camera2Device.h
services/camera/libcameraservice/device3/Camera3Device.cpp
services/camera/libcameraservice/device3/Camera3Device.h

index 923f487..ae4cf69 100644 (file)
@@ -41,6 +41,7 @@ enum {
     CREATE_DEFAULT_REQUEST,
     GET_CAMERA_INFO,
     WAIT_UNTIL_IDLE,
+    FLUSH
 };
 
 class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
@@ -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);
     }
index 45988d0..f71f302 100644 (file)
@@ -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;
 };
 
 // ----------------------------------------------------------------------------
index 414316d..289ba06 100644 (file)
@@ -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<String16>& args) {
     String8 result;
     result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
index 21d633c..c6b6336 100644 (file)
@@ -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
      */
index aa92bec..ebbd4ea 100644 (file)
@@ -209,6 +209,13 @@ class CameraDeviceBase : public virtual RefBase {
      */
     virtual status_t pushReprocessBuffer(int reprocessStreamId,
             buffer_handle_t *buffer, wp<BufferReleasedListener> listener) = 0;
+
+    /**
+     * Flush all pending and in-flight requests. Blocks until flush is
+     * complete.
+     */
+    virtual status_t flush() = 0;
+
 };
 
 }; // namespace android
index 710d0e9..fe2cd77 100644 (file)
@@ -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<String16>& /*args*/) {
     ATRACE_CALL();
index 8945ec2..2aa22a2 100644 (file)
@@ -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<BufferReleasedListener> 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<camera_metadata_t*> &bufs);
 
+        // Clear the request queue and the streaming slot
+        status_t clear();
+
         status_t dump(int fd, const Vector<String16>& args);
 
       private:
index 0a4a24c..7f2ec7a 100644 (file)
@@ -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;
index 76c08ae..99e1cc8 100644 (file)
@@ -124,6 +124,8 @@ class Camera3Device :
     virtual status_t pushReprocessBuffer(int reprocessStreamId,
             buffer_handle_t *buffer, wp<BufferReleasedListener> 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<CaptureRequest> 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.