Bug 1112445 - Ignore the audio stream when determining whether we should skip-t-o-next-keyframe for async readers. r=mattwoodrow

This commit is contained in:
Chris Pearce 2015-01-13 22:31:03 +13:00
parent 5c5fba50de
commit fd96ffc61f
5 changed files with 32 additions and 8 deletions

View File

@ -243,6 +243,12 @@ public:
mDecoder = nullptr;
}
// Returns true if the reader implements RequestAudioData()
// and RequestVideoData() asynchronously, rather than using the
// implementation in this class to adapt the old synchronous to
// the newer async model.
virtual bool IsAsync() const { return false; }
protected:
virtual ~MediaDecoderReader();

View File

@ -612,15 +612,20 @@ MediaDecoderStateMachine::NeedToSkipToNextKeyframe()
// data to decode. If we're running low on downloaded data to decode,
// we won't start keyframe skipping, as we'll be pausing playback to buffer
// soon anyway and we'll want to be able to display frames immediately
// after buffering finishes.
bool isLowOnDecodedAudio = !mIsAudioPrerolling && IsAudioDecoding() &&
// after buffering finishes. We ignore the low audio calculations for
// readers that are async, as since their audio decode runs on a different
// task queue it should never run low and skipping won't help their decode.
bool isLowOnDecodedAudio = !mReader->IsAsync() &&
!mIsAudioPrerolling && IsAudioDecoding() &&
(GetDecodedAudioDuration() <
mLowAudioThresholdUsecs * mPlaybackRate);
bool isLowOnDecodedVideo = !mIsVideoPrerolling &&
(mDecodedVideoEndTime - GetClock() <
LOW_VIDEO_THRESHOLD_USECS * mPlaybackRate);
if ((isLowOnDecodedAudio || isLowOnDecodedVideo) && !HasLowUndecodedData()) {
DECODER_LOG("Skipping video decode to the next keyframe");
bool lowUndecoded = HasLowUndecodedData();
if ((isLowOnDecodedAudio || isLowOnDecodedVideo) && !lowUndecoded) {
DECODER_LOG("Skipping video decode to the next keyframe lowAudio=%d lowVideo=%d lowUndecoded=%d async=%d",
isLowOnDecodedAudio, isLowOnDecodedVideo, lowUndecoded, mReader->IsAsync());
return true;
}
@ -994,10 +999,14 @@ MediaDecoderStateMachine::OnVideoDecoded(VideoData* aVideoSample)
StopPrerollingVideo();
}
// If the requested video sample was slow to arrive, increase the
// amount of audio we buffer to ensure that we don't run out of audio.
// TODO: Detect when we're truly async, and don't do this if so, as
// it's not necessary.
// For non async readers, if the requested video sample was slow to
// arrive, increase the amount of audio we buffer to ensure that we
// don't run out of audio. This is unnecessary for async readers,
// since they decode audio and video on different threads so they
// are unlikely to run out of decoded audio.
if (mReader->IsAsync()) {
return;
}
TimeDuration decodeTime = TimeStamp::Now() - mVideoDecodeStartTime;
if (THRESHOLD_FACTOR * DurationToUsecs(decodeTime) > mLowAudioThresholdUsecs &&
!HasLowUndecodedData())

View File

@ -82,6 +82,8 @@ public:
virtual nsRefPtr<ShutdownPromise> Shutdown() MOZ_OVERRIDE;
virtual bool IsAsync() const MOZ_OVERRIDE { return true; }
private:
bool InitDemuxer();

View File

@ -130,6 +130,11 @@ public:
nsresult SetCDMProxy(CDMProxy* aProxy);
#endif
virtual bool IsAsync() const MOZ_OVERRIDE {
return (!mAudioReader || mAudioReader->IsAsync()) &&
(!mVideoReader || mVideoReader->IsAsync());
}
private:
// Switch the current audio/video reader to the reader that
// contains aTarget (or up to aError after target). Both

View File

@ -110,6 +110,8 @@ public:
virtual android::sp<android::MediaSource> GetAudioOffloadTrack();
virtual bool IsAsync() const MOZ_OVERRIDE { return true; }
protected:
struct TrackInputCopier
{