mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Backed out changesets ef6465b02d0d f749e3f70ffc ecd54a3fbfdd 8f472a850073 (bug 879717)
This commit is contained in:
parent
d947cf32a0
commit
5c602bba2f
@ -285,13 +285,6 @@ public:
|
||||
|
||||
void NotifyMediaTrackEnabled(MediaTrack* aTrack);
|
||||
|
||||
/**
|
||||
* Called by a DOMMediaStream when it has tracks available.
|
||||
* This allows us to setup audio and video outputs after the stream
|
||||
* has already reported that playback started, in case they are added late.
|
||||
*/
|
||||
void NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream);
|
||||
|
||||
virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
@ -623,7 +616,6 @@ protected:
|
||||
|
||||
class MediaLoadListener;
|
||||
class StreamListener;
|
||||
class MediaStreamTracksAvailableCallback;
|
||||
|
||||
virtual void GetItemValueText(nsAString& text) MOZ_OVERRIDE;
|
||||
virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
|
||||
@ -1026,9 +1018,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.
|
||||
|
@ -71,8 +71,6 @@
|
||||
#include "mozilla/dom/MediaSource.h"
|
||||
#include "MediaMetadataManager.h"
|
||||
#include "MediaSourceDecoder.h"
|
||||
#include "AudioStreamTrack.h"
|
||||
#include "VideoStreamTrack.h"
|
||||
|
||||
#include "AudioChannelService.h"
|
||||
|
||||
@ -666,10 +664,7 @@ void HTMLMediaElement::AbortExistingLoads()
|
||||
mHaveQueuedSelectResource = false;
|
||||
mSuspendedForPreloadNone = false;
|
||||
mDownloadSuspendedByCache = false;
|
||||
mHasAudio = false;
|
||||
mHasVideo = false;
|
||||
mSourcePointer = nullptr;
|
||||
mLastNextFrameStatus = NEXT_FRAME_UNINITIALIZED;
|
||||
|
||||
mTags = nullptr;
|
||||
|
||||
@ -903,39 +898,6 @@ void HTMLMediaElement::NotifyMediaTrackEnabled(MediaTrack* aTrack)
|
||||
}
|
||||
}
|
||||
|
||||
void HTMLMediaElement::NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream)
|
||||
{
|
||||
if (!mSrcStream || mSrcStream != aStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool oldHasAudio = mHasAudio;
|
||||
bool oldHasVideo = mHasVideo;
|
||||
|
||||
nsAutoTArray<nsRefPtr<AudioStreamTrack>,1> audioTracks;
|
||||
aStream->GetAudioTracks(audioTracks);
|
||||
nsAutoTArray<nsRefPtr<VideoStreamTrack>,1> videoTracks;
|
||||
aStream->GetVideoTracks(videoTracks);
|
||||
|
||||
mHasAudio = !audioTracks.IsEmpty();
|
||||
mHasVideo = !videoTracks.IsEmpty();
|
||||
|
||||
if (!oldHasAudio && mHasAudio) {
|
||||
GetSrcMediaStream()->AddAudioOutput(this);
|
||||
GetSrcMediaStream()->SetAudioOutputVolume(this, float(mMuted ? 0.0 : mVolume));
|
||||
}
|
||||
if (!oldHasVideo && mHasVideo ) {
|
||||
VideoFrameContainer* container = GetVideoFrameContainer();
|
||||
if (container) {
|
||||
GetSrcMediaStream()->AddVideoOutput(container);
|
||||
}
|
||||
// mHasVideo changed so make sure the screen wakelock is updated
|
||||
NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
|
||||
CheckAutoplayDataReady();
|
||||
}
|
||||
|
||||
void HTMLMediaElement::LoadFromSourceChildren()
|
||||
{
|
||||
NS_ASSERTION(mDelayingLoadEvent,
|
||||
@ -2025,7 +1987,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),
|
||||
@ -2854,28 +2815,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.");
|
||||
|
||||
if (!mElement) {
|
||||
return;
|
||||
}
|
||||
mElement->NotifyMediaStreamTracksAvailable(aStream);
|
||||
}
|
||||
private:
|
||||
HTMLMediaElement* mElement;
|
||||
};
|
||||
|
||||
void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
|
||||
{
|
||||
NS_ASSERTION(!mSrcStream && !mSrcStreamListener, "Should have been ended already");
|
||||
@ -2897,24 +2836,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));
|
||||
|
||||
MediaInfo mediaInfo;
|
||||
mediaInfo.mAudio.mHasAudio = mHasAudio;
|
||||
mediaInfo.mVideo.mHasVideo = mHasVideo;
|
||||
MetadataLoaded(&mediaInfo, nullptr);
|
||||
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
|
||||
|
||||
ChangeDelayLoadStatus(false);
|
||||
GetSrcMediaStream()->AddAudioOutput(this);
|
||||
GetSrcMediaStream()->SetAudioOutputVolume(this, float(mMuted ? 0.0 : mVolume));
|
||||
VideoFrameContainer* container = GetVideoFrameContainer();
|
||||
if (container) {
|
||||
GetSrcMediaStream()->AddVideoOutput(container);
|
||||
}
|
||||
|
||||
// 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.
|
||||
}
|
||||
@ -2930,12 +2867,12 @@ void HTMLMediaElement::EndSrcMediaStreamPlayback()
|
||||
// Kill its reference to this element
|
||||
mSrcStreamListener->Forget();
|
||||
mSrcStreamListener = nullptr;
|
||||
if (stream && mHasAudio) {
|
||||
if (stream) {
|
||||
stream->RemoveAudioOutput(this);
|
||||
}
|
||||
VideoFrameContainer* container = GetVideoFrameContainer();
|
||||
if (container) {
|
||||
if (stream && mHasVideo) {
|
||||
if (stream) {
|
||||
stream->RemoveVideoOutput(container);
|
||||
}
|
||||
container->ClearCurrentFrame();
|
||||
@ -2987,11 +2924,6 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
|
||||
mVideoFrameContainer->ForgetElement();
|
||||
mVideoFrameContainer = nullptr;
|
||||
}
|
||||
|
||||
if (IsVideo()) {
|
||||
// Update the screen wakelock in case mHasVideo changed
|
||||
NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void HTMLMediaElement::FirstFrameLoaded()
|
||||
@ -2999,7 +2931,6 @@ void HTMLMediaElement::FirstFrameLoaded()
|
||||
NS_ASSERTION(!mSuspendedAfterFirstFrame, "Should not have already suspended");
|
||||
|
||||
ChangeDelayLoadStatus(false);
|
||||
UpdateReadyStateForData(NEXT_FRAME_UNAVAILABLE);
|
||||
|
||||
if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
|
||||
!HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
|
||||
@ -3162,18 +3093,10 @@ bool HTMLMediaElement::ShouldCheckAllowOrigin()
|
||||
|
||||
void HTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatus aNextFrame)
|
||||
{
|
||||
mLastNextFrameStatus = aNextFrame;
|
||||
|
||||
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 (!mHasAudio && !mHasVideo) {
|
||||
// No tracks available yet, don't advance from HAVE_METADATA
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3196,14 +3119,6 @@ void HTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatu
|
||||
return;
|
||||
}
|
||||
|
||||
if (mReadyState < nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA && mHasVideo) {
|
||||
VideoFrameContainer* container = GetVideoFrameContainer();
|
||||
if (container && mMediaSize == nsIntSize(-1,-1)) {
|
||||
// No frame has been set yet. Don't advance.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aNextFrame != MediaDecoderOwner::NEXT_FRAME_AVAILABLE) {
|
||||
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
|
||||
if (!mWaitingFired && aNextFrame == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING) {
|
||||
@ -3344,15 +3259,14 @@ void HTMLMediaElement::ChangeNetworkState(nsMediaNetworkState aState)
|
||||
|
||||
bool HTMLMediaElement::CanActivateAutoplay()
|
||||
{
|
||||
// For stream inputs, we activate autoplay on HAVE_METADATA 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 && mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA)) &&
|
||||
(mHasAudio || mHasVideo) &&
|
||||
(mSrcStream && mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA)) &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
|
||||
mAutoplayEnabled &&
|
||||
!IsEditable();
|
||||
@ -3381,14 +3295,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());
|
||||
|
||||
@ -3501,7 +3425,6 @@ void HTMLMediaElement::NotifyDecoderPrincipalChanged()
|
||||
void HTMLMediaElement::UpdateMediaSize(nsIntSize size)
|
||||
{
|
||||
mMediaSize = size;
|
||||
UpdateReadyStateForData(mLastNextFrameStatus);
|
||||
}
|
||||
|
||||
void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents)
|
||||
|
@ -322,7 +322,6 @@ skip-if = buildapp == 'mulet' || os == 'win' # bug 894922
|
||||
[test_bug686942.html]
|
||||
[test_bug726904.html]
|
||||
[test_bug874897.html]
|
||||
[test_bug879717.html]
|
||||
[test_bug883173.html]
|
||||
[test_bug895091.html]
|
||||
[test_bug895305.html]
|
||||
|
@ -1,65 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for bug 879717, check that a video element can be drawn into a canvas directly on 'play' event</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>
|
||||
<video id="v1" autoplay />
|
||||
<video id="v2" autoplay />
|
||||
<canvas id="c1" />
|
||||
<canvas id="c2" />
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var media = getPlayableVideo(gSmallTests);
|
||||
|
||||
var checkDrawImage = function(video, canvas, name) {
|
||||
var exception = null;
|
||||
var exceptionName = "nothing";
|
||||
try {
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
exceptionName = e.name;
|
||||
}
|
||||
ok(exception === null || video.ended,
|
||||
"drawImage shouldn't throw an exception on play of " + name + ", got " + exceptionName);
|
||||
};
|
||||
|
||||
if (media == null) {
|
||||
todo(false, "No media supported.");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
v1.src = media.name;
|
||||
v2.mozSrcObject = v1.mozCaptureStream();
|
||||
|
||||
var v1Tested = false;
|
||||
var v2Tested = false;
|
||||
|
||||
v1.addEventListener('play', function() {
|
||||
checkDrawImage(v1, c1, media.name);
|
||||
|
||||
v1Tested = true;
|
||||
if (v2Tested) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
|
||||
v2.addEventListener('play', function() {
|
||||
checkDrawImage(v2, c2, "stream of " + media.name);
|
||||
|
||||
v2Tested = true;
|
||||
if (v1Tested) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -19,8 +19,6 @@ using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static const TrackID TRACK_VIDEO = 2;
|
||||
|
||||
void
|
||||
FakeMediaStreamGraph::DispatchToMainThreadAfterStreamStateUpdate(already_AddRefed<nsIRunnable> aRunnable)
|
||||
{
|
||||
@ -34,7 +32,6 @@ CameraPreviewMediaStream::CameraPreviewMediaStream(DOMMediaStream* aWrapper)
|
||||
, mInvalidatePending(0)
|
||||
, mDiscardedFrames(0)
|
||||
, mRateLimit(false)
|
||||
, mTrackCreated(false)
|
||||
{
|
||||
SetGraphImpl(MediaStreamGraph::GetInstance());
|
||||
mFakeMediaStreamGraph = new FakeMediaStreamGraph();
|
||||
@ -114,22 +111,6 @@ CameraPreviewMediaStream::RemoveListener(MediaStreamListener* aListener)
|
||||
listener->NotifyEvent(mFakeMediaStreamGraph, MediaStreamListener::EVENT_REMOVED);
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::OnPreviewStateChange(bool aActive)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mTrackCreated && aActive) {
|
||||
mTrackCreated = true;
|
||||
VideoSegment tmpSegment;
|
||||
uint32_t trackEvent = aActive ? MediaStreamListener::TRACK_EVENT_CREATED
|
||||
: MediaStreamListener::TRACK_EVENT_ENDED;
|
||||
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
|
||||
MediaStreamListener* l = mListeners[j];
|
||||
l->NotifyQueuedTrackChanges(mFakeMediaStreamGraph, TRACK_VIDEO, 0, 0, trackEvent, tmpSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::Destroy()
|
||||
{
|
||||
|
@ -51,7 +51,6 @@ public:
|
||||
virtual void AddListener(MediaStreamListener* aListener) MOZ_OVERRIDE;
|
||||
virtual void RemoveListener(MediaStreamListener* aListener) MOZ_OVERRIDE;
|
||||
virtual void Destroy();
|
||||
void OnPreviewStateChange(bool aActive);
|
||||
|
||||
void Invalidate();
|
||||
|
||||
@ -68,7 +67,6 @@ protected:
|
||||
int32_t mInvalidatePending;
|
||||
uint32_t mDiscardedFrames;
|
||||
bool mRateLimit;
|
||||
bool mTrackCreated;
|
||||
nsRefPtr<FakeMediaStreamGraph> mFakeMediaStreamGraph;
|
||||
};
|
||||
|
||||
|
@ -218,8 +218,7 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
|
||||
mCurrentConfiguration = initialConfig.forget();
|
||||
|
||||
// Attach our DOM-facing media stream to our viewfinder stream.
|
||||
SetHintContents(HINT_CONTENTS_VIDEO);
|
||||
InitStreamCommon(mInput);
|
||||
mStream = mInput;
|
||||
MOZ_ASSERT(mWindow, "Shouldn't be created with a null window!");
|
||||
if (mWindow->GetExtantDoc()) {
|
||||
CombineWithPrincipal(mWindow->GetExtantDoc()->NodePrincipal());
|
||||
|
@ -137,7 +137,6 @@ DOMCameraControlListener::OnPreviewStateChange(PreviewState aState)
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid preview state");
|
||||
return;
|
||||
}
|
||||
mStream->OnPreviewStateChange(aState == kPreviewStarted);
|
||||
NS_DispatchToMainThread(new Callback(mDOMCameraControl, aState));
|
||||
}
|
||||
|
||||
|
@ -109,26 +109,18 @@ var Camera = {
|
||||
var blob = e.data;
|
||||
var img = new Image();
|
||||
var test = this._currentTest;
|
||||
var onPreviewStateChange = function(e) {
|
||||
if (e.newState === 'started') {
|
||||
ok(true, "viewfinder is ready and playing after resume");
|
||||
Camera.cameraObj.removeEventListener('previewstatechange', onPreviewStateChange);
|
||||
Camera._testsCompleted++;
|
||||
if(Camera._testsCompleted == Camera._tests.length) {
|
||||
ok(true, "test finishing");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
Camera.runTests();
|
||||
}
|
||||
}
|
||||
}
|
||||
Camera.cameraObj.addEventListener('previewstatechange', onPreviewStateChange);
|
||||
img.onload = function Imgsize() {
|
||||
ok(this.width == test.pictureSize.width, "The image taken has the width " +
|
||||
this.width + " pictureSize width = " + test.pictureSize.width);
|
||||
ok(this.height == test.pictureSize.height, "The image taken has the height " +
|
||||
this.height + " picturesize height = " + test.pictureSize.height);
|
||||
Camera.cameraObj.resumePreview();
|
||||
Camera._testsCompleted++;
|
||||
if(Camera._testsCompleted == Camera._tests.length) {
|
||||
ok(true, "test finishing");
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
Camera.runTests();
|
||||
}
|
||||
}
|
||||
ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
|
||||
ok("image/" + test.fileFormat == blob.type, "Blob Type = " + blob.type);
|
||||
|
Loading…
Reference in New Issue
Block a user