Fix decoder drop frame issue

Use async call to do releaseOutputBuffer so that
the output frames can be released at time.

Bug: 299531074

Change-Id: Ib9468dd5384d626a3e6b313181a8ea945bf015e2
Signed-off-by: Ruofei Ma <ruofeim@google.com>
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/FrameReleaseQueue.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/FrameReleaseQueue.java
index 306aeee..d182f88 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/FrameReleaseQueue.java
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/FrameReleaseQueue.java
@@ -22,6 +22,7 @@
 import java.nio.ByteBuffer;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.CompletableFuture;
 
 public class FrameReleaseQueue {
     private static final String TAG = "FrameReleaseQueue";
@@ -61,31 +62,31 @@
                         // first frame of loop
                         firstReleaseTime = getCurSysTime();
                         nextReleaseTime = firstReleaseTime + mWaitTime;
-                        popAndRelease(curFrameInfo, true);
+                        popAndRelease(true);
                     } else if (!doFrameRelease.get() && mFrameInfoQueue.size() == 1) {
                         // EOS
                         Log.i(TAG, "EOS");
-                        popAndRelease(curFrameInfo, false);
+                        popAndRelease(false);
                     } else {
                         nextReleaseTime += mWaitTime;
                         int curSysTime = getCurSysTime();
                         int curMediaTime = curSysTime - firstReleaseTime;
                         while (curFrameInfo != null && curFrameInfo.displayTime > 0 &&
                                 curFrameInfo.displayTime <= curMediaTime) {
-                            if (!((curMediaTime - curFrameInfo.displayTime) < THRESHOLD_TIME)) {
+                            if (!((curMediaTime - curFrameInfo.displayTime) <= THRESHOLD_TIME)) {
                                 Log.d(TAG, "Dropping expired frame " + curFrameInfo.number +
                                     " display time " + curFrameInfo.displayTime +
                                     " current time " + curMediaTime);
-                                popAndRelease(curFrameInfo, false);
+                                popAndRelease(false);
                             } else {
-                                popAndRelease(curFrameInfo, true);
+                                popAndRelease(true);
                             }
                             curFrameInfo = mFrameInfoQueue.peek();
                         }
                         if (curFrameInfo != null && curFrameInfo.displayTime > curMediaTime) {
                             if ((curFrameInfo.displayTime - curMediaTime) < THRESHOLD_TIME) {
                                 // release the frame now as we are already there
-                                popAndRelease(curFrameInfo, true);
+                                popAndRelease(true);
                             }
                         }
                     }
@@ -148,20 +149,22 @@
         return (int)(System.nanoTime()/1000000);
     }
 
-    private void popAndRelease(FrameInfo curFrameInfo, boolean renderThisFrame) {
+    private void popAndRelease(boolean renderThisFrame) {
+        final boolean actualRender = (renderThisFrame && mRender);
         try {
-            curFrameInfo = mFrameInfoQueue.take();
+            final FrameInfo curFrameInfo = mFrameInfoQueue.take();
+
+            CompletableFuture future = CompletableFuture.runAsync(() -> {
+                try {
+                    mCodec.releaseOutputBuffer(curFrameInfo.bufferId, actualRender);
+                } catch (IllegalStateException e) {
+                    e.printStackTrace();
+                }
+            });
+
         } catch (InterruptedException e) {
             Log.e(TAG, "Threw InterruptedException on take");
         }
-        boolean actualRender = (renderThisFrame && mRender);
-        try {
-            mCodec.releaseOutputBuffer(curFrameInfo.bufferId, actualRender);
-        } catch (IllegalStateException e) {
-            Log.e(TAG,
-                    "Threw IllegalStateException on releaseOutputBuffer for frame "
-                            + curFrameInfo.number);
-        }
     }
 
     public void stopFrameRelease() {