Propagate errors all the way through the MediaSources and send either MEDIA_PLAYBACK_COMPLETE or MEDIA_ERROR depending on the final reason for running out of buffers to play back.

related-to-bug: 2463749
This commit is contained in:
Andreas Huber
2010-02-23 13:45:33 -08:00
parent 80bd6a1637
commit d7d22eba3c
8 changed files with 42 additions and 11 deletions

View File

@@ -61,7 +61,7 @@ public:
status_t seekTo(int64_t time_us);
bool isSeeking();
bool reachedEOS();
bool reachedEOS(status_t *finalStatus);
private:
sp<MediaSource> mSource;
@@ -81,6 +81,7 @@ private:
bool mSeeking;
bool mReachedEOS;
status_t mFinalStatus;
int64_t mSeekTimeUs;
bool mStarted;

View File

@@ -132,6 +132,7 @@ private:
PortStatus mPortStatus[2];
bool mInitialBufferSubmit;
bool mSignalledEOS;
status_t mFinalStatus;
bool mNoMoreOutputData;
bool mOutputPortSettingsHaveChanged;
int64_t mSeekTimeUs;

View File

@@ -38,6 +38,7 @@ AudioPlayer::AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink)
mPositionTimeRealUs(-1),
mSeeking(false),
mReachedEOS(false),
mFinalStatus(OK),
mStarted(false),
mAudioSink(audioSink) {
}
@@ -168,6 +169,7 @@ void AudioPlayer::stop() {
mPositionTimeRealUs = -1;
mSeeking = false;
mReachedEOS = false;
mFinalStatus = OK;
mStarted = false;
}
@@ -181,8 +183,11 @@ bool AudioPlayer::isSeeking() {
return mSeeking;
}
bool AudioPlayer::reachedEOS() {
bool AudioPlayer::reachedEOS(status_t *finalStatus) {
*finalStatus = OK;
Mutex::Autolock autoLock(mLock);
*finalStatus = mFinalStatus;
return mReachedEOS;
}
@@ -245,6 +250,7 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) {
if (err != OK) {
mReachedEOS = true;
mFinalStatus = err;
break;
}

View File

@@ -434,14 +434,22 @@ void AwesomePlayer::onStreamDone() {
}
mStreamDoneEventPending = false;
if (mFlags & LOOPING) {
if (mStreamDoneStatus == ERROR_END_OF_STREAM && (mFlags & LOOPING)) {
seekTo_l(0);
if (mVideoSource != NULL) {
postVideoEvent_l();
}
} else {
notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
if (mStreamDoneStatus == ERROR_END_OF_STREAM) {
LOGV("MEDIA_PLAYBACK_COMPLETE");
notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
} else {
LOGV("MEDIA_ERROR %d", mStreamDoneStatus);
notifyListener_l(
MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
}
pause_l();
@@ -802,7 +810,7 @@ void AwesomePlayer::onVideoEvent() {
continue;
}
postStreamDoneEvent_l();
postStreamDoneEvent_l(err);
return;
}
@@ -904,11 +912,13 @@ void AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
}
void AwesomePlayer::postStreamDoneEvent_l() {
void AwesomePlayer::postStreamDoneEvent_l(status_t status) {
if (mStreamDoneEventPending) {
return;
}
mStreamDoneEventPending = true;
mStreamDoneStatus = status;
mQueue.postEvent(mStreamDoneEvent);
}
@@ -947,9 +957,10 @@ void AwesomePlayer::onCheckAudioStatus() {
notifyListener_l(MEDIA_SEEK_COMPLETE);
}
if (mWatchForAudioEOS && mAudioPlayer->reachedEOS()) {
status_t finalStatus;
if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
mWatchForAudioEOS = false;
postStreamDoneEvent_l();
postStreamDoneEvent_l(finalStatus);
}
postCheckAudioStatusEvent_l();

View File

@@ -1450,6 +1450,14 @@ status_t MPEG4Source::read(
&sampleIndex, SampleTable::kSyncSample_Flag);
if (err != OK) {
if (err == ERROR_OUT_OF_RANGE) {
// An attempt to seek past the end of the stream would
// normally cause this ERROR_OUT_OF_RANGE error. Propagating
// this all the way to the MediaPlayer would cause abnormal
// termination. Legacy behaviour appears to be to behave as if
// we had seeked to the end of stream, ending normally.
err = ERROR_END_OF_STREAM;
}
return err;
}

View File

@@ -1933,6 +1933,7 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
CODEC_LOGV("signalling end of input stream.");
flags |= OMX_BUFFERFLAG_EOS;
mFinalStatus = err;
mSignalledEOS = true;
} else {
mNoMoreOutputData = false;
@@ -2411,7 +2412,7 @@ status_t OMXCodec::read(
}
if (mFilledBuffers.empty()) {
return ERROR_END_OF_STREAM;
return mSignalledEOS ? mFinalStatus : ERROR_END_OF_STREAM;
}
if (mOutputPortSettingsHaveChanged) {

View File

@@ -55,6 +55,7 @@ private:
size_t mIndex;
bool mStarted;
bool mReachedEOS;
status_t mFinalStatus;
int64_t mSeekTimeUs;
int64_t mCacheDurationUs;
bool mPrefetcherStopped;
@@ -306,7 +307,7 @@ status_t PrefetchedSource::read(
}
if (mCachedBuffers.empty()) {
return ERROR_END_OF_STREAM;
return mReachedEOS ? mFinalStatus : ERROR_END_OF_STREAM;
}
*out = *mCachedBuffers.begin();
@@ -353,6 +354,7 @@ void PrefetchedSource::cacheMore() {
if (err != OK) {
mReachedEOS = true;
mFinalStatus = err;
mCondition.signal();
return;

View File

@@ -145,10 +145,11 @@ private:
Condition mPreparedCondition;
bool mIsAsyncPrepare;
status_t mPrepareResult;
status_t mStreamDoneStatus;
void postVideoEvent_l(int64_t delayUs = -1);
void postBufferingEvent_l();
void postStreamDoneEvent_l();
void postStreamDoneEvent_l(status_t status);
void postCheckAudioStatusEvent_l();
status_t getPosition_l(int64_t *positionUs);
status_t play_l();