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

Commit b65842dd authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

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

parents 76c156f7 202bce11
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