Loading media/libmediaplayerservice/nuplayer/NuPlayer.cpp +15 −24 Original line number Original line Diff line number Diff line Loading @@ -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); } } Loading Loading @@ -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 Loading Loading @@ -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); Loading media/libmediaplayerservice/nuplayer/NuPlayer.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -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); Loading media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +9 −18 Original line number Original line Diff line number Diff line Loading @@ -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), Loading @@ -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") { Loading Loading @@ -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; Loading Loading @@ -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) { Loading media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +0 −3 Original line number Original line Diff line number Diff line Loading @@ -53,7 +53,6 @@ private: kWhatRenderBuffer = 'rndr', kWhatRenderBuffer = 'rndr', }; }; sp<AMessage> mNotify; sp<NativeWindowWrapper> mNativeWindow; sp<NativeWindowWrapper> mNativeWindow; sp<Source> mSource; sp<Source> mSource; Loading Loading @@ -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(); Loading media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp +18 −2 Original line number Original line Diff line number Diff line Loading @@ -28,8 +28,10 @@ namespace android { namespace android { NuPlayer::DecoderBase::DecoderBase() NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> ¬ify) : 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; Loading Loading @@ -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
media/libmediaplayerservice/nuplayer/NuPlayer.cpp +15 −24 Original line number Original line Diff line number Diff line Loading @@ -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); } } Loading Loading @@ -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 Loading Loading @@ -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); Loading
media/libmediaplayerservice/nuplayer/NuPlayer.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -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); Loading
media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +9 −18 Original line number Original line Diff line number Diff line Loading @@ -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), Loading @@ -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") { Loading Loading @@ -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; Loading Loading @@ -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) { Loading
media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +0 −3 Original line number Original line Diff line number Diff line Loading @@ -53,7 +53,6 @@ private: kWhatRenderBuffer = 'rndr', kWhatRenderBuffer = 'rndr', }; }; sp<AMessage> mNotify; sp<NativeWindowWrapper> mNativeWindow; sp<NativeWindowWrapper> mNativeWindow; sp<Source> mSource; sp<Source> mSource; Loading Loading @@ -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(); Loading
media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp +18 −2 Original line number Original line Diff line number Diff line Loading @@ -28,8 +28,10 @@ namespace android { namespace android { NuPlayer::DecoderBase::DecoderBase() NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> ¬ify) : 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; Loading Loading @@ -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