Merge "Better support for buffered streaming of rtsp content, if buffer drops below a certain threshold we will temporarily pause playback until we have sufficient data." into gingerbread

This commit is contained in:
Andreas Huber
2010-09-01 15:44:46 -07:00
committed by Android (Google) Code Review
5 changed files with 77 additions and 2 deletions

View File

@@ -457,6 +457,33 @@ void AwesomePlayer::onBufferingUpdate() {
}
mBufferingEventPending = false;
int kLowWaterMarkSecs = 2;
int kHighWaterMarkSecs = 10;
if (mRTSPController != NULL) {
bool eos;
int64_t queueDurationUs = mRTSPController->getQueueDurationUs(&eos);
LOGV("queueDurationUs = %.2f secs", queueDurationUs / 1E6);
if ((mFlags & PLAYING) && !eos
&& (queueDurationUs < kLowWaterMarkSecs * 1000000ll)) {
LOGI("rtsp cache is running low, pausing.");
mFlags |= CACHE_UNDERRUN;
pause_l();
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
} else if ((mFlags & CACHE_UNDERRUN)
&& (eos || queueDurationUs > kHighWaterMarkSecs * 1000000ll)) {
LOGI("rtsp cache has filled up, resuming.");
mFlags &= ~CACHE_UNDERRUN;
play_l();
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
}
postBufferingEvent_l();
return;
}
if (mCachedSource == NULL) {
return;
}
@@ -484,8 +511,8 @@ void AwesomePlayer::onBufferingUpdate() {
notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
lowWatermark = 2 * bitrate / 8; // 2 secs
highWatermark = 10 * bitrate / 8; // 10 secs
lowWatermark = kLowWaterMarkSecs * bitrate / 8;
highWatermark = kHighWaterMarkSecs * bitrate / 8;
}
}

View File

@@ -42,6 +42,7 @@ struct ARTSPController : public MediaExtractor {
size_t index, uint32_t flags);
int64_t getNormalPlayTimeUs();
int64_t getQueueDurationUs(bool *eos);
void onMessageReceived(const sp<AMessage> &msg);

View File

@@ -746,4 +746,27 @@ void APacketSource::setNormalPlayTimeMapping(
mNormalPlayTimeBaseUs = normalPlayTimeUs;
}
int64_t APacketSource::getQueueDurationUs(bool *eos) {
Mutex::Autolock autoLock(mLock);
*eos = (mEOSResult != OK);
if (mBuffers.size() < 2) {
return 0;
}
const sp<ABuffer> first = *mBuffers.begin();
const sp<ABuffer> last = *--mBuffers.end();
int64_t firstTimeUs;
CHECK(first->meta()->findInt64("timeUs", &firstTimeUs));
int64_t lastTimeUs;
CHECK(last->meta()->findInt64("timeUs", &lastTimeUs));
CHECK_GE(lastTimeUs, firstTimeUs);
return lastTimeUs - firstTimeUs;
}
} // namespace android

View File

@@ -50,6 +50,8 @@ struct APacketSource : public MediaSource {
void setNormalPlayTimeMapping(
uint32_t rtpTime, int64_t normalPlayTimeUs);
int64_t getQueueDurationUs(bool *eos);
protected:
virtual ~APacketSource();

View File

@@ -143,4 +143,26 @@ int64_t ARTSPController::getNormalPlayTimeUs() {
return mHandler->getNormalPlayTimeUs();
}
int64_t ARTSPController::getQueueDurationUs(bool *eos) {
*eos = true;
int64_t minQueuedDurationUs = 0;
for (size_t i = 0; i < mHandler->countTracks(); ++i) {
sp<APacketSource> source = mHandler->getPacketSource(i);
bool newEOS;
int64_t queuedDurationUs = source->getQueueDurationUs(&newEOS);
if (!newEOS) {
*eos = false;
}
if (i == 0 || queuedDurationUs < minQueuedDurationUs) {
minQueuedDurationUs = queuedDurationUs;
}
}
return minQueuedDurationUs;
}
} // namespace android