OSDN Git Service

Camera: add interface to evict obsolete buffer caches
authorYin-Chia Yeh <yinchiayeh@google.com>
Thu, 30 Mar 2017 22:06:20 +0000 (15:06 -0700)
committerYin-Chia Yeh <yinchiayeh@google.com>
Mon, 3 Apr 2017 21:41:23 +0000 (14:41 -0700)
Test: fix CTS ReprocessCaptureTest
Bug: 34461678
Change-Id: Icde654b0c8423c31d7d39d180913ffa374e7de3c

camera/device/3.2/ICameraDeviceSession.hal
camera/device/3.2/default/CameraDeviceSession.cpp
camera/device/3.2/default/CameraDeviceSession.h
camera/device/3.2/types.hal
camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp

index e186c8d..731fc76 100644 (file)
@@ -183,6 +183,11 @@ interface ICameraDeviceSession {
      * client, the HAL must process the requests in order of lowest index to
      * highest index.
      *
+     * The cachesToRemove argument contains a list of buffer caches (see
+     * StreamBuffer document for more information on buffer cache) to be removed
+     * by camera HAL. Camera HAL must remove these cache entries whether or not
+     * this method returns OK.
+     *
      * The actual request processing is asynchronous, with the results of
      * capture being returned by the HAL through the processCaptureResult()
      * call. This call requires the result metadata to be available, but output
@@ -238,7 +243,8 @@ interface ICameraDeviceSession {
      *     that HAL processed successfully before HAL runs into an error.
      *
      */
-    processCaptureRequest(vec<CaptureRequest> requests)
+    processCaptureRequest(vec<CaptureRequest> requests,
+            vec<BufferCache> cachesToRemove)
             generates (Status status, uint32_t numRequestProcessed);
 
     /**
index fb1d1ff..5b3024b 100644 (file)
@@ -678,8 +678,32 @@ void CameraDeviceSession::cleanupBuffersLocked(int id) {
     mCirculatingBuffers.erase(id);
 }
 
+void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove) {
+    Mutex::Autolock _l(mInflightLock);
+    for (auto& cache : cachesToRemove) {
+        auto cbsIt = mCirculatingBuffers.find(cache.streamId);
+        if (cbsIt == mCirculatingBuffers.end()) {
+            // The stream could have been removed
+            continue;
+        }
+        CirculatingBuffers& cbs = cbsIt->second;
+        auto it = cbs.find(cache.bufferId);
+        if (it != cbs.end()) {
+            sHandleImporter.freeBuffer(it->second);
+            cbs.erase(it);
+        } else {
+            ALOGE("%s: stream %d buffer %" PRIu64 " is not cached",
+                    __FUNCTION__, cache.streamId, cache.bufferId);
+        }
+    }
+}
+
 Return<void> CameraDeviceSession::processCaptureRequest(
-        const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb)  {
+        const hidl_vec<CaptureRequest>& requests,
+        const hidl_vec<BufferCache>& cachesToRemove,
+        processCaptureRequest_cb _hidl_cb)  {
+    updateBufferCaches(cachesToRemove);
+
     uint32_t numRequestProcessed = 0;
     Status s = Status::OK;
     for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
index 8923c05..781056e 100644 (file)
@@ -85,7 +85,9 @@ struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callba
     Return<void> configureStreams(
             const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
     Return<void> processCaptureRequest(
-            const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb) override;
+            const hidl_vec<CaptureRequest>& requests,
+            const hidl_vec<BufferCache>& cachesToRemove,
+            processCaptureRequest_cb _hidl_cb) override;
     Return<Status> flush() override;
     Return<void> close() override;
 
@@ -234,6 +236,8 @@ private:
 
     void cleanupBuffersLocked(int id);
 
+    void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
+
     Status processOneCaptureRequest(const CaptureRequest& request);
     /**
      * Static callback forwarding methods from HAL to instance
index fd75528..5ae7a18 100644 (file)
@@ -958,3 +958,25 @@ struct CaptureResult {
     uint32_t partialResult;
 
 };
+
+/**
+ * BufferCache:
+ *
+ * A list of cached bufferIds associated with a certain stream.
+ * Buffers are passed between camera service and camera HAL via bufferId except
+ * the first time a new buffer is being passed to HAL in CaptureRequest. Camera
+ * service and camera HAL therefore need to maintain a cached map of bufferId
+ * and corresponing native handle.
+ *
+ */
+struct BufferCache {
+    /**
+     * The ID of the stream this list is associated with.
+     */
+    int32_t streamId;
+
+    /**
+     * A cached buffer ID associated with streamId.
+     */
+    uint64_t bufferId;
+};
index a79c9fa..47cc9f1 100644 (file)
@@ -61,6 +61,7 @@ using ::android::hardware::camera::common::V1_0::TorchModeStatus;
 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
 using ::android::hardware::camera::device::V3_2::ICameraDevice;
+using ::android::hardware::camera::device::V3_2::BufferCache;
 using ::android::hardware::camera::device::V3_2::CaptureRequest;
 using ::android::hardware::camera::device::V3_2::CaptureResult;
 using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
@@ -2481,8 +2482,10 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) {
 
             Status status = Status::INTERNAL_ERROR;
             uint32_t numRequestProcessed = 0;
+            hidl_vec<BufferCache> cachesToRemove;
             Return<void> returnStatus = session->processCaptureRequest(
                     {request},
+                    cachesToRemove,
                     [&status, &numRequestProcessed] (auto s, uint32_t n) {
                         status = s;
                         numRequestProcessed = n;
@@ -2513,6 +2516,7 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) {
 
             returnStatus = session->processCaptureRequest(
                     {request},
+                    cachesToRemove,
                     [&status, &numRequestProcessed] (auto s, uint32_t n) {
                         status = s;
                         numRequestProcessed = n;
@@ -2579,8 +2583,10 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
             //Settings were not correctly initialized, we should fail here
             Status status = Status::OK;
             uint32_t numRequestProcessed = 0;
+            hidl_vec<BufferCache> cachesToRemove;
             Return<void> ret = session->processCaptureRequest(
                     {request},
+                    cachesToRemove,
                     [&status, &numRequestProcessed] (auto s, uint32_t n) {
                         status = s;
                         numRequestProcessed = n;
@@ -2632,8 +2638,10 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
             //Output buffers are missing, we should fail here
             Status status = Status::OK;
             uint32_t numRequestProcessed = 0;
+            hidl_vec<BufferCache> cachesToRemove;
             ret = session->processCaptureRequest(
                     {request},
+                    cachesToRemove,
                     [&status, &numRequestProcessed] (auto s, uint32_t n) {
                         status = s;
                         numRequestProcessed = n;
@@ -2701,8 +2709,10 @@ TEST_F(CameraHidlTest, flushPreviewRequest) {
 
             Status status = Status::INTERNAL_ERROR;
             uint32_t numRequestProcessed = 0;
+            hidl_vec<BufferCache> cachesToRemove;
             ret = session->processCaptureRequest(
                     {request},
+                    cachesToRemove,
                     [&status, &numRequestProcessed] (auto s, uint32_t n) {
                         status = s;
                         numRequestProcessed = n;