diff options
Diffstat (limited to 'media/libmediaplayerservice')
6 files changed, 58 insertions, 30 deletions
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 5e7b644..88a7745 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -1510,17 +1510,7 @@ void NuPlayer::GenericSource::readBuffer( mVideoTimeUs = timeUs; } - // formatChange && seeking: track whose source is changed during selection - // formatChange && !seeking: track whose source is not changed during selection - // !formatChange: normal seek - if ((seeking || formatChange) - && (trackType == MEDIA_TRACK_TYPE_AUDIO - || trackType == MEDIA_TRACK_TYPE_VIDEO)) { - ATSParser::DiscontinuityType type = (formatChange && seeking) - ? ATSParser::DISCONTINUITY_FORMATCHANGE - : ATSParser::DISCONTINUITY_NONE; - track->mPackets->queueDiscontinuity( type, NULL, true /* discard */); - } + queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track); sp<ABuffer> buffer = mediaBufferToABuffer( mbuf, trackType, seekTimeUs, actualTimeUs); @@ -1538,10 +1528,26 @@ void NuPlayer::GenericSource::readBuffer( false /* discard */); #endif } else { + queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track); track->mPackets->signalEOS(err); break; } } } +void NuPlayer::GenericSource::queueDiscontinuityIfNeeded( + bool seeking, bool formatChange, media_track_type trackType, Track *track) { + // formatChange && seeking: track whose source is changed during selection + // formatChange && !seeking: track whose source is not changed during selection + // !formatChange: normal seek + if ((seeking || formatChange) + && (trackType == MEDIA_TRACK_TYPE_AUDIO + || trackType == MEDIA_TRACK_TYPE_VIDEO)) { + ATSParser::DiscontinuityType type = (formatChange && seeking) + ? ATSParser::DISCONTINUITY_FORMATCHANGE + : ATSParser::DISCONTINUITY_NONE; + track->mPackets->queueDiscontinuity(type, NULL /* extra */, true /* discard */); + } +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index 7fab051..0a75e4c 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -200,6 +200,9 @@ private: media_track_type trackType, int64_t seekTimeUs = -1ll, int64_t *actualTimeUs = NULL, bool formatChange = false); + void queueDiscontinuityIfNeeded( + bool seeking, bool formatChange, media_track_type trackType, Track *track); + void schedulePollBuffering(); void cancelPollBuffering(); void restartPollBuffering(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 87074f0..a79858c 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1153,6 +1153,22 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d", (long long)seekTimeUs, needNotify); + if (!mStarted) { + // Seek before the player is started. In order to preview video, + // need to start the player and pause it. This branch is called + // only once if needed. After the player is started, any seek + // operation will go through normal path. + // All cases, including audio-only, are handled in the same way + // for the sake of simplicity. + onStart(seekTimeUs); + onPause(); + mPausedByClient = true; + if (needNotify) { + notifyDriverSeekComplete(); + } + break; + } + mDeferredActions.push_back( new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, FLUSH_CMD_FLUSH /* video */)); @@ -1246,13 +1262,16 @@ status_t NuPlayer::onInstantiateSecureDecoders() { return OK; } -void NuPlayer::onStart() { +void NuPlayer::onStart(int64_t startPositionUs) { mOffloadAudio = false; mAudioEOS = false; mVideoEOS = false; mStarted = true; mSource->start(); + if (startPositionUs > 0) { + performSeek(startPositionUs); + } uint32_t flags = 0; @@ -1908,11 +1927,15 @@ void NuPlayer::performResumeDecoders(bool needNotify) { void NuPlayer::finishResume() { if (mResumePending) { mResumePending = false; - if (mDriver != NULL) { - sp<NuPlayerDriver> driver = mDriver.promote(); - if (driver != NULL) { - driver->notifySeekComplete(); - } + notifyDriverSeekComplete(); + } +} + +void NuPlayer::notifyDriverSeekComplete() { + if (mDriver != NULL) { + sp<NuPlayerDriver> driver = mDriver.promote(); + if (driver != NULL) { + driver->notifySeekComplete(); } } } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index f417f48..d7aa830 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -233,7 +233,7 @@ private: void handleFlushComplete(bool audio, bool isDecoder); void finishFlushIfPossible(); - void onStart(); + void onStart(int64_t startPositionUs = -1); void onResume(); void onPause(); @@ -242,6 +242,7 @@ private: void flushDecoder(bool audio, bool needShutdown); void finishResume(); + void notifyDriverSeekComplete(); void postScanSources(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 73f8ba8..6abc81c 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -415,6 +415,11 @@ bool NuPlayer::Decoder::handleAnInputBuffer(size_t index) { sp<ABuffer> buffer; mCodec->getInputBuffer(index, &buffer); + if (buffer == NULL) { + handleError(UNKNOWN_ERROR); + return false; + } + if (index >= mInputBuffers.size()) { for (size_t i = mInputBuffers.size(); i <= index; ++i) { mInputBuffers.add(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 231f2e1..84ae25e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -397,23 +397,13 @@ status_t NuPlayerDriver::seekTo(int msec) { switch (mState) { case STATE_PREPARED: case STATE_STOPPED_AND_PREPARED: - { + case STATE_PAUSED: mStartupSeekTimeUs = seekTimeUs; - // pretend that the seek completed. It will actually happen when starting playback. - // TODO: actually perform the seek here, so the player is ready to go at the new - // location - notifySeekComplete_l(); - break; - } - + // fall through. case STATE_RUNNING: - case STATE_PAUSED: { mAtEOS = false; mSeekInProgress = true; - if (mState == STATE_PAUSED) { - mStartupSeekTimeUs = seekTimeUs; - } // seeks can take a while, so we essentially paused notifyListener_l(MEDIA_PAUSED); mPlayer->seekToAsync(seekTimeUs, true /* needNotify */); |