Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf2604f8 authored by Andreas Huber's avatar Andreas Huber
Browse files

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
parent 4a8b9a23
Loading
Loading
Loading
Loading
+68 −12
Original line number Diff line number Diff line
@@ -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,6 +381,7 @@ status_t Converter::doMoreWork() {
        feedEncoderInputBuffers();
    }

    for (;;) {
        size_t offset;
        size_t size;
        int64_t timeUs;
@@ -345,7 +389,13 @@ status_t Converter::doMoreWork() {
        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 @@ 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;
+9 −0
Original line number Diff line number Diff line
@@ -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);
};