Bug 877461. Part 3: Retry libstagefright audio/video decoding if it fails due to a timeout. r=sotaro

This commit is contained in:
Robert O'Callahan 2013-06-06 11:43:43 +12:00
parent cbb523d07c
commit 1465637e4d
2 changed files with 24 additions and 11 deletions

View file

@ -140,6 +140,11 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
return false; return false;
} }
// Ignore empty buffer which stagefright media read will sporadically return
if (frame.mSize == 0 && !frame.mGraphicBuffer) {
return true;
}
parsed++; parsed++;
if (frame.mShouldSkip && mSkipCount < MAX_DROPPED_FRAMES) { if (frame.mShouldSkip && mSkipCount < MAX_DROPPED_FRAMES) {
mSkipCount++; mSkipCount++;

View file

@ -561,11 +561,15 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
mIsVideoSeeking = false; mIsVideoSeeking = false;
ReleaseAllPendingVideoBuffersLocked(); ReleaseAllPendingVideoBuffersLocked();
} }
aDoSeek = false;
} else { } else {
err = mVideoSource->read(&mVideoBuffer); err = mVideoSource->read(&mVideoBuffer);
} }
if (err == OK && mVideoBuffer->range_length() > 0) { aFrame->mSize = 0;
if (err == OK) {
int64_t timeUs; int64_t timeUs;
int32_t unreadable; int32_t unreadable;
int32_t keyFrame; int32_t keyFrame;
@ -602,7 +606,7 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
aFrame->mKeyFrame = keyFrame; aFrame->mKeyFrame = keyFrame;
aFrame->Y.mWidth = mVideoWidth; aFrame->Y.mWidth = mVideoWidth;
aFrame->Y.mHeight = mVideoHeight; aFrame->Y.mHeight = mVideoHeight;
} else { } else if (mVideoBuffer->range_length() > 0) {
char *data = static_cast<char *>(mVideoBuffer->data()) + mVideoBuffer->range_offset(); char *data = static_cast<char *>(mVideoBuffer->data()) + mVideoBuffer->range_offset();
size_t length = mVideoBuffer->range_length(); size_t length = mVideoBuffer->range_length();
@ -618,7 +622,6 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
if (aKeyframeSkip && timeUs < aTimeUs) { if (aKeyframeSkip && timeUs < aTimeUs) {
aFrame->mShouldSkip = true; aFrame->mShouldSkip = true;
} }
} }
else if (err == INFO_FORMAT_CHANGED) { else if (err == INFO_FORMAT_CHANGED) {
// If the format changed, update our cached info. // If the format changed, update our cached info.
@ -631,12 +634,14 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
else if (err == ERROR_END_OF_STREAM) { else if (err == ERROR_END_OF_STREAM) {
return false; return false;
} }
else if (err == UNKNOWN_ERROR) { else if (err == -ETIMEDOUT) {
// This sometimes is used to mean "out of memory", but regardless, LOG(PR_LOG_DEBUG, "OmxDecoder::ReadVideo timed out, will retry");
// don't keep trying to decode if the decoder doesn't want to. return true;
return false;
} }
else if (err != OK && err != -ETIMEDOUT) { else {
// UNKNOWN_ERROR is sometimes is used to mean "out of memory", but
// regardless, don't keep trying to decode if the decoder doesn't want to.
LOG(PR_LOG_DEBUG, "OmxDecoder::ReadVideo failed, err=%d", err);
return false; return false;
} }
@ -664,6 +669,7 @@ bool OmxDecoder::ReadAudio(AudioFrame *aFrame, int64_t aSeekTimeUs)
mAudioMetadataRead = false; mAudioMetadataRead = false;
aSeekTimeUs = -1; aSeekTimeUs = -1;
aFrame->mSize = 0;
if (err == OK && mAudioBuffer && mAudioBuffer->range_length() != 0) { if (err == OK && mAudioBuffer && mAudioBuffer->range_length() != 0) {
int64_t timeUs; int64_t timeUs;
@ -689,10 +695,12 @@ bool OmxDecoder::ReadAudio(AudioFrame *aFrame, int64_t aSeekTimeUs)
return false; return false;
} }
} }
else if (err == UNKNOWN_ERROR) { else if (err == -ETIMEDOUT) {
return false; LOG(PR_LOG_DEBUG, "OmxDecoder::ReadAudio timed out, will retry");
return true;
} }
else if (err != OK && err != -ETIMEDOUT) { else if (err != OK) {
LOG(PR_LOG_DEBUG, "OmxDecoder::ReadAudio failed, err=%d", err);
return false; return false;
} }