void NuPlayer::RTSPSource::onPollBuffering() { bool prepared, underflow, overflow, startServer, finished; checkBuffering(&prepared, &underflow, &overflow, &startServer, &finished); if (prepared && mInPreparationPhase) { mInPreparationPhase = false; notifyPrepared(); } if (!mInPreparationPhase && underflow) { startBufferingIfNecessary(); } if (haveSufficientDataOnAllTracks()) { stopBufferingIfNecessary(); } if (overflow && mHandler != NULL) { mHandler->pause(); } if (startServer && mHandler != NULL) { mHandler->resume(); } if (finished && mHandler != NULL) { mHandler->cancelAccessUnitTimeoutCheck(); } schedulePollBuffering(); }
bool NuPlayer::RTSPSource::stopBufferingIfNecessary() { Mutex::Autolock _l(mBufferingLock); if (mBuffering) { if (!haveSufficientDataOnAllTracks()) { return false; } mBuffering = false; sp<AMessage> notify = dupNotify(); notify->setInt32("what", kWhatResumeOnBufferingEnd); notify->post(); } return true; }
status_t NuPlayer::RTSPSource::dequeueAccessUnit( bool audio, sp<ABuffer> *accessUnit) { if (mBuffering) { if (!haveSufficientDataOnAllTracks()) { return -EWOULDBLOCK; } mBuffering = false; sp<AMessage> notify = dupNotify(); notify->setInt32("what", kWhatBufferingEnd); notify->post(); } sp<AnotherPacketSource> source = getSource(audio); if (source == NULL) { return -EWOULDBLOCK; } status_t finalResult; if (!source->hasBufferAvailable(&finalResult)) { if (finalResult == OK) { int64_t mediaDurationUs = 0; getDuration(&mediaDurationUs); sp<AnotherPacketSource> otherSource = getSource(!audio); status_t otherFinalResult; // If other source already signaled EOS, this source should also signal EOS if (otherSource != NULL && !otherSource->hasBufferAvailable(&otherFinalResult) && otherFinalResult == ERROR_END_OF_STREAM) { source->signalEOS(ERROR_END_OF_STREAM); return ERROR_END_OF_STREAM; } // If this source has detected near end, give it some time to retrieve more // data before signaling EOS if (source->isFinished(mediaDurationUs)) { int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo; if (eosTimeout == 0) { setEOSTimeout(audio, ALooper::GetNowUs()); } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) { setEOSTimeout(audio, 0); source->signalEOS(ERROR_END_OF_STREAM); return ERROR_END_OF_STREAM; } return -EWOULDBLOCK; } if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) { // We should not enter buffering mode // if any of the sources already have detected EOS. mBuffering = true; sp<AMessage> notify = dupNotify(); notify->setInt32("what", kWhatBufferingStart); notify->post(); } return -EWOULDBLOCK; } return finalResult; } setEOSTimeout(audio, 0); return source->dequeueAccessUnit(accessUnit); }