mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 13:25:37 +00:00
Backed out changesets 6bd00fa70b00, 4e2f8f3b8f6b, and c89fec9c8b55 (bug 879717) for introducting multiple new intermittent failures.
--HG-- extra : rebase_source : 4aad9383081f256484dd06e87f14cc82ecf186b5
This commit is contained in:
parent
f33e0b3f59
commit
c54bf72326
@ -71,8 +71,6 @@
|
||||
#include "mozilla/dom/MediaSource.h"
|
||||
#include "MediaMetadataManager.h"
|
||||
#include "MediaSourceDecoder.h"
|
||||
#include "AudioStreamTrack.h"
|
||||
#include "VideoStreamTrack.h"
|
||||
|
||||
#include "AudioChannelService.h"
|
||||
|
||||
@ -665,10 +663,7 @@ void HTMLMediaElement::AbortExistingLoads()
|
||||
mHaveQueuedSelectResource = false;
|
||||
mSuspendedForPreloadNone = false;
|
||||
mDownloadSuspendedByCache = false;
|
||||
mHasAudio = false;
|
||||
mHasVideo = false;
|
||||
mSourcePointer = nullptr;
|
||||
mLastNextFrameStatus = NEXT_FRAME_UNINITIALIZED;
|
||||
|
||||
mTags = nullptr;
|
||||
|
||||
@ -902,30 +897,6 @@ void HTMLMediaElement::NotifyMediaTrackEnabled(MediaTrack* aTrack)
|
||||
}
|
||||
}
|
||||
|
||||
void HTMLMediaElement::NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream)
|
||||
{
|
||||
if (!mSrcStream || mSrcStream != aStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool oldHasVideo = mHasVideo;
|
||||
|
||||
nsAutoTArray<nsRefPtr<AudioStreamTrack>,1> audioTracks;
|
||||
mSrcStream->GetAudioTracks(audioTracks);
|
||||
nsAutoTArray<nsRefPtr<VideoStreamTrack>,1> videoTracks;
|
||||
mSrcStream->GetVideoTracks(videoTracks);
|
||||
|
||||
mHasAudio = !audioTracks.IsEmpty();
|
||||
mHasVideo = !videoTracks.IsEmpty();
|
||||
|
||||
if (IsVideo() && oldHasVideo != mHasVideo) {
|
||||
// We are a video element and mHasVideo changed so update the screen wakelock
|
||||
NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
|
||||
UpdateReadyStateForData(mLastNextFrameStatus);
|
||||
}
|
||||
|
||||
void HTMLMediaElement::LoadFromSourceChildren()
|
||||
{
|
||||
NS_ASSERTION(mDelayingLoadEvent,
|
||||
@ -2010,7 +1981,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
||||
mCurrentLoadID(0),
|
||||
mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY),
|
||||
mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING),
|
||||
mLastNextFrameStatus(NEXT_FRAME_UNINITIALIZED),
|
||||
mLoadWaitStatus(NOT_WAITING),
|
||||
mVolume(1.0),
|
||||
mPreloadAction(PRELOAD_UNDEFINED),
|
||||
@ -2848,25 +2818,6 @@ private:
|
||||
bool mPendingNotifyOutput;
|
||||
};
|
||||
|
||||
class HTMLMediaElement::MediaStreamTracksAvailableCallback:
|
||||
public DOMMediaStream::OnTracksAvailableCallback
|
||||
{
|
||||
public:
|
||||
explicit MediaStreamTracksAvailableCallback(HTMLMediaElement* aElement,
|
||||
DOMMediaStream::TrackTypeHints aExpectedTracks = 0):
|
||||
DOMMediaStream::OnTracksAvailableCallback(aExpectedTracks),
|
||||
mElement(aElement)
|
||||
{}
|
||||
virtual void NotifyTracksAvailable(DOMMediaStream* aStream)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
|
||||
mElement->NotifyMediaStreamTracksAvailable(aStream);
|
||||
}
|
||||
private:
|
||||
HTMLMediaElement* mElement;
|
||||
};
|
||||
|
||||
void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
|
||||
{
|
||||
NS_ASSERTION(!mSrcStream && !mSrcStreamListener, "Should have been ended already");
|
||||
@ -2888,26 +2839,22 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
|
||||
if (mPausedForInactiveDocumentOrChannel) {
|
||||
GetSrcMediaStream()->ChangeExplicitBlockerCount(1);
|
||||
}
|
||||
|
||||
mSrcStream->OnTracksAvailable(new MediaStreamTracksAvailableCallback(this, DOMMediaStream::HINT_CONTENTS_AUDIO));
|
||||
mSrcStream->OnTracksAvailable(new MediaStreamTracksAvailableCallback(this, DOMMediaStream::HINT_CONTENTS_VIDEO));
|
||||
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
|
||||
|
||||
ChangeDelayLoadStatus(false);
|
||||
GetSrcMediaStream()->AddAudioOutput(this);
|
||||
SetVolumeInternal();
|
||||
GetSrcMediaStream()->SetAudioOutputVolume(this, float(mMuted ? 0.0 : mVolume));
|
||||
VideoFrameContainer* container = GetVideoFrameContainer();
|
||||
if (container) {
|
||||
GetSrcMediaStream()->AddVideoOutput(container);
|
||||
}
|
||||
|
||||
CheckAutoplayDataReady();
|
||||
|
||||
// Note: we must call DisconnectTrackListListeners(...) before dropping
|
||||
// mSrcStream
|
||||
mSrcStream->ConstructMediaTracks(AudioTracks(), VideoTracks());
|
||||
|
||||
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
|
||||
AddRemoveSelfReference();
|
||||
// FirstFrameLoaded() will be called when the stream has current data.
|
||||
}
|
||||
@ -2988,11 +2935,6 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
|
||||
} else {
|
||||
UpdateMediaSize(aInfo->mVideo.mDisplay);
|
||||
}
|
||||
|
||||
if (IsVideo() && aInfo->HasVideo()) {
|
||||
// We are a video element playing video so update the screen wakelock
|
||||
NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void HTMLMediaElement::FirstFrameLoaded()
|
||||
@ -3253,47 +3195,18 @@ bool HTMLMediaElement::ShouldCheckAllowOrigin()
|
||||
|
||||
void HTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatus aNextFrame)
|
||||
{
|
||||
mLastNextFrameStatus = aNextFrame;
|
||||
|
||||
if (mDecoder && mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
|
||||
if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
|
||||
// aNextFrame might have a next frame because the decoder can advance
|
||||
// on its own thread before MetadataLoaded gets a chance to run.
|
||||
// The arrival of more data can't change us out of this readyState.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSrcStream && mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
|
||||
if ((!mHasAudio && !mHasVideo) ||
|
||||
(IsVideo() && mHasVideo && mMediaSize == nsIntSize(-1, -1))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We are playing a stream that has video and a video frame is now set.
|
||||
// This means we have all metadata needed to change ready state.
|
||||
MediaInfo mediaInfo;
|
||||
mediaInfo.mAudio.mHasAudio = mHasAudio;
|
||||
mediaInfo.mVideo.mHasVideo = mHasVideo;
|
||||
if (mHasVideo) {
|
||||
mediaInfo.mVideo.mDisplay = mMediaSize;
|
||||
}
|
||||
MetadataLoaded(&mediaInfo, nsAutoPtr<const MetadataTags>(nullptr));
|
||||
}
|
||||
|
||||
if (aNextFrame == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING) {
|
||||
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsVideo() && mHasVideo && !IsPlaybackEnded() &&
|
||||
GetImageContainer() && !GetImageContainer()->HasCurrentImage()) {
|
||||
// Don't advance if we are playing video, but don't have a video frame.
|
||||
// Also, if video became available after advancing to HAVE_CURRENT_DATA
|
||||
// while we are still playing, we need to revert to HAVE_METADATA until
|
||||
// a video frame is available.
|
||||
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDownloadSuspendedByCache && mDecoder && !mDecoder->IsEnded()) {
|
||||
// The decoder has signaled that the download has been suspended by the
|
||||
// media cache. So move readyState into HAVE_ENOUGH_DATA, in case there's
|
||||
@ -3441,14 +3354,14 @@ void HTMLMediaElement::ChangeNetworkState(nsMediaNetworkState aState)
|
||||
|
||||
bool HTMLMediaElement::CanActivateAutoplay()
|
||||
{
|
||||
// For stream inputs, we activate autoplay on HAVE_NOTHING because
|
||||
// For stream inputs, we activate autoplay on HAVE_CURRENT_DATA because
|
||||
// this element itself might be blocking the stream from making progress by
|
||||
// being paused.
|
||||
return !mPausedForInactiveDocumentOrChannel &&
|
||||
mAutoplaying &&
|
||||
mPaused &&
|
||||
((mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) ||
|
||||
mSrcStream) &&
|
||||
(mSrcStream && mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA)) &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
|
||||
mAutoplayEnabled &&
|
||||
!IsEditable();
|
||||
@ -3477,14 +3390,24 @@ void HTMLMediaElement::CheckAutoplayDataReady()
|
||||
|
||||
VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
|
||||
{
|
||||
if (mVideoFrameContainer)
|
||||
return mVideoFrameContainer;
|
||||
// If we have loaded the metadata, and the size of the video is still
|
||||
// (-1, -1), the media has no video. Don't go a create a video frame
|
||||
// container.
|
||||
if (mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA &&
|
||||
mMediaSize == nsIntSize(-1, -1)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Only video frames need an image container.
|
||||
if (!IsVideo()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mHasVideo = true;
|
||||
|
||||
if (mVideoFrameContainer)
|
||||
return mVideoFrameContainer;
|
||||
|
||||
mVideoFrameContainer =
|
||||
new VideoFrameContainer(this, LayerManager::CreateAsynchronousImageContainer());
|
||||
|
||||
@ -3597,7 +3520,6 @@ void HTMLMediaElement::NotifyDecoderPrincipalChanged()
|
||||
void HTMLMediaElement::UpdateMediaSize(nsIntSize size)
|
||||
{
|
||||
mMediaSize = size;
|
||||
UpdateReadyStateForData(mLastNextFrameStatus);
|
||||
}
|
||||
|
||||
void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents)
|
||||
|
@ -281,11 +281,6 @@ public:
|
||||
|
||||
void NotifyMediaTrackEnabled(MediaTrack* aTrack);
|
||||
|
||||
/**
|
||||
* Called when tracks become available to the source media stream.
|
||||
*/
|
||||
void NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream);
|
||||
|
||||
virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
@ -617,7 +612,6 @@ protected:
|
||||
virtual ~HTMLMediaElement();
|
||||
|
||||
class MediaLoadListener;
|
||||
class MediaStreamTracksAvailableCallback;
|
||||
class StreamListener;
|
||||
|
||||
virtual void GetItemValueText(nsAString& text) MOZ_OVERRIDE;
|
||||
@ -1042,9 +1036,6 @@ protected:
|
||||
nsMediaNetworkState mNetworkState;
|
||||
nsMediaReadyState mReadyState;
|
||||
|
||||
// Last value passed from codec or stream source to UpdateReadyStateForData.
|
||||
NextFrameStatus mLastNextFrameStatus;
|
||||
|
||||
enum LoadAlgorithmState {
|
||||
// No load algorithm instance is waiting for a source to be added to the
|
||||
// media in order to continue loading.
|
||||
|
@ -14,7 +14,7 @@ var gSmallTests = [
|
||||
{ name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
|
||||
{ name:"vp9.webm", type:"video/webm", width:320, height:240, duration:4 },
|
||||
{ name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
|
||||
{ name:"gizmo.mp4", type:"video/mp4", width:560, height:320, duration:5.56 },
|
||||
{ name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
|
||||
{ name:"bogus.duh", type:"bogus/duh" }
|
||||
];
|
||||
|
||||
|
@ -332,7 +332,6 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
|
||||
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
|
||||
[test_bug726904.html]
|
||||
[test_bug874897.html]
|
||||
[test_bug879717.html]
|
||||
[test_bug883173.html]
|
||||
[test_bug895091.html]
|
||||
[test_bug895305.html]
|
||||
@ -470,7 +469,6 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
|
||||
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
|
||||
[test_reset_events_async.html]
|
||||
[test_reset_src.html]
|
||||
[test_video_dimensions.html]
|
||||
[test_resume.html]
|
||||
skip-if = true # bug 1021673
|
||||
[test_seek_out_of_range.html]
|
||||
|
@ -1,119 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for bug 879717, check that a video element can be drawn into a canvas at various states of playback</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
var checkDrawImage = function(eventName, videoElement) {
|
||||
var exception = null;
|
||||
var exceptionName = "nothing";
|
||||
try {
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
exceptionName = e.name;
|
||||
}
|
||||
ok(exception === null,
|
||||
"drawImage shouldn't throw an exception on " + eventName +
|
||||
" of " + videoElement.testName + ", got " + exceptionName);
|
||||
};
|
||||
|
||||
var checkDrawImageEventHandler = function(ev) {
|
||||
checkDrawImage(ev.type, ev.target);
|
||||
};
|
||||
var startTest = function(media, token) {
|
||||
manager.started(token);
|
||||
|
||||
// File playback
|
||||
var v1 = document.createElement("video");
|
||||
v1.autoplay = true;
|
||||
|
||||
// Captured file playback
|
||||
var v2 = document.createElement("video");
|
||||
v2.autoplay = true;
|
||||
|
||||
// Stream playback
|
||||
var v3 = document.createElement("video");
|
||||
v3.autoplay = true;
|
||||
|
||||
v1.gotLoadeddata = false;
|
||||
v2.gotLoadeddata = false;
|
||||
v3.gotLoadeddata = false;
|
||||
|
||||
v1.testName = "v1 (" + media.name + ")";
|
||||
v2.testName = "v2 (Captured " + media.name + ")";
|
||||
v3.testName = "v3 (Stream of " + media.name + ")";
|
||||
|
||||
checkDrawImage("beforeplay", v1);
|
||||
checkDrawImage("beforeplay", v2);
|
||||
checkDrawImage("beforeplay", v3);
|
||||
|
||||
v1.onloadedmetadata = checkDrawImageEventHandler;
|
||||
v2.onloadedmetadata = checkDrawImageEventHandler;
|
||||
v3.onloadedmetadata = checkDrawImageEventHandler;
|
||||
|
||||
v1.onplay = checkDrawImageEventHandler;
|
||||
v2.onplay = checkDrawImageEventHandler;
|
||||
v3.onplay = checkDrawImageEventHandler;
|
||||
|
||||
v1.onplaying = checkDrawImageEventHandler;
|
||||
v2.onplaying = checkDrawImageEventHandler;
|
||||
v3.onplaying = checkDrawImageEventHandler;
|
||||
|
||||
var onloadeddata = function(ev) {
|
||||
ev.target.gotLoadeddata = true;
|
||||
checkDrawImageEventHandler(ev);
|
||||
};
|
||||
|
||||
v1.onloadeddata = onloadeddata;
|
||||
v2.onloadeddata = onloadeddata;
|
||||
v3.onloadeddata = onloadeddata;
|
||||
|
||||
var checkFinished = function() {
|
||||
if (!v1.testFinished || !v2.testFinished || !v3.testFinished) {
|
||||
return;
|
||||
}
|
||||
|
||||
ok(v1.gotLoadeddata, v1.testName + " should have gotten the 'loadeddata' event callback");
|
||||
ok(v2.gotLoadeddata, v2.testName + " should have gotten the 'loadeddata' event callback");
|
||||
ok(v3.gotLoadeddata, v3.testName + " should have gotten the 'loadeddata' event callback");
|
||||
|
||||
manager.finished(token);
|
||||
};
|
||||
|
||||
var onended = function(ev) {
|
||||
checkDrawImageEventHandler(ev);
|
||||
removeNodeAndSource(ev.target);
|
||||
ev.target.testFinished = true;
|
||||
checkFinished();
|
||||
};
|
||||
|
||||
v1.onended = onended;
|
||||
v2.onended = onended;
|
||||
v3.onended = onended;
|
||||
|
||||
document.body.appendChild(v1);
|
||||
document.body.appendChild(v2);
|
||||
document.body.appendChild(v3);
|
||||
|
||||
v1.src = media.name;
|
||||
v2.src = media.name;
|
||||
v3.mozSrcObject = v2.mozCaptureStreamUntilEnded();
|
||||
}
|
||||
|
||||
manager.runTests(getPlayableVideos(gSmallTests), startTest);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -45,8 +45,6 @@ function doTest() {
|
||||
}
|
||||
++step;
|
||||
});
|
||||
a.play();
|
||||
b.play();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -1,67 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test that a video element has set video dimensions on loadedmetadata</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
var startTest = function(test, token) {
|
||||
manager.started(token);
|
||||
var v1 = document.createElement('video');
|
||||
var v2 = document.createElement('video');
|
||||
var vout = document.createElement('video');
|
||||
|
||||
var numVideoElementsFinished = 0;
|
||||
|
||||
var onloadedmetadata = function(ev) {
|
||||
var v = ev.target;
|
||||
ok(!v.loadedmetadata, v.testName + " should only fire loadedmetadata once");
|
||||
v.loadedmetadata = true;
|
||||
is(v.videoWidth, test.width, v.testName + " video width should be set on loadedmetadata");
|
||||
is(v.videoHeight, test.height, v.testName + " video height should be set on loadedmetadata");
|
||||
|
||||
numVideoElementsFinished += 1;
|
||||
if (v === v1) {
|
||||
removeNodeAndSource(v1);
|
||||
v2.play();
|
||||
vout.play();
|
||||
}
|
||||
|
||||
if (numVideoElementsFinished === 3) {
|
||||
removeNodeAndSource(v2);
|
||||
removeNodeAndSource(vout);
|
||||
manager.finished(token);
|
||||
}
|
||||
};
|
||||
var setupElement = function(v, id) {
|
||||
v.loadedmetadata = false;
|
||||
v.onloadedmetadata = onloadedmetadata;
|
||||
document.body.appendChild(v);
|
||||
};
|
||||
|
||||
v1.testName = test.name;
|
||||
v2.testName = test.name + " (Captured)";
|
||||
vout.testName = test.name + " (Stream)";
|
||||
|
||||
v1.src = test.name;
|
||||
v2.src = test.name;
|
||||
vout.src = URL.createObjectURL(v2.mozCaptureStreamUntilEnded());
|
||||
|
||||
setupElement(v1, "v1");
|
||||
setupElement(v2, "v2");
|
||||
setupElement(vout, "vout");
|
||||
|
||||
v1.play();
|
||||
};
|
||||
|
||||
manager.runTests(getPlayableVideos(gSmallTests), startTest);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user