Merge "Make BufferQueue based block pool non-blocking" into qt-dev
am: d3757001b9

Change-Id: Icacc0bb128998baa0213f0c338a3e41048ffb8bb
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 00e0c16..90265de 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -61,6 +61,10 @@
 constexpr size_t kSmoothnessFactor = 4;
 constexpr size_t kRenderingDepth = 3;
 
+// This is for keeping IGBP's buffer dropping logic in legacy mode other
+// than making it non-blocking. Do not change this value.
+const static size_t kDequeueTimeoutNs = 0;
+
 }  // namespace
 
 CCodecBufferChannel::QueueGuard::QueueGuard(
@@ -1456,6 +1460,7 @@
     sp<IGraphicBufferProducer> producer;
     if (newSurface) {
         newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
+        newSurface->setDequeueTimeout(kDequeueTimeoutNs);
         producer = newSurface->getIGraphicBufferProducer();
         producer->setGenerationNumber(generation);
     } else {
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index 9cc5677..ae39220 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -223,7 +223,6 @@
                         }
                     });
             if (!transResult.isOk() || status != android::OK) {
-                ALOGD("cannot dequeue buffer %d", status);
                 if (transResult.isOk()) {
                     if (status == android::INVALID_OPERATION ||
                         status == android::TIMED_OUT ||
@@ -233,6 +232,7 @@
                         return C2_BLOCKING;
                     }
                 }
+                ALOGD("cannot dequeue buffer %d", status);
                 return C2_BAD_VALUE;
             }
         }
@@ -355,39 +355,31 @@
             return mInit;
         }
 
-        static int kMaxIgbpRetry = 20; // TODO: small number can cause crash in releasing.
         static int kMaxIgbpRetryDelayUs = 10000;
 
-        int curTry = 0;
-
-        while (curTry++ < kMaxIgbpRetry) {
-            std::unique_lock<std::mutex> lock(mMutex);
-            // TODO: return C2_NO_INIT
-            if (mProducerId == 0) {
-                std::shared_ptr<C2GraphicAllocation> alloc;
-                c2_status_t err = mAllocator->newGraphicAllocation(
-                        width, height, format, usage, &alloc);
-                if (err != C2_OK) {
-                    return err;
-                }
-                std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
-                        std::make_shared<C2BufferQueueBlockPoolData>(
-                                0, (uint64_t)0, ~0, shared_from_this());
-                // TODO: config?
-                *block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
-                ALOGV("allocated a buffer successfully");
-
-                return C2_OK;
+        std::unique_lock<std::mutex> lock(mMutex);
+        if (mProducerId == 0) {
+            std::shared_ptr<C2GraphicAllocation> alloc;
+            c2_status_t err = mAllocator->newGraphicAllocation(
+                    width, height, format, usage, &alloc);
+            if (err != C2_OK) {
+                return err;
             }
-            c2_status_t status = fetchFromIgbp_l(width, height, format, usage, block);
-            if (status == C2_BLOCKING) {
-                lock.unlock();
-                ::usleep(kMaxIgbpRetryDelayUs);
-                continue;
-            }
-            return status;
+            std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
+                    std::make_shared<C2BufferQueueBlockPoolData>(
+                            0, (uint64_t)0, ~0, shared_from_this());
+            *block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
+            ALOGV("allocated a buffer successfully");
+
+            return C2_OK;
         }
-        return C2_BLOCKING;
+        c2_status_t status = fetchFromIgbp_l(width, height, format, usage, block);
+        if (status == C2_BLOCKING) {
+            lock.unlock();
+            // in order not to drain cpu from component's spinning
+            ::usleep(kMaxIgbpRetryDelayUs);
+        }
+        return status;
     }
 
     void setRenderCallback(const OnRenderCallback &renderCallback) {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index d8de103..3b87462 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -780,6 +780,9 @@
     // need to enable allocation when attaching
     surface->getIGraphicBufferProducer()->allowAllocation(true);
 
+    // dequeueBuffer cannot time out
+    surface->setDequeueTimeout(-1);
+
     // for meta data mode, we move dequeud buffers to the new surface.
     // for non-meta mode, we must move all registered buffers
     for (size_t i = 0; i < buffers.size(); ++i) {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index a7d37e5..b1fdb2c 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2221,6 +2221,7 @@
                             }
 
                             if (mime.startsWithIgnoreCase("video/")) {
+                                mSurface->setDequeueTimeout(-1);
                                 mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
                             }
                         }
@@ -2508,6 +2509,7 @@
                                             && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
                                         pushBlankBuffersToNativeWindow(mSurface.get());
                                     }
+                                    surface->setDequeueTimeout(-1);
                                     mSoftRenderer = new SoftwareRenderer(surface);
                                     // TODO: check if this was successful
                                 } else {