OSDN Git Service

Enable silence detection and don't driver the audio encoder
authorAndreas Huber <andih@google.com>
Tue, 2 Oct 2012 21:17:38 +0000 (14:17 -0700)
committerAndreas Huber <andih@google.com>
Tue, 2 Oct 2012 21:17:38 +0000 (14:17 -0700)
or send any audio out over the network if we've seen at least one second
of silence.

Change-Id: Ic2bca4ce7d55bd246283dc669f5f5cb6106d88ea
related-to-bug: 7248248

media/libstagefright/wifi-display/source/Converter.cpp
media/libstagefright/wifi-display/source/Converter.h

index b9539e9..6f336c7 100644 (file)
@@ -44,7 +44,12 @@ Converter::Converter(
       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 @@ void Converter::notifyError(status_t err) {
     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 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) {
                 }
 #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 @@ void Converter::scheduleDoMoreWork() {
     }
 
     mDoMoreWorkPending = true;
-    (new AMessage(kWhatDoMoreWork, id()))->post(10000ll);
+    (new AMessage(kWhatDoMoreWork, id()))->post(mIsVideo ? 10000ll : 5000ll);
 }
 
 status_t Converter::feedEncoderInputBuffers() {
@@ -338,14 +381,21 @@ status_t Converter::doMoreWork() {
         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 == -EAGAIN) {
+                err = OK;
+            }
+            break;
+        }
 
-    if (err == OK) {
         if (flags & MediaCodec::BUFFER_FLAG_EOS) {
             sp<AMessage> notify = mNotify->dup();
             notify->setInt32("what", kWhatEOS);
@@ -354,6 +404,10 @@ status_t Converter::doMoreWork() {
             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 @@ status_t Converter::doMoreWork() {
             }
         }
 
-        err = mEncoder->releaseOutputBuffer(bufferIndex);
-    } else if (err == -EAGAIN) {
-        err = OK;
+        mEncoder->releaseOutputBuffer(bufferIndex);
+
+        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
+            break;
+        }
     }
 
     return err;
index 9f54523..93ff72f 100644 (file)
@@ -25,6 +25,8 @@ namespace android {
 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 @@ private:
 
     bool mDoMoreWorkPending;
 
+#if ENABLE_SILENCE_DETECTION
+    int64_t mFirstSilentFrameUs;
+    bool mInSilentMode;
+#endif
+
     status_t initEncoder();
 
     status_t feedEncoderInputBuffers();
@@ -92,6 +99,8 @@ private:
 
     void notifyError(status_t err);
 
+    static bool IsSilence(const sp<ABuffer> &accessUnit);
+
     DISALLOW_EVIL_CONSTRUCTORS(Converter);
 };