mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Back out 4 changesets (bug 1229987
) for ASan e10s timeout in test_playback.html, Mac timeouts in test_BufferingWait_mp4.html, and Win8 failures in test_WaitingToEndedTransition_mp4.html
Backed out changeset 707a87454058 (bug1229987
) Backed out changeset 37003d495f20 (bug1229987
) Backed out changeset c8f4e1eaf884 (bug1229987
) Backed out changeset 42ca05d8546d (bug1229987
)
This commit is contained in:
parent
4d21fa83d0
commit
45242f7699
@ -783,17 +783,6 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
|
||||
self->WaitRequestRef(aRejection.mType).Complete();
|
||||
}));
|
||||
|
||||
// We are out of data to decode and will enter buffering mode soon.
|
||||
// We want to play the frames we have already decoded, so we stop pre-rolling
|
||||
// and ensure that loadeddata is fired as required.
|
||||
if (isAudio) {
|
||||
StopPrerollingAudio();
|
||||
} else {
|
||||
StopPrerollingVideo();
|
||||
}
|
||||
if (mState == DECODER_STATE_BUFFERING || mState == DECODER_STATE_DECODING) {
|
||||
MaybeFinishDecodeFirstFrame();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -691,7 +691,6 @@ MediaFormatReader::NotifyWaitingForData(TrackType aTrack)
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
decoder.mWaitingForData = true;
|
||||
decoder.mNeedDraining = true;
|
||||
ScheduleUpdate(aTrack);
|
||||
}
|
||||
|
||||
@ -884,7 +883,6 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack,
|
||||
info->GetID());
|
||||
decoder.mInfo = info;
|
||||
decoder.mLastStreamSourceID = info->GetID();
|
||||
decoder.mNextStreamSourceID.reset();
|
||||
// Flush will clear our array of queued samples. So make a copy now.
|
||||
nsTArray<RefPtr<MediaRawData>> samples{decoder.mQueuedSamples};
|
||||
Flush(aTrack);
|
||||
@ -894,11 +892,38 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack,
|
||||
decoder.mQueuedSamples.AppendElements(Move(samples));
|
||||
NotifyDecodingRequested(aTrack);
|
||||
} else {
|
||||
TimeUnit seekTime =
|
||||
decoder.mTimeThreshold.refOr(TimeUnit::FromMicroseconds(sample->mTime));
|
||||
MOZ_ASSERT(decoder.mTimeThreshold.isNothing());
|
||||
LOG("Stream change occurred on a non-keyframe. Seeking to:%lld",
|
||||
seekTime.ToMicroseconds());
|
||||
InternalSeek(aTrack, seekTime);
|
||||
sample->mTime);
|
||||
decoder.mTimeThreshold = Some(TimeUnit::FromMicroseconds(sample->mTime));
|
||||
RefPtr<MediaFormatReader> self = this;
|
||||
decoder.ResetDemuxer();
|
||||
decoder.mSeekRequest.Begin(decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref())
|
||||
->Then(OwnerThread(), __func__,
|
||||
[self, aTrack] (media::TimeUnit aTime) {
|
||||
auto& decoder = self->GetDecoderData(aTrack);
|
||||
decoder.mSeekRequest.Complete();
|
||||
self->NotifyDecodingRequested(aTrack);
|
||||
},
|
||||
[self, aTrack] (DemuxerFailureReason aResult) {
|
||||
auto& decoder = self->GetDecoderData(aTrack);
|
||||
decoder.mSeekRequest.Complete();
|
||||
switch (aResult) {
|
||||
case DemuxerFailureReason::WAITING_FOR_DATA:
|
||||
self->NotifyWaitingForData(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::END_OF_STREAM:
|
||||
self->NotifyEndOfStream(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::CANCELED:
|
||||
case DemuxerFailureReason::SHUTDOWN:
|
||||
break;
|
||||
default:
|
||||
self->NotifyError(aTrack);
|
||||
break;
|
||||
}
|
||||
decoder.mTimeThreshold.reset();
|
||||
}));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -932,42 +957,6 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack,
|
||||
decoder.mInputExhausted = false;
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::InternalSeek(TrackType aTrack, const media::TimeUnit& aTime)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
decoder.mTimeThreshold = Some(aTime);
|
||||
RefPtr<MediaFormatReader> self = this;
|
||||
decoder.ResetDemuxer();
|
||||
decoder.mSeekRequest.Begin(decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref())
|
||||
->Then(OwnerThread(), __func__,
|
||||
[self, aTrack] (media::TimeUnit aTime) {
|
||||
auto& decoder = self->GetDecoderData(aTrack);
|
||||
decoder.mSeekRequest.Complete();
|
||||
self->NotifyDecodingRequested(aTrack);
|
||||
},
|
||||
[self, aTrack] (DemuxerFailureReason aResult) {
|
||||
auto& decoder = self->GetDecoderData(aTrack);
|
||||
decoder.mSeekRequest.Complete();
|
||||
switch (aResult) {
|
||||
case DemuxerFailureReason::WAITING_FOR_DATA:
|
||||
self->NotifyWaitingForData(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::END_OF_STREAM:
|
||||
self->NotifyEndOfStream(aTrack);
|
||||
break;
|
||||
case DemuxerFailureReason::CANCELED:
|
||||
case DemuxerFailureReason::SHUTDOWN:
|
||||
break;
|
||||
default:
|
||||
self->NotifyError(aTrack);
|
||||
break;
|
||||
}
|
||||
decoder.mTimeThreshold.reset();
|
||||
}));
|
||||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::DrainDecoder(TrackType aTrack)
|
||||
{
|
||||
@ -1017,8 +1006,7 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!decoder.HasPromise() && decoder.mWaitingForData &&
|
||||
!decoder.mDraining && !decoder.mNeedDraining) {
|
||||
if (!decoder.HasPromise() && decoder.mWaitingForData) {
|
||||
// Nothing more we can do at present.
|
||||
LOGV("Still waiting for data.");
|
||||
return;
|
||||
@ -1048,47 +1036,32 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||
RefPtr<MediaData> output = decoder.mOutput[0];
|
||||
decoder.mOutput.RemoveElementAt(0);
|
||||
decoder.mSizeOfQueue -= 1;
|
||||
decoder.mLastSampleTime =
|
||||
Some(media::TimeUnit::FromMicroseconds(output->GetEndTime()));
|
||||
if (decoder.mTimeThreshold.isNothing() ||
|
||||
media::TimeUnit::FromMicroseconds(output->mTime) >= decoder.mTimeThreshold.ref()) {
|
||||
ReturnOutput(output, aTrack);
|
||||
decoder.mTimeThreshold.reset();
|
||||
break;
|
||||
} else {
|
||||
LOGV("Internal Seeking: Dropping %s frame time:%f wanted:%f (kf:%d)",
|
||||
TrackTypeToStr(aTrack),
|
||||
LOGV("Internal Seeking: Dropping frame time:%f wanted:%f (kf:%d)",
|
||||
media::TimeUnit::FromMicroseconds(output->mTime).ToSeconds(),
|
||||
decoder.mTimeThreshold.ref().ToSeconds(),
|
||||
output->mKeyframe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (decoder.HasPromise() && decoder.mOutput.IsEmpty()) {
|
||||
if (decoder.mError) {
|
||||
decoder.RejectPromise(DECODE_ERROR, __func__);
|
||||
return;
|
||||
}
|
||||
if (decoder.mDrainComplete) {
|
||||
bool wasDraining = decoder.mDraining;
|
||||
} else if (decoder.mDrainComplete) {
|
||||
decoder.mDrainComplete = false;
|
||||
decoder.mDraining = false;
|
||||
if (decoder.mDemuxEOS) {
|
||||
decoder.RejectPromise(END_OF_STREAM, __func__);
|
||||
// We reached the end of the data stream. Nothing more to do.
|
||||
if (decoder.mError) {
|
||||
LOG("Decoding Error");
|
||||
decoder.RejectPromise(DECODE_ERROR, __func__);
|
||||
return;
|
||||
} else if (decoder.mDemuxEOS) {
|
||||
decoder.RejectPromise(END_OF_STREAM, __func__);
|
||||
}
|
||||
if (wasDraining && decoder.mLastSampleTime && !decoder.mNextStreamSourceID) {
|
||||
// We have completed draining the decoder following WaitingForData.
|
||||
// Set up the internal seek machinery to be able to resume from the
|
||||
// last sample decoded.
|
||||
LOG("Seeking to last sample time: %lld",
|
||||
decoder.mLastSampleTime.ref().ToMicroseconds());
|
||||
InternalSeek(aTrack, decoder.mLastSampleTime.ref());
|
||||
}
|
||||
}
|
||||
if (decoder.mWaitingForData && !decoder.mDraining && !decoder.mNeedDraining) {
|
||||
} else if (decoder.mError) {
|
||||
decoder.RejectPromise(DECODE_ERROR, __func__);
|
||||
return;
|
||||
} else if (decoder.mWaitingForData) {
|
||||
LOG("Waiting For Data");
|
||||
decoder.RejectPromise(WAITING_FOR_DATA, __func__);
|
||||
return;
|
||||
|
@ -127,8 +127,6 @@ private:
|
||||
// Decode any pending already demuxed samples.
|
||||
bool DecodeDemuxedSamples(TrackType aTrack,
|
||||
MediaRawData* aSample);
|
||||
void InternalSeek(TrackType aTrack, const media::TimeUnit& aTime);
|
||||
|
||||
// Drain the current decoder.
|
||||
void DrainDecoder(TrackType aTrack);
|
||||
void NotifyNewOutput(TrackType aTrack, MediaData* aSample);
|
||||
@ -263,11 +261,8 @@ private:
|
||||
bool mDraining;
|
||||
bool mDrainComplete;
|
||||
// If set, all decoded samples prior mTimeThreshold will be dropped.
|
||||
// Used for internal seeking when a change of stream is detected or when
|
||||
// encountering data discontinuity.
|
||||
// Used for internal seeking when a change of stream is detected.
|
||||
Maybe<media::TimeUnit> mTimeThreshold;
|
||||
// End time of last sample output.
|
||||
Maybe<media::TimeUnit> mLastSampleTime;
|
||||
|
||||
// Decoded samples returned my mDecoder awaiting being returned to
|
||||
// state machine upon request.
|
||||
@ -305,7 +300,6 @@ private:
|
||||
mDraining = false;
|
||||
mDrainComplete = false;
|
||||
mTimeThreshold.reset();
|
||||
mLastSampleTime.reset();
|
||||
mOutput.Clear();
|
||||
mNumSamplesInput = 0;
|
||||
mNumSamplesOutput = 0;
|
||||
|
@ -295,7 +295,7 @@ MediaSourceTrackDemuxer::MediaSourceTrackDemuxer(MediaSourceDemuxer* aParent,
|
||||
, mManager(aManager)
|
||||
, mType(aType)
|
||||
, mMonitor("MediaSourceTrackDemuxer")
|
||||
, mReset(true)
|
||||
, mLastSeek(Some(TimeUnit()))
|
||||
{
|
||||
}
|
||||
|
||||
@ -328,8 +328,7 @@ MediaSourceTrackDemuxer::Reset()
|
||||
RefPtr<MediaSourceTrackDemuxer> self = this;
|
||||
nsCOMPtr<nsIRunnable> task =
|
||||
NS_NewRunnableFunction([self] () {
|
||||
self->mNextSample.reset();
|
||||
self->mReset = true;
|
||||
self->mLastSeek = Some(TimeUnit());
|
||||
self->mManager->Seek(self->mType, TimeUnit(), TimeUnit());
|
||||
{
|
||||
MonitorAutoLock mon(self->mMonitor);
|
||||
@ -381,58 +380,49 @@ MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
|
||||
buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
|
||||
|
||||
if (!buffered.Contains(aTime)) {
|
||||
mLastSeek = Some(aTime);
|
||||
// We don't have the data to seek to.
|
||||
return SeekPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
|
||||
__func__);
|
||||
}
|
||||
TimeUnit seekTime =
|
||||
mManager->Seek(mType, aTime, MediaSourceDemuxer::EOS_FUZZ);
|
||||
bool error;
|
||||
RefPtr<MediaRawData> sample =
|
||||
mManager->GetSample(mType,
|
||||
media::TimeUnit(),
|
||||
error);
|
||||
MOZ_ASSERT(!error && sample);
|
||||
mNextSample = Some(sample);
|
||||
mReset = false;
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mNextRandomAccessPoint = mManager->GetNextRandomAccessPoint(mType);
|
||||
}
|
||||
mLastSeek = Some(aTime);
|
||||
return SeekPromise::CreateAndResolve(seekTime, __func__);
|
||||
}
|
||||
|
||||
RefPtr<MediaSourceTrackDemuxer::SamplesPromise>
|
||||
MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
|
||||
{
|
||||
if (mReset) {
|
||||
if (mLastSeek) {
|
||||
// If a seek (or reset) was recently performed, we ensure that the data
|
||||
// we are about to retrieve is still available.
|
||||
TimeIntervals buffered = mManager->Buffered(mType);
|
||||
buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
|
||||
|
||||
if (!buffered.Contains(TimeUnit::FromMicroseconds(0))) {
|
||||
if (!buffered.Contains(mLastSeek.ref())) {
|
||||
return SamplesPromise::CreateAndReject(
|
||||
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
|
||||
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
}
|
||||
mReset = false;
|
||||
mLastSeek.reset();
|
||||
}
|
||||
bool error = false;
|
||||
RefPtr<MediaRawData> sample;
|
||||
if (mNextSample) {
|
||||
sample = mNextSample.ref();
|
||||
mNextSample.reset();
|
||||
} else {
|
||||
sample = mManager->GetSample(mType, MediaSourceDemuxer::EOS_FUZZ, error);
|
||||
if (!sample) {
|
||||
if (error) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
}
|
||||
return SamplesPromise::CreateAndReject(
|
||||
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
|
||||
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
bool error;
|
||||
RefPtr<MediaRawData> sample =
|
||||
mManager->GetSample(mType,
|
||||
MediaSourceDemuxer::EOS_FUZZ,
|
||||
error);
|
||||
if (!sample) {
|
||||
if (error) {
|
||||
return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||
}
|
||||
return SamplesPromise::CreateAndReject(
|
||||
mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
|
||||
DemuxerFailureReason::WAITING_FOR_DATA, __func__);
|
||||
}
|
||||
RefPtr<SamplesHolder> samples = new SamplesHolder;
|
||||
samples->mSamples.AppendElement(sample);
|
||||
|
@ -129,10 +129,7 @@ private:
|
||||
// Monitor protecting members below accessed from multiple threads.
|
||||
Monitor mMonitor;
|
||||
media::TimeUnit mNextRandomAccessPoint;
|
||||
Maybe<RefPtr<MediaRawData>> mNextSample;
|
||||
// Set to true following a reset. Ensure that the next sample demuxed
|
||||
// is available at position 0.
|
||||
bool mReset;
|
||||
Maybe<media::TimeUnit> mLastSeek;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -40,9 +40,7 @@ skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac"))
|
||||
[test_BufferingWait.html]
|
||||
skip-if = toolkit == 'android' #timeout android bug 1199531
|
||||
[test_BufferingWait_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
[test_DrainOnMissingData_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
|
||||
[test_EndOfStream.html]
|
||||
skip-if = (true || toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet only bug 1101187 and bug 1182946
|
||||
[test_EndOfStream_mp4.html]
|
||||
@ -53,7 +51,7 @@ skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac"))
|
||||
[test_FrameSelection.html]
|
||||
[test_HaveMetadataUnbufferedSeek.html]
|
||||
[test_HaveMetadataUnbufferedSeek_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
|
||||
[test_LoadedDataFired_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
[test_LoadedMetadataFired.html]
|
||||
@ -100,11 +98,11 @@ skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac"))
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
[test_TruncatedDuration.html]
|
||||
[test_TruncatedDuration_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
|
||||
[test_WaitingOnMissingData.html]
|
||||
skip-if = true # Disabled due to bug 1124493 and friends. WebM MSE is deprioritized.
|
||||
[test_WaitingOnMissingData_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
|
||||
[test_WaitingToEndedTransition_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
|
||||
|
||||
|
@ -41,14 +41,18 @@ runWithMSE(function(ms, v) {
|
||||
/* Note - Missing |bipbop4| segment here corresponding to (2.41, 3.20] */
|
||||
.then(fetchAndLoad.bind(null, sb, 'bipbop/bipbop', ['5'], '.m4s'))
|
||||
.then(function() {
|
||||
var promise = waitUntilTime(1.62-1/30);
|
||||
// Some decoders (Windows in particular) may keep up to 25 frames queued
|
||||
// before returning a sample. 0.7 is 1.62s - 25 * 0.03333
|
||||
var promise = waitUntilTime(0.7);
|
||||
info("Playing video. It should play for a bit, then fire 'waiting'");
|
||||
v.play();
|
||||
return promise;
|
||||
}).then(function() {
|
||||
window.firstStop = Date.now();
|
||||
fetchAndLoad(sb, 'bipbop/bipbop', ['3'], '.m4s');
|
||||
return waitUntilTime(2.41-1/30);
|
||||
// Some decoders (Windows in particular) may keep up to 25 frames queued
|
||||
// before returning a sample. 1.5 is 2.41s - 25 * 0.03333
|
||||
return waitUntilTime(1.5);
|
||||
}).then(function() {
|
||||
var waitDuration = (Date.now() - window.firstStop) / 1000;
|
||||
ok(waitDuration < 15, "Should not spend an inordinate amount of time buffering: " + waitDuration);
|
||||
|
@ -1,60 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
|
||||
<title>MSE: |waiting| event when source data is missing</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test"><script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
runWithMSE(function(ms, el) {
|
||||
el.controls = true;
|
||||
once(ms, 'sourceopen').then(function() {
|
||||
ok(true, "Receive a sourceopen event");
|
||||
var videosb = ms.addSourceBuffer("video/mp4");
|
||||
fetchAndLoad(videosb, 'bipbop/bipbop_video', ['init'], '.mp4')
|
||||
.then(function() {
|
||||
// Set appendWindowEnd to ensure we only have about 6 frames worth.
|
||||
// We must feed at least 6 frames to pass the MDSM pre-roll.
|
||||
videosb.appendWindowEnd = .4;
|
||||
return fetchAndLoad(videosb, 'bipbop/bipbop_video', ['1'], '.m4s');
|
||||
})
|
||||
.then(function() {
|
||||
info("Invoking play()");
|
||||
var promises = [];
|
||||
promises.push(once(el, 'playing'));
|
||||
el.play();
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.then(function() {
|
||||
info("got playing");
|
||||
return once(el, 'waiting');
|
||||
}).then(function() {
|
||||
info("got waiting");
|
||||
info("Loading more data");
|
||||
// Waiting will be fired on the last frame +- 40ms.
|
||||
isfuzzy(el.currentTime, videosb.buffered.end(0) - 1/30,
|
||||
0.04, "Got a waiting event at " + el.currentTime);
|
||||
videosb.appendWindowEnd = 1;
|
||||
var p = once(el, 'ended');
|
||||
var loads = fetchAndLoad(videosb, 'bipbop/bipbop_video', [1], '.m4s');
|
||||
loads.then(() => ms.endOfStream());
|
||||
return p;
|
||||
}).then(function() {
|
||||
// These fuzz factors are bigger than they should be. We should investigate
|
||||
// and fix them in bug 1137574.
|
||||
is(el.duration, 0.801666, "Video has correct duration: " + el.duration);
|
||||
is(el.currentTime, el.duration, "Video has correct currentTime.");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -37,6 +37,9 @@ runWithMSE(function(ms, el) {
|
||||
var promises = [];
|
||||
promises.push(once(el, 'loadeddata'));
|
||||
promises.push(once(el, 'canplay'));
|
||||
// Load [0, 1.601666). We must ensure that we load over 25 frames as the
|
||||
// windows H264 decoder will not produce a sample until then
|
||||
// (bug 1191138).
|
||||
promises.push(fetchAndLoad(videosb, 'bipbop/bipbop_video', range(1, 3), '.m4s'));
|
||||
return Promise.all(promises);
|
||||
})
|
||||
|
@ -40,8 +40,9 @@ runWithMSE(function(ms, el) {
|
||||
// currentTime is based on the current video frame, so if the audio ends just before
|
||||
// the next video frame, currentTime can be up to 1 frame's worth earlier than
|
||||
// min(audioEnd, videoEnd).
|
||||
isfuzzy(el.currentTime, Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 1/30,
|
||||
0.04, "Got a waiting event at " + el.currentTime);
|
||||
// Some decoders (Windows in particular) may keep up to 25 frames queued.
|
||||
isfuzzy(el.currentTime, Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 1/60,
|
||||
25 * 1/30, "Got a waiting event at " + el.currentTime);
|
||||
info("Loading more data");
|
||||
var p = once(el, 'ended');
|
||||
var loads = Promise.all([fetchAndLoad(audiosb, 'bipbop/bipbop_audio', [5], '.m4s'),
|
||||
|
@ -39,8 +39,9 @@ runWithMSE(function(ms, el) {
|
||||
// the next video frame, currentTime can be up to 1 frame's worth earlier than
|
||||
// min(audioEnd, videoEnd).
|
||||
// Some decoders (Windows in particular) may keep up to 25 frames queued.
|
||||
isfuzzy(el.currentTime, Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 1/30,
|
||||
0.04, "Got a waiting event at " + el.currentTime);
|
||||
isfuzzy(el.currentTime, Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 1/60,
|
||||
25 * 1/30, "Got a waiting event at " + el.currentTime);
|
||||
}).then(function() {
|
||||
var p = once(el, 'ended');
|
||||
ms.endOfStream();
|
||||
return p;
|
||||
|
Loading…
Reference in New Issue
Block a user