зеркало из https://github.com/mozilla/gecko-dev.git
Bug 623637 - Initiate media buffering when decode hits end of downloaded data, rather than when they're close. r=roc a=roc
This commit is contained in:
Родитель
5e9829c7c7
Коммит
84b8ab4f74
|
@ -303,6 +303,8 @@ public:
|
|||
// with the decode monitor held. Called on the state machine thread and
|
||||
// the main thread.
|
||||
virtual void StartBuffering() = 0;
|
||||
|
||||
virtual void NotifyDataExhausted() = 0;
|
||||
};
|
||||
|
||||
class nsBuiltinDecoder : public nsMediaDecoder
|
||||
|
@ -367,6 +369,10 @@ class nsBuiltinDecoder : public nsMediaDecoder
|
|||
// from the resource.
|
||||
void NotifyBytesConsumed(PRInt64 aBytes);
|
||||
|
||||
void NotifyDataExhausted() {
|
||||
mDecoderStateMachine->NotifyDataExhausted();
|
||||
}
|
||||
|
||||
// Called when the video file has completed downloading.
|
||||
// Call on the main thread only.
|
||||
void ResourceLoaded();
|
||||
|
|
|
@ -901,7 +901,23 @@ PRBool nsBuiltinDecoderStateMachine::IsDecodeCloseToDownload()
|
|||
double threshold = (bufferTarget > 0 && length != -1) ?
|
||||
(length / (bufferTarget)) : LIVE_BUFFER_MARGIN;
|
||||
return (downloadPos - decodePos) < threshold;
|
||||
}
|
||||
}
|
||||
|
||||
void nsBuiltinDecoderStateMachine::NotifyDataExhausted()
|
||||
{
|
||||
MonitorAutoEnter mon(mDecoder->GetMonitor());
|
||||
nsMediaStream* stream = mDecoder->GetCurrentStream();
|
||||
NS_ASSERTION(!stream->IsDataCachedToEndOfStream(mDecoder->mDecoderPosition),
|
||||
"We shouldn't be notified in this case!");
|
||||
if (mDecoder->GetState() == nsBuiltinDecoder::PLAY_STATE_PLAYING &&
|
||||
mState == DECODER_STATE_DECODING &&
|
||||
!stream->IsSuspended())
|
||||
{
|
||||
// Our decode has caught up with the download. Let's buffer to make sure
|
||||
// we can play a decent amount of video in the future.
|
||||
StartBuffering();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsBuiltinDecoderStateMachine::Run()
|
||||
{
|
||||
|
@ -991,17 +1007,6 @@ nsresult nsBuiltinDecoderStateMachine::Run()
|
|||
|
||||
if (mState != DECODER_STATE_DECODING)
|
||||
continue;
|
||||
|
||||
if (IsDecodeCloseToDownload() &&
|
||||
mDecoder->GetState() == nsBuiltinDecoder::PLAY_STATE_PLAYING &&
|
||||
!stream->IsDataCachedToEndOfStream(mDecoder->mDecoderPosition) &&
|
||||
!stream->IsSuspended())
|
||||
{
|
||||
// We're low on decoded data, and/or our decode has caught up with
|
||||
// the download. Let's buffer to make sure we can play a decent
|
||||
// amount of video in the future.
|
||||
StartBuffering();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1107,6 +1112,11 @@ nsresult nsBuiltinDecoderStateMachine::Run()
|
|||
|
||||
case DECODER_STATE_BUFFERING:
|
||||
{
|
||||
if (IsPlaying()) {
|
||||
StopPlayback(AUDIO_PAUSE);
|
||||
mDecoder->GetMonitor().NotifyAll();
|
||||
}
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
if (mBufferingEndOffset == -1) {
|
||||
// This is the first time we've entered the buffering state.
|
||||
|
@ -1479,10 +1489,6 @@ void nsBuiltinDecoderStateMachine::LoadMetadata()
|
|||
void nsBuiltinDecoderStateMachine::StartBuffering()
|
||||
{
|
||||
mDecoder->GetMonitor().AssertCurrentThreadIn();
|
||||
if (IsPlaying()) {
|
||||
StopPlayback(AUDIO_PAUSE);
|
||||
mDecoder->GetMonitor().NotifyAll();
|
||||
}
|
||||
|
||||
// We need to tell the element that buffering has started.
|
||||
// We can't just directly send an asynchronous runnable that
|
||||
|
|
|
@ -250,6 +250,8 @@ public:
|
|||
return mEndTime;
|
||||
}
|
||||
|
||||
void NotifyDataExhausted();
|
||||
|
||||
protected:
|
||||
|
||||
// Returns PR_TRUE if the decode is withing an estimated one tenth of a
|
||||
|
|
|
@ -286,6 +286,11 @@ public:
|
|||
// to buffer, given the current download and playback rates.
|
||||
PRBool CanPlayThrough();
|
||||
|
||||
// Called by the nsMediaStream when a read on the stream by the decoder
|
||||
// is about to block due to insuffient data. Decoders may want to pause
|
||||
// playback and go into buffering mode when this is called.
|
||||
virtual void NotifyDataExhausted() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
// Start timer to update download progress information.
|
||||
|
|
|
@ -571,6 +571,15 @@ nsresult nsMediaChannelStream::Read(char* aBuffer,
|
|||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
|
||||
|
||||
PRInt64 pos = Tell();
|
||||
PRInt64 endOfRead = pos + aCount;
|
||||
if (endOfRead > mCacheStream.GetCachedDataEnd(pos) &&
|
||||
!IsDataCachedToEndOfStream(pos)) {
|
||||
// Our read will almost certainly block waiting for more data to download.
|
||||
// Notify the decoder, so it can move to buffering state if need be.
|
||||
mDecoder->NotifyDataExhausted();
|
||||
}
|
||||
|
||||
return mCacheStream.Read(aBuffer, aCount, aBytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ function ended(evt) {
|
|||
|
||||
function startTest(test, token) {
|
||||
var v = document.createElement('video');
|
||||
v.token = v;
|
||||
manager.started(v);
|
||||
v.token = token;
|
||||
manager.started(v.token);
|
||||
v.src = test.name;
|
||||
v._name = test.name;
|
||||
v._finished = false;
|
||||
|
|
|
@ -244,6 +244,7 @@ class nsWaveDecoder : public nsMediaDecoder
|
|||
|
||||
virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {}
|
||||
|
||||
void NotifyDataExhausted() {}
|
||||
private:
|
||||
// Notifies the element that seeking has started.
|
||||
void SeekingStarted();
|
||||
|
|
Загрузка…
Ссылка в новой задаче