From 07fbf9458a9a6a5b644e7d02f7e59c7b75218d0c Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Tue, 2 Oct 2012 14:17:38 -0700 Subject: [PATCH] Enable silence detection and don't driver the audio encoder 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 --- .../wifi-display/source/Converter.cpp | 80 ++++++++++++++++++---- .../libstagefright/wifi-display/source/Converter.h | 9 +++ 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp index b9539e91fe..6f336c7a07 100644 --- a/media/libstagefright/wifi-display/source/Converter.cpp +++ b/media/libstagefright/wifi-display/source/Converter.cpp @@ -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 &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 &msg) { switch (msg->what()) { case kWhatMediaPullerNotify: @@ -220,6 +239,30 @@ void Converter::onMessageReceived(const sp &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 notify = mNotify->dup(); notify->setInt32("what", kWhatEOS); @@ -354,6 +404,10 @@ status_t Converter::doMoreWork() { sp 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; diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h index 9f54523258..93ff72fb03 100644 --- a/media/libstagefright/wifi-display/source/Converter.h +++ b/media/libstagefright/wifi-display/source/Converter.h @@ -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 &accessUnit); + DISALLOW_EVIL_CONSTRUCTORS(Converter); }; -- 2.11.0