mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 935118 - Allow buffering to be triggered when we're low on decoded audio or video. r=roc
This commit is contained in:
parent
ad54eee5af
commit
0523044e79
@ -961,7 +961,7 @@ MediaDecoder::GetStatistics()
|
||||
double MediaDecoder::ComputePlaybackRate(bool* aReliable)
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread());
|
||||
MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread() || OnDecodeThread());
|
||||
|
||||
int64_t length = mResource ? mResource->GetLength() : -1;
|
||||
if (mDuration >= 0 && length >= 0) {
|
||||
|
@ -1829,52 +1829,44 @@ bool MediaDecoderStateMachine::HasLowDecodedData(int64_t aAudioUsecs) const
|
||||
AssertCurrentThreadInMonitor();
|
||||
// We consider ourselves low on decoded data if we're low on audio,
|
||||
// provided we've not decoded to the end of the audio stream, or
|
||||
// if we're only playing video and we're low on video frames, provided
|
||||
// if we're low on video frames, provided
|
||||
// we've not decoded to the end of the video stream.
|
||||
return ((HasAudio() &&
|
||||
!mReader->AudioQueue().IsFinished() &&
|
||||
AudioDecodedUsecs() < aAudioUsecs)
|
||||
||
|
||||
(!HasAudio() &&
|
||||
HasVideo() &&
|
||||
(HasVideo() &&
|
||||
!mReader->VideoQueue().IsFinished() &&
|
||||
static_cast<uint32_t>(mReader->VideoQueue().GetSize()) < LOW_VIDEO_FRAMES));
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::HasLowUndecodedData() const
|
||||
{
|
||||
return GetUndecodedData() < mLowDataThresholdUsecs;
|
||||
return HasLowUndecodedData(mLowDataThresholdUsecs);
|
||||
}
|
||||
|
||||
int64_t MediaDecoderStateMachine::GetUndecodedData() const
|
||||
bool MediaDecoderStateMachine::HasLowUndecodedData(double aUsecs) const
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
NS_ASSERTION(mState > DECODER_STATE_DECODING_METADATA,
|
||||
"Must have loaded metadata for GetBuffered() to work");
|
||||
TimeRanges buffered;
|
||||
|
||||
nsresult res = mDecoder->GetBuffered(&buffered);
|
||||
NS_ENSURE_SUCCESS(res, 0);
|
||||
double currentTime = GetCurrentTime();
|
||||
|
||||
nsIDOMTimeRanges* r = static_cast<nsIDOMTimeRanges*>(&buffered);
|
||||
uint32_t length = 0;
|
||||
res = r->GetLength(&length);
|
||||
NS_ENSURE_SUCCESS(res, 0);
|
||||
|
||||
for (uint32_t index = 0; index < length; ++index) {
|
||||
double start, end;
|
||||
res = r->Start(index, &start);
|
||||
NS_ENSURE_SUCCESS(res, 0);
|
||||
|
||||
res = r->End(index, &end);
|
||||
NS_ENSURE_SUCCESS(res, 0);
|
||||
|
||||
if (start <= currentTime && end >= currentTime) {
|
||||
return static_cast<int64_t>((end - currentTime) * USECS_PER_S);
|
||||
}
|
||||
bool reliable;
|
||||
double bytesPerSecond = mDecoder->ComputePlaybackRate(&reliable);
|
||||
if (!reliable) {
|
||||
// Default to assuming we have enough
|
||||
return false;
|
||||
}
|
||||
return 0;
|
||||
|
||||
MediaResource* stream = mDecoder->GetResource();
|
||||
int64_t currentPos = stream->Tell();
|
||||
int64_t requiredPos = currentPos + int64_t((aUsecs/1000000.0)*bytesPerSecond);
|
||||
int64_t length = stream->GetLength();
|
||||
if (length >= 0) {
|
||||
requiredPos = std::min(requiredPos, length);
|
||||
}
|
||||
|
||||
return stream->GetCachedDataEnd(currentPos) < requiredPos;
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::SetFrameBufferLength(uint32_t aLength)
|
||||
@ -2282,14 +2274,13 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
if ((isLiveStream || !mDecoder->CanPlayThrough()) &&
|
||||
elapsed < TimeDuration::FromSeconds(mBufferingWait * mPlaybackRate) &&
|
||||
(mQuickBuffering ? HasLowDecodedData(QUICK_BUFFERING_LOW_DATA_USECS)
|
||||
: (GetUndecodedData() < mBufferingWait * mPlaybackRate * USECS_PER_S)) &&
|
||||
: HasLowUndecodedData(mBufferingWait * USECS_PER_S)) &&
|
||||
!mDecoder->IsDataCachedToEndOfResource() &&
|
||||
!resource->IsSuspended())
|
||||
{
|
||||
LOG(PR_LOG_DEBUG,
|
||||
("%p Buffering: %.3lfs/%ds, timeout in %.3lfs %s",
|
||||
("%p Buffering: wait %ds, timeout in %.3lfs %s",
|
||||
mDecoder.get(),
|
||||
GetUndecodedData() / static_cast<double>(USECS_PER_S),
|
||||
mBufferingWait,
|
||||
mBufferingWait - elapsed.ToSeconds(),
|
||||
(mQuickBuffering ? "(quick exit)" : "")));
|
||||
@ -2528,15 +2519,15 @@ void MediaDecoderStateMachine::AdvanceFrame()
|
||||
mDecoder->GetState() == MediaDecoder::PLAY_STATE_PLAYING &&
|
||||
HasLowDecodedData(remainingTime + EXHAUSTED_DATA_MARGIN_USECS) &&
|
||||
!mDecoder->IsDataCachedToEndOfResource() &&
|
||||
!resource->IsSuspended() &&
|
||||
(JustExitedQuickBuffering() || HasLowUndecodedData()))
|
||||
{
|
||||
if (currentFrame) {
|
||||
mReader->VideoQueue().PushFront(currentFrame.forget());
|
||||
!resource->IsSuspended()) {
|
||||
if (JustExitedQuickBuffering() || HasLowUndecodedData()) {
|
||||
if (currentFrame) {
|
||||
mReader->VideoQueue().PushFront(currentFrame.forget());
|
||||
}
|
||||
StartBuffering();
|
||||
ScheduleStateMachine();
|
||||
return;
|
||||
}
|
||||
StartBuffering();
|
||||
ScheduleStateMachine();
|
||||
return;
|
||||
}
|
||||
|
||||
// We've got enough data to keep playing until at least the next frame.
|
||||
|
@ -394,9 +394,8 @@ private:
|
||||
// The decoder monitor must be held.
|
||||
bool HasLowUndecodedData() const;
|
||||
|
||||
// Returns the number of microseconds of undecoded data available for
|
||||
// decoding. The decoder monitor must be held.
|
||||
int64_t GetUndecodedData() const;
|
||||
// Returns true if we have less than aUsecs of undecoded data available.
|
||||
bool HasLowUndecodedData(double aUsecs) const;
|
||||
|
||||
// Returns the number of unplayed usecs of audio we've got decoded and/or
|
||||
// pushed to the hardware waiting to play. This is how much audio we can
|
||||
|
Loading…
Reference in New Issue
Block a user