Loading include/media/mediaplayer.h +1 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ enum media_event_type { MEDIA_BUFFERING_UPDATE = 3, MEDIA_SEEK_COMPLETE = 4, MEDIA_SET_VIDEO_SIZE = 5, MEDIA_RESET_COMPLETE = 6, // not visible on java side MEDIA_ERROR = 100, MEDIA_INFO = 200, }; Loading media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -87,7 +87,7 @@ bool NuPlayer::HTTPLiveSource::feedMoreTSData() { break; } else if (n < 0) { LOGI("input data EOS reached."); mTSParser->signalEOS(ERROR_END_OF_STREAM); mTSParser->signalEOS(n); mEOS = true; break; } else { Loading media/libmediaplayerservice/nuplayer/NuPlayer.cpp +145 −56 Original line number Diff line number Diff line Loading @@ -45,8 +45,11 @@ NuPlayer::NuPlayer() : mAudioEOS(false), mVideoEOS(false), mScanSourcesPending(false), mScanSourcesGeneration(0), mFlushingAudio(NONE), mFlushingVideo(NONE) { mFlushingVideo(NONE), mResetInProgress(false), mResetPostponed(false) { } NuPlayer::~NuPlayer() { Loading Loading @@ -87,18 +90,22 @@ void NuPlayer::start() { (new AMessage(kWhatStart, id()))->post(); } void NuPlayer::resetAsync() { (new AMessage(kWhatReset, id()))->post(); } // static bool NuPlayer::IsFlushingState(FlushStatus state, bool *formatChange) { bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) { switch (state) { case FLUSHING_DECODER: if (formatChange != NULL) { *formatChange = false; if (needShutdown != NULL) { *needShutdown = false; } return true; case FLUSHING_DECODER_FORMATCHANGE: if (formatChange != NULL) { *formatChange = true; case FLUSHING_DECODER_SHUTDOWN: if (needShutdown != NULL) { *needShutdown = true; } return true; Loading @@ -111,7 +118,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatSetDataSource: { LOGI("kWhatSetDataSource"); LOGV("kWhatSetDataSource"); CHECK(mSource == NULL); Loading @@ -124,7 +131,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatSetVideoSurface: { LOGI("kWhatSetVideoSurface"); LOGV("kWhatSetVideoSurface"); sp<RefBase> obj; CHECK(msg->findObject("surface", &obj)); Loading @@ -135,7 +142,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatSetAudioSink: { LOGI("kWhatSetAudioSink"); LOGV("kWhatSetAudioSink"); sp<RefBase> obj; CHECK(msg->findObject("sink", &obj)); Loading @@ -146,6 +153,9 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatStart: { mAudioEOS = false; mVideoEOS = false; mSource->start(); mRenderer = new Renderer( Loading @@ -154,13 +164,19 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { looper()->registerHandler(mRenderer); (new AMessage(kWhatScanSources, id()))->post(); mScanSourcesPending = true; postScanSources(); break; } case kWhatScanSources: { int32_t generation; CHECK(msg->findInt32("generation", &generation)); if (generation != mScanSourcesGeneration) { // Drop obsolete msg. break; } mScanSourcesPending = false; instantiateDecoder(false, &mVideoDecoder); Loading @@ -170,6 +186,11 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { } if (!mSource->feedMoreTSData()) { if (mAudioDecoder == NULL && mVideoDecoder == NULL) { // We're not currently decoding anything (no audio or // video tracks found) and we just ran out of input data. notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); } break; } Loading Loading @@ -203,20 +224,20 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { } else if (what == ACodec::kWhatEOS) { mRenderer->queueEOS(audio, ERROR_END_OF_STREAM); } else if (what == ACodec::kWhatFlushCompleted) { bool formatChange; bool needShutdown; if (audio) { CHECK(IsFlushingState(mFlushingAudio, &formatChange)); CHECK(IsFlushingState(mFlushingAudio, &needShutdown)); mFlushingAudio = FLUSHED; } else { CHECK(IsFlushingState(mFlushingVideo, &formatChange)); CHECK(IsFlushingState(mFlushingVideo, &needShutdown)); mFlushingVideo = FLUSHED; } LOGI("decoder %s flush completed", audio ? "audio" : "video"); LOGV("decoder %s flush completed", audio ? "audio" : "video"); if (formatChange) { LOGI("initiating %s decoder shutdown", if (needShutdown) { LOGV("initiating %s decoder shutdown", audio ? "audio" : "video"); (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); Loading @@ -238,7 +259,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { int32_t sampleRate; CHECK(codecRequest->findInt32("sample-rate", &sampleRate)); LOGI("Audio output format changed to %d Hz, %d channels", LOGV("Audio output format changed to %d Hz, %d channels", sampleRate, numChannels); mAudioSink->close(); Loading @@ -247,7 +268,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mRenderer->signalAudioSinkChanged(); } else if (what == ACodec::kWhatShutdownCompleted) { LOGI("%s shutdown completed", audio ? "audio" : "video"); LOGV("%s shutdown completed", audio ? "audio" : "video"); if (audio) { mAudioDecoder.clear(); Loading Loading @@ -285,7 +306,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mVideoEOS = true; } LOGI("reached %s EOS", audio ? "audio" : "video"); LOGV("reached %s EOS", audio ? "audio" : "video"); if ((mAudioEOS || mAudioDecoder == NULL) && (mVideoEOS || mVideoDecoder == NULL)) { Loading @@ -297,7 +318,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); LOGI("renderer %s flush completed.", audio ? "audio" : "video"); LOGV("renderer %s flush completed.", audio ? "audio" : "video"); } break; } Loading @@ -307,6 +328,37 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatReset: { LOGV("kWhatReset"); if (mFlushingAudio != NONE || mFlushingVideo != NONE) { // We're currently flushing, postpone the reset until that's // completed. LOGV("postponing reset"); mResetPostponed = true; break; } if (mAudioDecoder == NULL && mVideoDecoder == NULL) { finishReset(); break; } if (mAudioDecoder != NULL) { flushDecoder(true /* audio */, true /* needShutdown */); } if (mVideoDecoder != NULL) { flushDecoder(false /* audio */, true /* needShutdown */); } mResetInProgress = true; break; } default: TRESPASS(); break; Loading @@ -322,7 +374,7 @@ void NuPlayer::finishFlushIfPossible() { return; } LOGI("both audio and video are flushed now."); LOGV("both audio and video are flushed now."); mRenderer->signalTimeDiscontinuity(); Loading @@ -343,10 +395,39 @@ void NuPlayer::finishFlushIfPossible() { mFlushingAudio = NONE; mFlushingVideo = NONE; if (scanSourcesAgain && !mScanSourcesPending) { mScanSourcesPending = true; (new AMessage(kWhatScanSources, id()))->post(); if (mResetInProgress) { LOGV("reset completed"); mResetInProgress = false; finishReset(); } else if (mResetPostponed) { (new AMessage(kWhatReset, id()))->post(); mResetPostponed = false; } else if (scanSourcesAgain) { postScanSources(); } } void NuPlayer::finishReset() { CHECK(mAudioDecoder == NULL); CHECK(mVideoDecoder == NULL); mRenderer.clear(); mSource.clear(); notifyListener(MEDIA_RESET_COMPLETE, 0, 0); } void NuPlayer::postScanSources() { if (mScanSourcesPending) { return; } sp<AMessage> msg = new AMessage(kWhatScanSources, id()); msg->setInt32("generation", mScanSourcesGeneration); msg->post(); mScanSourcesPending = true; } status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { Loading Loading @@ -396,37 +477,10 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { bool formatChange = type == ATSParser::DISCONTINUITY_FORMATCHANGE; LOGI("%s discontinuity (formatChange=%d)", LOGV("%s discontinuity (formatChange=%d)", audio ? "audio" : "video", formatChange); (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); mRenderer->flush(audio); if (audio) { CHECK(mFlushingAudio == NONE || mFlushingAudio == AWAITING_DISCONTINUITY); mFlushingAudio = formatChange ? FLUSHING_DECODER_FORMATCHANGE : FLUSHING_DECODER; if (mFlushingVideo == NONE) { mFlushingVideo = (mVideoDecoder != NULL) ? AWAITING_DISCONTINUITY : FLUSHED; } } else { CHECK(mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY); mFlushingVideo = formatChange ? FLUSHING_DECODER_FORMATCHANGE : FLUSHING_DECODER; if (mFlushingAudio == NONE) { mFlushingAudio = (mAudioDecoder != NULL) ? AWAITING_DISCONTINUITY : FLUSHED; } } flushDecoder(audio, formatChange); } reply->setInt32("err", err); Loading @@ -439,7 +493,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { #if 0 int64_t mediaTimeUs; CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); LOGI("feeding %s input buffer at media time %.2f secs", LOGV("feeding %s input buffer at media time %.2f secs", audio ? "audio" : "video", mediaTimeUs / 1E6); #endif Loading Loading @@ -478,4 +532,39 @@ void NuPlayer::notifyListener(int msg, int ext1, int ext2) { listener->sendEvent(msg, ext1, ext2); } void NuPlayer::flushDecoder(bool audio, bool needShutdown) { // Make sure we don't continue to scan sources until we finish flushing. ++mScanSourcesGeneration; (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); mRenderer->flush(audio); FlushStatus newStatus = needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; if (audio) { CHECK(mFlushingAudio == NONE || mFlushingAudio == AWAITING_DISCONTINUITY); mFlushingAudio = newStatus; if (mFlushingVideo == NONE) { mFlushingVideo = (mVideoDecoder != NULL) ? AWAITING_DISCONTINUITY : FLUSHED; } } else { CHECK(mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY); mFlushingVideo = newStatus; if (mFlushingAudio == NONE) { mFlushingAudio = (mAudioDecoder != NULL) ? AWAITING_DISCONTINUITY : FLUSHED; } } } } // namespace android media/libmediaplayerservice/nuplayer/NuPlayer.h +15 −3 Original line number Diff line number Diff line Loading @@ -40,6 +40,10 @@ struct NuPlayer : public AHandler { void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink); void start(); // Will notify the listener that reset() has completed // with code MEDIA_RESET_COMPLETE. void resetAsync(); protected: virtual ~NuPlayer(); Loading @@ -63,6 +67,7 @@ private: kWhatVideoNotify, kWhatAudioNotify, kWhatRendererNotify, kWhatReset, }; wp<MediaPlayerBase> mListener; Loading @@ -73,17 +78,17 @@ private: sp<Decoder> mAudioDecoder; sp<Renderer> mRenderer; bool mEOS; bool mAudioEOS; bool mVideoEOS; bool mScanSourcesPending; int32_t mScanSourcesGeneration; enum FlushStatus { NONE, AWAITING_DISCONTINUITY, FLUSHING_DECODER, FLUSHING_DECODER_FORMATCHANGE, FLUSHING_DECODER_SHUTDOWN, SHUTTING_DOWN_DECODER, FLUSHED, SHUT_DOWN, Loading @@ -91,6 +96,8 @@ private: FlushStatus mFlushingAudio; FlushStatus mFlushingVideo; bool mResetInProgress; bool mResetPostponed; status_t instantiateDecoder(bool audio, sp<Decoder> *decoder); Loading @@ -101,7 +108,12 @@ private: void finishFlushIfPossible(); static bool IsFlushingState(FlushStatus state, bool *formatChange = NULL); void flushDecoder(bool audio, bool needShutdown); static bool IsFlushingState(FlushStatus state, bool *needShutdown = NULL); void finishReset(); void postScanSources(); DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; Loading media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +24 −1 Original line number Diff line number Diff line Loading @@ -22,12 +22,14 @@ #include "NuPlayer.h" #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> namespace android { NuPlayerDriver::NuPlayerDriver() : mLooper(new ALooper), : mResetInProgress(false), mLooper(new ALooper), mPlayer(false) { mLooper->setName("NuPlayerDriver Looper"); Loading Loading @@ -121,6 +123,15 @@ status_t NuPlayerDriver::getDuration(int *msec) { } status_t NuPlayerDriver::reset() { Mutex::Autolock autoLock(mLock); mResetInProgress = true; mPlayer->resetAsync(); while (mResetInProgress) { mCondition.wait(mLock); } return OK; } Loading @@ -145,4 +156,16 @@ status_t NuPlayerDriver::getMetadata( return INVALID_OPERATION; } void NuPlayerDriver::sendEvent(int msg, int ext1, int ext2) { if (msg != MEDIA_RESET_COMPLETE) { MediaPlayerInterface::sendEvent(msg, ext1, ext2); return; } Mutex::Autolock autoLock(mLock); CHECK(mResetInProgress); mResetInProgress = false; mCondition.broadcast(); } } // namespace android Loading
include/media/mediaplayer.h +1 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ enum media_event_type { MEDIA_BUFFERING_UPDATE = 3, MEDIA_SEEK_COMPLETE = 4, MEDIA_SET_VIDEO_SIZE = 5, MEDIA_RESET_COMPLETE = 6, // not visible on java side MEDIA_ERROR = 100, MEDIA_INFO = 200, }; Loading
media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -87,7 +87,7 @@ bool NuPlayer::HTTPLiveSource::feedMoreTSData() { break; } else if (n < 0) { LOGI("input data EOS reached."); mTSParser->signalEOS(ERROR_END_OF_STREAM); mTSParser->signalEOS(n); mEOS = true; break; } else { Loading
media/libmediaplayerservice/nuplayer/NuPlayer.cpp +145 −56 Original line number Diff line number Diff line Loading @@ -45,8 +45,11 @@ NuPlayer::NuPlayer() : mAudioEOS(false), mVideoEOS(false), mScanSourcesPending(false), mScanSourcesGeneration(0), mFlushingAudio(NONE), mFlushingVideo(NONE) { mFlushingVideo(NONE), mResetInProgress(false), mResetPostponed(false) { } NuPlayer::~NuPlayer() { Loading Loading @@ -87,18 +90,22 @@ void NuPlayer::start() { (new AMessage(kWhatStart, id()))->post(); } void NuPlayer::resetAsync() { (new AMessage(kWhatReset, id()))->post(); } // static bool NuPlayer::IsFlushingState(FlushStatus state, bool *formatChange) { bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) { switch (state) { case FLUSHING_DECODER: if (formatChange != NULL) { *formatChange = false; if (needShutdown != NULL) { *needShutdown = false; } return true; case FLUSHING_DECODER_FORMATCHANGE: if (formatChange != NULL) { *formatChange = true; case FLUSHING_DECODER_SHUTDOWN: if (needShutdown != NULL) { *needShutdown = true; } return true; Loading @@ -111,7 +118,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatSetDataSource: { LOGI("kWhatSetDataSource"); LOGV("kWhatSetDataSource"); CHECK(mSource == NULL); Loading @@ -124,7 +131,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatSetVideoSurface: { LOGI("kWhatSetVideoSurface"); LOGV("kWhatSetVideoSurface"); sp<RefBase> obj; CHECK(msg->findObject("surface", &obj)); Loading @@ -135,7 +142,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatSetAudioSink: { LOGI("kWhatSetAudioSink"); LOGV("kWhatSetAudioSink"); sp<RefBase> obj; CHECK(msg->findObject("sink", &obj)); Loading @@ -146,6 +153,9 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatStart: { mAudioEOS = false; mVideoEOS = false; mSource->start(); mRenderer = new Renderer( Loading @@ -154,13 +164,19 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { looper()->registerHandler(mRenderer); (new AMessage(kWhatScanSources, id()))->post(); mScanSourcesPending = true; postScanSources(); break; } case kWhatScanSources: { int32_t generation; CHECK(msg->findInt32("generation", &generation)); if (generation != mScanSourcesGeneration) { // Drop obsolete msg. break; } mScanSourcesPending = false; instantiateDecoder(false, &mVideoDecoder); Loading @@ -170,6 +186,11 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { } if (!mSource->feedMoreTSData()) { if (mAudioDecoder == NULL && mVideoDecoder == NULL) { // We're not currently decoding anything (no audio or // video tracks found) and we just ran out of input data. notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); } break; } Loading Loading @@ -203,20 +224,20 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { } else if (what == ACodec::kWhatEOS) { mRenderer->queueEOS(audio, ERROR_END_OF_STREAM); } else if (what == ACodec::kWhatFlushCompleted) { bool formatChange; bool needShutdown; if (audio) { CHECK(IsFlushingState(mFlushingAudio, &formatChange)); CHECK(IsFlushingState(mFlushingAudio, &needShutdown)); mFlushingAudio = FLUSHED; } else { CHECK(IsFlushingState(mFlushingVideo, &formatChange)); CHECK(IsFlushingState(mFlushingVideo, &needShutdown)); mFlushingVideo = FLUSHED; } LOGI("decoder %s flush completed", audio ? "audio" : "video"); LOGV("decoder %s flush completed", audio ? "audio" : "video"); if (formatChange) { LOGI("initiating %s decoder shutdown", if (needShutdown) { LOGV("initiating %s decoder shutdown", audio ? "audio" : "video"); (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); Loading @@ -238,7 +259,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { int32_t sampleRate; CHECK(codecRequest->findInt32("sample-rate", &sampleRate)); LOGI("Audio output format changed to %d Hz, %d channels", LOGV("Audio output format changed to %d Hz, %d channels", sampleRate, numChannels); mAudioSink->close(); Loading @@ -247,7 +268,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mRenderer->signalAudioSinkChanged(); } else if (what == ACodec::kWhatShutdownCompleted) { LOGI("%s shutdown completed", audio ? "audio" : "video"); LOGV("%s shutdown completed", audio ? "audio" : "video"); if (audio) { mAudioDecoder.clear(); Loading Loading @@ -285,7 +306,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mVideoEOS = true; } LOGI("reached %s EOS", audio ? "audio" : "video"); LOGV("reached %s EOS", audio ? "audio" : "video"); if ((mAudioEOS || mAudioDecoder == NULL) && (mVideoEOS || mVideoDecoder == NULL)) { Loading @@ -297,7 +318,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); LOGI("renderer %s flush completed.", audio ? "audio" : "video"); LOGV("renderer %s flush completed.", audio ? "audio" : "video"); } break; } Loading @@ -307,6 +328,37 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatReset: { LOGV("kWhatReset"); if (mFlushingAudio != NONE || mFlushingVideo != NONE) { // We're currently flushing, postpone the reset until that's // completed. LOGV("postponing reset"); mResetPostponed = true; break; } if (mAudioDecoder == NULL && mVideoDecoder == NULL) { finishReset(); break; } if (mAudioDecoder != NULL) { flushDecoder(true /* audio */, true /* needShutdown */); } if (mVideoDecoder != NULL) { flushDecoder(false /* audio */, true /* needShutdown */); } mResetInProgress = true; break; } default: TRESPASS(); break; Loading @@ -322,7 +374,7 @@ void NuPlayer::finishFlushIfPossible() { return; } LOGI("both audio and video are flushed now."); LOGV("both audio and video are flushed now."); mRenderer->signalTimeDiscontinuity(); Loading @@ -343,10 +395,39 @@ void NuPlayer::finishFlushIfPossible() { mFlushingAudio = NONE; mFlushingVideo = NONE; if (scanSourcesAgain && !mScanSourcesPending) { mScanSourcesPending = true; (new AMessage(kWhatScanSources, id()))->post(); if (mResetInProgress) { LOGV("reset completed"); mResetInProgress = false; finishReset(); } else if (mResetPostponed) { (new AMessage(kWhatReset, id()))->post(); mResetPostponed = false; } else if (scanSourcesAgain) { postScanSources(); } } void NuPlayer::finishReset() { CHECK(mAudioDecoder == NULL); CHECK(mVideoDecoder == NULL); mRenderer.clear(); mSource.clear(); notifyListener(MEDIA_RESET_COMPLETE, 0, 0); } void NuPlayer::postScanSources() { if (mScanSourcesPending) { return; } sp<AMessage> msg = new AMessage(kWhatScanSources, id()); msg->setInt32("generation", mScanSourcesGeneration); msg->post(); mScanSourcesPending = true; } status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { Loading Loading @@ -396,37 +477,10 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { bool formatChange = type == ATSParser::DISCONTINUITY_FORMATCHANGE; LOGI("%s discontinuity (formatChange=%d)", LOGV("%s discontinuity (formatChange=%d)", audio ? "audio" : "video", formatChange); (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); mRenderer->flush(audio); if (audio) { CHECK(mFlushingAudio == NONE || mFlushingAudio == AWAITING_DISCONTINUITY); mFlushingAudio = formatChange ? FLUSHING_DECODER_FORMATCHANGE : FLUSHING_DECODER; if (mFlushingVideo == NONE) { mFlushingVideo = (mVideoDecoder != NULL) ? AWAITING_DISCONTINUITY : FLUSHED; } } else { CHECK(mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY); mFlushingVideo = formatChange ? FLUSHING_DECODER_FORMATCHANGE : FLUSHING_DECODER; if (mFlushingAudio == NONE) { mFlushingAudio = (mAudioDecoder != NULL) ? AWAITING_DISCONTINUITY : FLUSHED; } } flushDecoder(audio, formatChange); } reply->setInt32("err", err); Loading @@ -439,7 +493,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { #if 0 int64_t mediaTimeUs; CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); LOGI("feeding %s input buffer at media time %.2f secs", LOGV("feeding %s input buffer at media time %.2f secs", audio ? "audio" : "video", mediaTimeUs / 1E6); #endif Loading Loading @@ -478,4 +532,39 @@ void NuPlayer::notifyListener(int msg, int ext1, int ext2) { listener->sendEvent(msg, ext1, ext2); } void NuPlayer::flushDecoder(bool audio, bool needShutdown) { // Make sure we don't continue to scan sources until we finish flushing. ++mScanSourcesGeneration; (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); mRenderer->flush(audio); FlushStatus newStatus = needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; if (audio) { CHECK(mFlushingAudio == NONE || mFlushingAudio == AWAITING_DISCONTINUITY); mFlushingAudio = newStatus; if (mFlushingVideo == NONE) { mFlushingVideo = (mVideoDecoder != NULL) ? AWAITING_DISCONTINUITY : FLUSHED; } } else { CHECK(mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY); mFlushingVideo = newStatus; if (mFlushingAudio == NONE) { mFlushingAudio = (mAudioDecoder != NULL) ? AWAITING_DISCONTINUITY : FLUSHED; } } } } // namespace android
media/libmediaplayerservice/nuplayer/NuPlayer.h +15 −3 Original line number Diff line number Diff line Loading @@ -40,6 +40,10 @@ struct NuPlayer : public AHandler { void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink); void start(); // Will notify the listener that reset() has completed // with code MEDIA_RESET_COMPLETE. void resetAsync(); protected: virtual ~NuPlayer(); Loading @@ -63,6 +67,7 @@ private: kWhatVideoNotify, kWhatAudioNotify, kWhatRendererNotify, kWhatReset, }; wp<MediaPlayerBase> mListener; Loading @@ -73,17 +78,17 @@ private: sp<Decoder> mAudioDecoder; sp<Renderer> mRenderer; bool mEOS; bool mAudioEOS; bool mVideoEOS; bool mScanSourcesPending; int32_t mScanSourcesGeneration; enum FlushStatus { NONE, AWAITING_DISCONTINUITY, FLUSHING_DECODER, FLUSHING_DECODER_FORMATCHANGE, FLUSHING_DECODER_SHUTDOWN, SHUTTING_DOWN_DECODER, FLUSHED, SHUT_DOWN, Loading @@ -91,6 +96,8 @@ private: FlushStatus mFlushingAudio; FlushStatus mFlushingVideo; bool mResetInProgress; bool mResetPostponed; status_t instantiateDecoder(bool audio, sp<Decoder> *decoder); Loading @@ -101,7 +108,12 @@ private: void finishFlushIfPossible(); static bool IsFlushingState(FlushStatus state, bool *formatChange = NULL); void flushDecoder(bool audio, bool needShutdown); static bool IsFlushingState(FlushStatus state, bool *needShutdown = NULL); void finishReset(); void postScanSources(); DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; Loading
media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +24 −1 Original line number Diff line number Diff line Loading @@ -22,12 +22,14 @@ #include "NuPlayer.h" #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> namespace android { NuPlayerDriver::NuPlayerDriver() : mLooper(new ALooper), : mResetInProgress(false), mLooper(new ALooper), mPlayer(false) { mLooper->setName("NuPlayerDriver Looper"); Loading Loading @@ -121,6 +123,15 @@ status_t NuPlayerDriver::getDuration(int *msec) { } status_t NuPlayerDriver::reset() { Mutex::Autolock autoLock(mLock); mResetInProgress = true; mPlayer->resetAsync(); while (mResetInProgress) { mCondition.wait(mLock); } return OK; } Loading @@ -145,4 +156,16 @@ status_t NuPlayerDriver::getMetadata( return INVALID_OPERATION; } void NuPlayerDriver::sendEvent(int msg, int ext1, int ext2) { if (msg != MEDIA_RESET_COMPLETE) { MediaPlayerInterface::sendEvent(msg, ext1, ext2); return; } Mutex::Autolock autoLock(mLock); CHECK(mResetInProgress); mResetInProgress = false; mCondition.broadcast(); } } // namespace android