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 Original line Diff line number Diff line
@@ -629,15 +629,16 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
                sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
                sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
                sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
                audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
                audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
                bool canOffload = canOffloadStream(audioMeta, (videoFormat != NULL),
                const bool hasVideo = (videoFormat != NULL);
                         true /* is_streaming */, streamType);
                const bool canOffload = canOffloadStream(
                        audioMeta, hasVideo, true /* is_streaming */, streamType);
                if (canOffload) {
                if (canOffload) {
                    if (!mOffloadAudio) {
                    if (!mOffloadAudio) {
                        mRenderer->signalEnableOffloadAudio();
                        mRenderer->signalEnableOffloadAudio();
                    }
                    }
                    // open audio sink early under offload mode.
                    // open audio sink early under offload mode.
                    sp<AMessage> format = mSource->getFormat(true /*audio*/);
                    sp<AMessage> format = mSource->getFormat(true /*audio*/);
                    openAudioSink(format, true /*offloadOnly*/);
                    tryOpenAudioSinkForOffload(format, hasVideo);
                }
                }
                instantiateDecoder(true, &mAudioDecoder);
                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),
                // Decoder errors can be due to Source (e.g. from streaming),
                // or from decoding corrupted bitstreams, or from other decoder
                // or from decoding corrupted bitstreams, or from other decoder
                // MediaCodec operations (e.g. from an ongoing reset or seek).
                // 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,
                // We try to gracefully shut down the affected decoder if possible,
                // rather than trying to force the shutdown with something
                // rather than trying to force the shutdown with something
@@ -1146,28 +1149,16 @@ void NuPlayer::postScanSources() {
    mScanSourcesPending = true;
    mScanSourcesPending = true;
}
}


void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) {
void NuPlayer::tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo) {
    uint32_t flags;
    // Note: This is called early in NuPlayer to determine whether offloading
    int64_t durationUs;
    // is possible; otherwise the decoders call the renderer openAudioSink directly.
    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;
    }


    mOffloadAudio = mRenderer->openAudioSink(
    status_t err = mRenderer->openAudioSink(
            format, offloadOnly, hasVideo, flags);
            format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio);

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


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


    status_t instantiateDecoder(bool audio, sp<DecoderBase> *decoder);
    status_t instantiateDecoder(bool audio, sp<DecoderBase> *decoder);
+9 −18
Original line number Original line Diff line number Diff line
@@ -44,7 +44,7 @@ NuPlayer::Decoder::Decoder(
        const sp<Renderer> &renderer,
        const sp<Renderer> &renderer,
        const sp<NativeWindowWrapper> &nativeWindow,
        const sp<NativeWindowWrapper> &nativeWindow,
        const sp<CCDecoder> &ccDecoder)
        const sp<CCDecoder> &ccDecoder)
    : mNotify(notify),
    : DecoderBase(notify),
      mNativeWindow(nativeWindow),
      mNativeWindow(nativeWindow),
      mSource(source),
      mSource(source),
      mRenderer(renderer),
      mRenderer(renderer),
@@ -56,7 +56,6 @@ NuPlayer::Decoder::Decoder(
      mIsVideoAVC(false),
      mIsVideoAVC(false),
      mIsSecure(false),
      mIsSecure(false),
      mFormatChangePending(false),
      mFormatChangePending(false),
      mBufferGeneration(0),
      mPaused(true),
      mPaused(true),
      mResumePending(false),
      mResumePending(false),
      mComponentName("decoder") {
      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() {
bool NuPlayer::Decoder::handleAnInputBuffer() {
    if (mFormatChangePending) {
    if (mFormatChangePending) {
        return false;
        return false;
@@ -462,8 +447,14 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() {
                flags = AUDIO_OUTPUT_FLAG_NONE;
                flags = AUDIO_OUTPUT_FLAG_NONE;
            }
            }


            mRenderer->openAudioSink(
            res = mRenderer->openAudioSink(
                    format, false /* offloadOnly */, hasVideo, flags);
                    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;
        return true;
    } else if (res == INFO_DISCONTINUITY) {
    } else if (res == INFO_DISCONTINUITY) {
+0 −3
Original line number Original line Diff line number Diff line
@@ -53,7 +53,6 @@ private:
        kWhatRenderBuffer        = 'rndr',
        kWhatRenderBuffer        = 'rndr',
    };
    };


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


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


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


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


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


namespace android {
namespace android {


NuPlayer::DecoderBase::DecoderBase()
NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
    : mRequestInputBuffersPending(false) {
    :  mNotify(notify),
       mBufferGeneration(0),
       mRequestInputBuffersPending(false) {
    // Every decoder has its own looper because MediaCodec operations
    // Every decoder has its own looper because MediaCodec operations
    // are blocking, but NuPlayer needs asynchronous operations.
    // are blocking, but NuPlayer needs asynchronous operations.
    mDecoderLooper = new ALooper;
    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
}  // namespace android
Loading