Loading media/libmediaplayer2/nuplayer2/NuPlayer2.cpp +130 −32 Original line number Diff line number Diff line Loading @@ -216,6 +216,7 @@ NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock) mAudioDecoderGeneration(0), mVideoDecoderGeneration(0), mRendererGeneration(0), mEOSMonitorGeneration(0), mLastStartedPlayingTimeNs(0), mPreviousSeekTimeUs(0), mAudioEOS(false), Loading Loading @@ -586,6 +587,11 @@ void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool msg->post(); } void NuPlayer2::rewind() { sp<AMessage> msg = new AMessage(kWhatRewind, this); msg->post(); } void NuPlayer2::writeTrackInfo( PlayerMessage* reply, const sp<AMessage>& format) const { if (format == NULL) { Loading Loading @@ -713,6 +719,22 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatEOSMonitor: { int32_t generation; CHECK(msg->findInt32("generation", &generation)); int32_t reason; CHECK(msg->findInt32("reason", &reason)); if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) { break; // stale or reset } ALOGV("kWhatEOSMonitor"); notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0); break; } case kWhatGetBufferingSettings: { sp<AReplyToken> replyID; Loading Loading @@ -1522,6 +1544,42 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatRewind: { ALOGV("kWhatRewind"); int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs; int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST; if (!mStarted) { if (!mSourceStarted) { mSourceStarted = true; mCurrentSourceInfo.mSource->start(); } performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode); break; } // seeks can take a while, so we essentially paused notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0); mDeferredActions.push_back( new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, FLUSH_CMD_FLUSH /* video */)); mDeferredActions.push_back( new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode)); // After a flush without shutdown, decoder is paused. // Don't resume it until source seek is done, otherwise it could // start pulling stale data too soon. mDeferredActions.push_back( new ResumeDecoderAction(false /* needNotify */)); processDeferredActions(); break; } case kWhatPause: { if (!mStarted) { Loading Loading @@ -1675,6 +1733,7 @@ void NuPlayer2::onStart(bool play) { mRenderer->setVideoFrameRate(rate); } addEndTimeMonitor(); // Renderer is created in paused state. if (play) { mRenderer->resume(); Loading @@ -1693,6 +1752,13 @@ void NuPlayer2::onStart(bool play) { postScanSources(); } void NuPlayer2::addEndTimeMonitor() { sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this); ++mEOSMonitorGeneration; msg->setInt32("generation", mEOSMonitorGeneration); mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs); } void NuPlayer2::startPlaybackTimer(const char *where) { Mutex::Autolock autoLock(mPlayingTimeLock); if (mLastStartedPlayingTimeNs == 0) { Loading Loading @@ -2473,17 +2539,22 @@ void NuPlayer2::performPlayNextDataSource() { long previousSrcId; { Mutex::Autolock autoLock(mSourceLock); mCurrentSourceInfo.mSource = mNextSourceInfo.mSource; mNextSourceInfo.mSource = NULL; previousSrcId = mCurrentSourceInfo.mSrcId; mCurrentSourceInfo.mSrcId = mNextSourceInfo.mSrcId; ++mNextSourceInfo.mSrcId; // to distinguish the two sources. mCurrentSourceInfo = mNextSourceInfo; mNextSourceInfo = SourceInfo(); mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources. } if (mDriver != NULL) { sp<NuPlayer2Driver> driver = mDriver.promote(); if (driver != NULL) { notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0); int64_t durationUs; if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) { driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs); } notifyListener( mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0); } Loading @@ -2494,6 +2565,8 @@ void NuPlayer2::performPlayNextDataSource() { mResetting = false; mSourceStarted = false; addEndTimeMonitor(); // Modular DRM if (mCrypto != NULL) { // decoders will be flushed before this so their mCrypto would go away on their own Loading Loading @@ -2589,8 +2662,9 @@ void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) { switch (what) { case Source::kWhatPrepared: { ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p", mCurrentSourceInfo.mSource.get()); ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)", mCurrentSourceInfo.mSource.get(), (long long)srcId); if (srcId == mCurrentSourceInfo.mSrcId) { if (mCurrentSourceInfo.mSource == NULL) { // This is a stale notification from a source that was // asynchronously preparing when the client called reset(). Loading Loading @@ -2621,6 +2695,18 @@ void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) { } driver->notifyPrepareCompleted(srcId, err); } } else if (srcId == mNextSourceInfo.mSrcId) { if (mNextSourceInfo.mSource == NULL) { break; // stale } sp<NuPlayer2Driver> driver = mDriver.promote(); if (driver != NULL) { int32_t err; CHECK(msg->findInt32("err", &err)); driver->notifyPrepareCompleted(srcId, err); } } break; } Loading Loading @@ -2665,8 +2751,10 @@ void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) { driver->notifyListener( srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0); } if (srcId == mCurrentSourceInfo.mSrcId) { driver->notifyFlagsChanged(srcId, flags); } } if (srcId == mCurrentSourceInfo.mSrcId) { if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) Loading Loading @@ -3131,4 +3219,14 @@ NuPlayer2::SourceInfo::SourceInfo() mEndTimeUs(INT64_MAX) { } NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) { mSource = other.mSource; mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType; mSrcId = other.mSrcId; mSourceFlags = other.mSourceFlags; mStartTimeUs = other.mStartTimeUs; mEndTimeUs = other.mEndTimeUs; return *this; } } // namespace android media/libmediaplayer2/nuplayer2/NuPlayer2.h +7 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ struct NuPlayer2 : public AHandler { int64_t seekTimeUs, MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC, bool needNotify = false); void rewind(); status_t setVideoScalingMode(int32_t mode); status_t getTrackInfo(PlayerMessage* reply) const; Loading Loading @@ -154,6 +155,8 @@ private: kWhatSetBufferingSettings = 'sBuS', kWhatPrepareDrm = 'pDrm', kWhatReleaseDrm = 'rDrm', kWhatRewind = 'reWd', kWhatEOSMonitor = 'eosM', }; typedef enum { Loading @@ -167,6 +170,7 @@ private: struct SourceInfo { SourceInfo(); SourceInfo &operator=(const SourceInfo &); sp<Source> mSource; std::atomic<DATA_SOURCE_TYPE> mDataSourceType; Loading Loading @@ -194,6 +198,7 @@ private: int32_t mAudioDecoderGeneration; int32_t mVideoDecoderGeneration; int32_t mRendererGeneration; int32_t mEOSMonitorGeneration; Mutex mPlayingTimeLock; int64_t mLastStartedPlayingTimeNs; Loading Loading @@ -302,6 +307,8 @@ private: void notifyListener(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in = NULL); void addEndTimeMonitor(); void handleFlushComplete(bool audio, bool isDecoder); void finishFlushIfPossible(); Loading media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -298,7 +298,7 @@ status_t NuPlayer2Driver::start_l() { case STATE_RUNNING: { if (mAtEOS) { mPlayer->seekToAsync(0); mPlayer->rewind(); mAtEOS = false; mPositionUs = -1; } Loading Loading @@ -859,7 +859,7 @@ void NuPlayer2Driver::notifyListener_l( } } if (mLooping || mAutoLoop) { mPlayer->seekToAsync(0); mPlayer->rewind(); if (mAudioSink != NULL) { // The renderer has stopped the sink at the end in order to play out // the last little bit of audio. In looping mode, we need to restart it. Loading media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -1563,6 +1563,7 @@ void NuPlayer2::Renderer::onFlush(const sp<AMessage> &msg) { } else { notifyComplete = mNotifyCompleteVideo; mNotifyCompleteVideo = false; mVideoRenderingStarted = false; } // If we're currently syncing the queues, i.e. dropping audio while Loading Loading
media/libmediaplayer2/nuplayer2/NuPlayer2.cpp +130 −32 Original line number Diff line number Diff line Loading @@ -216,6 +216,7 @@ NuPlayer2::NuPlayer2(pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock) mAudioDecoderGeneration(0), mVideoDecoderGeneration(0), mRendererGeneration(0), mEOSMonitorGeneration(0), mLastStartedPlayingTimeNs(0), mPreviousSeekTimeUs(0), mAudioEOS(false), Loading Loading @@ -586,6 +587,11 @@ void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool msg->post(); } void NuPlayer2::rewind() { sp<AMessage> msg = new AMessage(kWhatRewind, this); msg->post(); } void NuPlayer2::writeTrackInfo( PlayerMessage* reply, const sp<AMessage>& format) const { if (format == NULL) { Loading Loading @@ -713,6 +719,22 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatEOSMonitor: { int32_t generation; CHECK(msg->findInt32("generation", &generation)); int32_t reason; CHECK(msg->findInt32("reason", &reason)); if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) { break; // stale or reset } ALOGV("kWhatEOSMonitor"); notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0); break; } case kWhatGetBufferingSettings: { sp<AReplyToken> replyID; Loading Loading @@ -1522,6 +1544,42 @@ void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatRewind: { ALOGV("kWhatRewind"); int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs; int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST; if (!mStarted) { if (!mSourceStarted) { mSourceStarted = true; mCurrentSourceInfo.mSource->start(); } performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode); break; } // seeks can take a while, so we essentially paused notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0); mDeferredActions.push_back( new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, FLUSH_CMD_FLUSH /* video */)); mDeferredActions.push_back( new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode)); // After a flush without shutdown, decoder is paused. // Don't resume it until source seek is done, otherwise it could // start pulling stale data too soon. mDeferredActions.push_back( new ResumeDecoderAction(false /* needNotify */)); processDeferredActions(); break; } case kWhatPause: { if (!mStarted) { Loading Loading @@ -1675,6 +1733,7 @@ void NuPlayer2::onStart(bool play) { mRenderer->setVideoFrameRate(rate); } addEndTimeMonitor(); // Renderer is created in paused state. if (play) { mRenderer->resume(); Loading @@ -1693,6 +1752,13 @@ void NuPlayer2::onStart(bool play) { postScanSources(); } void NuPlayer2::addEndTimeMonitor() { sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this); ++mEOSMonitorGeneration; msg->setInt32("generation", mEOSMonitorGeneration); mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs); } void NuPlayer2::startPlaybackTimer(const char *where) { Mutex::Autolock autoLock(mPlayingTimeLock); if (mLastStartedPlayingTimeNs == 0) { Loading Loading @@ -2473,17 +2539,22 @@ void NuPlayer2::performPlayNextDataSource() { long previousSrcId; { Mutex::Autolock autoLock(mSourceLock); mCurrentSourceInfo.mSource = mNextSourceInfo.mSource; mNextSourceInfo.mSource = NULL; previousSrcId = mCurrentSourceInfo.mSrcId; mCurrentSourceInfo.mSrcId = mNextSourceInfo.mSrcId; ++mNextSourceInfo.mSrcId; // to distinguish the two sources. mCurrentSourceInfo = mNextSourceInfo; mNextSourceInfo = SourceInfo(); mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId; // to distinguish the two sources. } if (mDriver != NULL) { sp<NuPlayer2Driver> driver = mDriver.promote(); if (driver != NULL) { notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0); int64_t durationUs; if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) { driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs); } notifyListener( mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0); } Loading @@ -2494,6 +2565,8 @@ void NuPlayer2::performPlayNextDataSource() { mResetting = false; mSourceStarted = false; addEndTimeMonitor(); // Modular DRM if (mCrypto != NULL) { // decoders will be flushed before this so their mCrypto would go away on their own Loading Loading @@ -2589,8 +2662,9 @@ void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) { switch (what) { case Source::kWhatPrepared: { ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source: %p", mCurrentSourceInfo.mSource.get()); ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)", mCurrentSourceInfo.mSource.get(), (long long)srcId); if (srcId == mCurrentSourceInfo.mSrcId) { if (mCurrentSourceInfo.mSource == NULL) { // This is a stale notification from a source that was // asynchronously preparing when the client called reset(). Loading Loading @@ -2621,6 +2695,18 @@ void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) { } driver->notifyPrepareCompleted(srcId, err); } } else if (srcId == mNextSourceInfo.mSrcId) { if (mNextSourceInfo.mSource == NULL) { break; // stale } sp<NuPlayer2Driver> driver = mDriver.promote(); if (driver != NULL) { int32_t err; CHECK(msg->findInt32("err", &err)); driver->notifyPrepareCompleted(srcId, err); } } break; } Loading Loading @@ -2665,8 +2751,10 @@ void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) { driver->notifyListener( srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0); } if (srcId == mCurrentSourceInfo.mSrcId) { driver->notifyFlagsChanged(srcId, flags); } } if (srcId == mCurrentSourceInfo.mSrcId) { if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) Loading Loading @@ -3131,4 +3219,14 @@ NuPlayer2::SourceInfo::SourceInfo() mEndTimeUs(INT64_MAX) { } NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) { mSource = other.mSource; mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType; mSrcId = other.mSrcId; mSourceFlags = other.mSourceFlags; mStartTimeUs = other.mStartTimeUs; mEndTimeUs = other.mEndTimeUs; return *this; } } // namespace android
media/libmediaplayer2/nuplayer2/NuPlayer2.h +7 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ struct NuPlayer2 : public AHandler { int64_t seekTimeUs, MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC, bool needNotify = false); void rewind(); status_t setVideoScalingMode(int32_t mode); status_t getTrackInfo(PlayerMessage* reply) const; Loading Loading @@ -154,6 +155,8 @@ private: kWhatSetBufferingSettings = 'sBuS', kWhatPrepareDrm = 'pDrm', kWhatReleaseDrm = 'rDrm', kWhatRewind = 'reWd', kWhatEOSMonitor = 'eosM', }; typedef enum { Loading @@ -167,6 +170,7 @@ private: struct SourceInfo { SourceInfo(); SourceInfo &operator=(const SourceInfo &); sp<Source> mSource; std::atomic<DATA_SOURCE_TYPE> mDataSourceType; Loading Loading @@ -194,6 +198,7 @@ private: int32_t mAudioDecoderGeneration; int32_t mVideoDecoderGeneration; int32_t mRendererGeneration; int32_t mEOSMonitorGeneration; Mutex mPlayingTimeLock; int64_t mLastStartedPlayingTimeNs; Loading Loading @@ -302,6 +307,8 @@ private: void notifyListener(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in = NULL); void addEndTimeMonitor(); void handleFlushComplete(bool audio, bool isDecoder); void finishFlushIfPossible(); Loading
media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -298,7 +298,7 @@ status_t NuPlayer2Driver::start_l() { case STATE_RUNNING: { if (mAtEOS) { mPlayer->seekToAsync(0); mPlayer->rewind(); mAtEOS = false; mPositionUs = -1; } Loading Loading @@ -859,7 +859,7 @@ void NuPlayer2Driver::notifyListener_l( } } if (mLooping || mAutoLoop) { mPlayer->seekToAsync(0); mPlayer->rewind(); if (mAudioSink != NULL) { // The renderer has stopped the sink at the end in order to play out // the last little bit of audio. In looping mode, we need to restart it. Loading
media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -1563,6 +1563,7 @@ void NuPlayer2::Renderer::onFlush(const sp<AMessage> &msg) { } else { notifyComplete = mNotifyCompleteVideo; mNotifyCompleteVideo = false; mVideoRenderingStarted = false; } // If we're currently syncing the queues, i.e. dropping audio while Loading