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

Commit 4c56f8e0 authored by Andy Hung's avatar Andy Hung Committed by Android Git Automerger
Browse files

am b65842dd: Merge "Fix NuPlayer assertion on failure to create AudioTrack" into lmp-mr1-dev

* commit 'b65842dd':
  Fix NuPlayer assertion on failure to create AudioTrack
parents 7cc9a1c5 b65842dd
Loading
Loading
Loading
Loading
+15 −24
Original line number Diff line number Diff line
@@ -629,15 +629,16 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
                sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
                audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
                bool canOffload = canOffloadStream(audioMeta, (videoFormat != NULL),
                         true /* is_streaming */, streamType);
                const bool hasVideo = (videoFormat != NULL);
                const bool canOffload = canOffloadStream(
                        audioMeta, hasVideo, true /* is_streaming */, streamType);
                if (canOffload) {
                    if (!mOffloadAudio) {
                        mRenderer->signalEnableOffloadAudio();
                    }
                    // open audio sink early under offload mode.
                    sp<AMessage> format = mSource->getFormat(true /*audio*/);
                    openAudioSink(format, true /*offloadOnly*/);
                    tryOpenAudioSinkForOffload(format, hasVideo);
                }
                instantiateDecoder(true, &mAudioDecoder);
            }
@@ -774,6 +775,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                // Decoder errors can be due to Source (e.g. from streaming),
                // or from decoding corrupted bitstreams, or from other decoder
                // MediaCodec operations (e.g. from an ongoing reset or seek).
                // They may also be due to openAudioSink failure at
                // decoder start or after a format change.
                //
                // We try to gracefully shut down the affected decoder if possible,
                // rather than trying to force the shutdown with something
@@ -1146,28 +1149,16 @@ void NuPlayer::postScanSources() {
    mScanSourcesPending = true;
}

void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) {
    uint32_t flags;
    int64_t durationUs;
    bool hasVideo = (mVideoDecoder != NULL);
    // FIXME: we should handle the case where the video decoder
    // is created after we receive the format change indication.
    // Current code will just make that we select deep buffer
    // with video which should not be a problem as it should
    // not prevent from keeping A/V sync.
    if (!hasVideo &&
            mSource->getDuration(&durationUs) == OK &&
            durationUs
                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
    } else {
        flags = AUDIO_OUTPUT_FLAG_NONE;
    }
void NuPlayer::tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo) {
    // Note: This is called early in NuPlayer to determine whether offloading
    // is possible; otherwise the decoders call the renderer openAudioSink directly.

    mOffloadAudio = mRenderer->openAudioSink(
            format, offloadOnly, hasVideo, flags);

    if (mOffloadAudio) {
    status_t err = mRenderer->openAudioSink(
            format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio);
    if (err != OK) {
        // Any failure we turn off mOffloadAudio.
        mOffloadAudio = false;
    } else if (mOffloadAudio) {
        sp<MetaData> audioMeta =
                mSource->getFormatMeta(true /* audio */);
        sendMetaDataToHal(mAudioSink, audioMeta);
+1 −1
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ private:
        mFlushComplete[1][1] = false;
    }

    void openAudioSink(const sp<AMessage> &format, bool offloadOnly);
    void tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo);
    void closeAudioSink();

    status_t instantiateDecoder(bool audio, sp<DecoderBase> *decoder);
+9 −18
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ NuPlayer::Decoder::Decoder(
        const sp<Renderer> &renderer,
        const sp<NativeWindowWrapper> &nativeWindow,
        const sp<CCDecoder> &ccDecoder)
    : mNotify(notify),
    : DecoderBase(notify),
      mNativeWindow(nativeWindow),
      mSource(source),
      mRenderer(renderer),
@@ -56,7 +56,6 @@ NuPlayer::Decoder::Decoder(
      mIsVideoAVC(false),
      mIsSecure(false),
      mFormatChangePending(false),
      mBufferGeneration(0),
      mPaused(true),
      mResumePending(false),
      mComponentName("decoder") {
@@ -336,20 +335,6 @@ void NuPlayer::Decoder::doRequestBuffers() {
    }
}

void NuPlayer::Decoder::handleError(int32_t err)
{
    // We cannot immediately release the codec due to buffers still outstanding
    // in the renderer.  We signal to the player the error so it can shutdown/release the
    // decoder after flushing and increment the generation to discard unnecessary messages.

    ++mBufferGeneration;

    sp<AMessage> notify = mNotify->dup();
    notify->setInt32("what", kWhatError);
    notify->setInt32("err", err);
    notify->post();
}

bool NuPlayer::Decoder::handleAnInputBuffer() {
    if (mFormatChangePending) {
        return false;
@@ -462,8 +447,14 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() {
                flags = AUDIO_OUTPUT_FLAG_NONE;
            }

            mRenderer->openAudioSink(
                    format, false /* offloadOnly */, hasVideo, flags);
            res = mRenderer->openAudioSink(
                    format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaded */);
            if (res != OK) {
                ALOGE("Failed to open AudioSink on format change for %s (err=%d)",
                        mComponentName.c_str(), res);
                handleError(res);
                return false;
            }
        }
        return true;
    } else if (res == INFO_DISCONTINUITY) {
+0 −3
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ private:
        kWhatRenderBuffer        = 'rndr',
    };

    sp<AMessage> mNotify;
    sp<NativeWindowWrapper> mNativeWindow;

    sp<Source> mSource;
@@ -83,12 +82,10 @@ private:
    bool mIsSecure;
    bool mFormatChangePending;

    int32_t mBufferGeneration;
    bool mPaused;
    bool mResumePending;
    AString mComponentName;

    void handleError(int32_t err);
    bool handleAnInputBuffer();
    bool handleAnOutputBuffer();

+18 −2
Original line number Diff line number Diff line
@@ -28,8 +28,10 @@

namespace android {

NuPlayer::DecoderBase::DecoderBase()
    : mRequestInputBuffersPending(false) {
NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
    :  mNotify(notify),
       mBufferGeneration(0),
       mRequestInputBuffersPending(false) {
    // Every decoder has its own looper because MediaCodec operations
    // are blocking, but NuPlayer needs asynchronous operations.
    mDecoderLooper = new ALooper;
@@ -180,5 +182,19 @@ void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
    }
}

void NuPlayer::DecoderBase::handleError(int32_t err)
{
    // We cannot immediately release the codec due to buffers still outstanding
    // in the renderer.  We signal to the player the error so it can shutdown/release the
    // decoder after flushing and increment the generation to discard unnecessary messages.

    ++mBufferGeneration;

    sp<AMessage> notify = mNotify->dup();
    notify->setInt32("what", kWhatError);
    notify->setInt32("err", err);
    notify->post();
}

}  // namespace android
Loading