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:
@@ -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;
|
||||
|
||||
@@ -132,6 +132,7 @@ private:
|
||||
PortStatus mPortStatus[2];
|
||||
bool mInitialBufferSubmit;
|
||||
bool mSignalledEOS;
|
||||
status_t mFinalStatus;
|
||||
bool mNoMoreOutputData;
|
||||
bool mOutputPortSettingsHaveChanged;
|
||||
int64_t mSeekTimeUs;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user