am 844092c8: am 47aa9c47: Merge "Enable silence detection and don\'t driver the audio encoder" into jb-mr1-dev

* commit '844092c8931e229314e20bc2366551ed3f9181ba':
  Enable silence detection and don't driver the audio encoder
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
index b9539e9..6f336c7 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -44,7 +44,12 @@
       mCodecLooper(codecLooper),
       mInputFormat(format),
       mIsVideo(false),
-      mDoMoreWorkPending(false) {
+      mDoMoreWorkPending(false)
+#if ENABLE_SILENCE_DETECTION
+      ,mFirstSilentFrameUs(-1ll)
+      ,mInSilentMode(false)
+#endif
+    {
     AString mime;
     CHECK(mInputFormat->findString("mime", &mime));
 
@@ -171,6 +176,20 @@
     notify->post();
 }
 
+// static
+bool Converter::IsSilence(const sp<ABuffer> &accessUnit) {
+    const uint8_t *ptr = accessUnit->data();
+    const uint8_t *end = ptr + accessUnit->size();
+    while (ptr < end) {
+        if (*ptr != 0) {
+            return false;
+        }
+        ++ptr;
+    }
+
+    return true;
+}
+
 void Converter::onMessageReceived(const sp<AMessage> &msg) {
     switch (msg->what()) {
         case kWhatMediaPullerNotify:
@@ -220,6 +239,30 @@
                 }
 #endif
 
+#if ENABLE_SILENCE_DETECTION
+                if (!mIsVideo) {
+                    if (IsSilence(accessUnit)) {
+                        if (!mInSilentMode) {
+                            int64_t nowUs = ALooper::GetNowUs();
+
+                            if (mFirstSilentFrameUs < 0ll) {
+                                mFirstSilentFrameUs = nowUs;
+                            } else if (nowUs >= mFirstSilentFrameUs + 1000000ll) {
+                                mInSilentMode = true;
+                                ALOGI("audio in silent mode now.");
+                                break;
+                            }
+                        }
+                    } else {
+                        if (mInSilentMode) {
+                            ALOGI("audio no longer in silent mode.");
+                        }
+                        mInSilentMode = false;
+                        mFirstSilentFrameUs = -1ll;
+                    }
+                }
+#endif
+
                 mInputBufferQueue.push_back(accessUnit);
 
                 feedEncoderInputBuffers();
@@ -283,7 +326,7 @@
     }
 
     mDoMoreWorkPending = true;
-    (new AMessage(kWhatDoMoreWork, id()))->post(10000ll);
+    (new AMessage(kWhatDoMoreWork, id()))->post(mIsVideo ? 10000ll : 5000ll);
 }
 
 status_t Converter::feedEncoderInputBuffers() {
@@ -338,14 +381,21 @@
         feedEncoderInputBuffers();
     }
 
-    size_t offset;
-    size_t size;
-    int64_t timeUs;
-    uint32_t flags;
-    err = mEncoder->dequeueOutputBuffer(
-            &bufferIndex, &offset, &size, &timeUs, &flags);
+    for (;;) {
+        size_t offset;
+        size_t size;
+        int64_t timeUs;
+        uint32_t flags;
+        err = mEncoder->dequeueOutputBuffer(
+                &bufferIndex, &offset, &size, &timeUs, &flags);
 
-    if (err == OK) {
+        if (err != OK) {
+            if (err == -EAGAIN) {
+                err = OK;
+            }
+            break;
+        }
+
         if (flags & MediaCodec::BUFFER_FLAG_EOS) {
             sp<AMessage> notify = mNotify->dup();
             notify->setInt32("what", kWhatEOS);
@@ -354,6 +404,10 @@
             sp<ABuffer> buffer = new ABuffer(size);
             buffer->meta()->setInt64("timeUs", timeUs);
 
+            if (!mIsVideo) {
+                ALOGV("audio time %lld us (%.2f secs)", timeUs, timeUs / 1E6);
+            }
+
             memcpy(buffer->data(),
                    mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset,
                    size);
@@ -368,9 +422,11 @@
             }
         }
 
-        err = mEncoder->releaseOutputBuffer(bufferIndex);
-    } else if (err == -EAGAIN) {
-        err = OK;
+        mEncoder->releaseOutputBuffer(bufferIndex);
+
+        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
+            break;
+        }
     }
 
     return err;
diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h
index 9f54523..93ff72f 100644
--- a/media/libstagefright/wifi-display/source/Converter.h
+++ b/media/libstagefright/wifi-display/source/Converter.h
@@ -25,6 +25,8 @@
 struct ABuffer;
 struct MediaCodec;
 
+#define ENABLE_SILENCE_DETECTION        1
+
 // Utility class that receives media access units and converts them into
 // media access unit of a different format.
 // Right now this'll convert raw video into H.264 and raw audio into AAC.
@@ -83,6 +85,11 @@
 
     bool mDoMoreWorkPending;
 
+#if ENABLE_SILENCE_DETECTION
+    int64_t mFirstSilentFrameUs;
+    bool mInSilentMode;
+#endif
+
     status_t initEncoder();
 
     status_t feedEncoderInputBuffers();
@@ -92,6 +99,8 @@
 
     void notifyError(status_t err);
 
+    static bool IsSilence(const sp<ABuffer> &accessUnit);
+
     DISALLOW_EVIL_CONSTRUCTORS(Converter);
 };