Backed out changeset 0c5a4939300c (bug 1454889) for causing frequent Leaks (Bug 1378025). a=backout

This commit is contained in:
Narcis Beleuzu 2018-05-07 12:06:25 +03:00
parent f76ef214fb
commit 2b99556758
14 changed files with 222 additions and 27 deletions

View File

@ -670,7 +670,7 @@ function prompt(aBrowser, aRequest) {
stream.getTracks().forEach(t => t.stop());
return;
}
video.srcObject = stream;
video.src = chromeWin.URL.createObjectURL(stream);
video.stream = stream;
doc.getElementById("webRTC-preview").hidden = false;
video.onloadedmetadata = function(e) {

View File

@ -6,6 +6,7 @@
#include "nsHostObjectProtocolHandler.h"
#include "DOMMediaStream.h"
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
@ -41,6 +42,7 @@ struct DataInfo
{
enum ObjectType {
eBlobImpl,
eMediaStream,
eMediaSource
};
@ -51,6 +53,13 @@ struct DataInfo
, mRevoked(false)
{}
DataInfo(DOMMediaStream* aMediaStream, nsIPrincipal* aPrincipal)
: mObjectType(eMediaStream)
, mMediaStream(aMediaStream)
, mPrincipal(aPrincipal)
, mRevoked(false)
{}
DataInfo(MediaSource* aMediaSource, nsIPrincipal* aPrincipal)
: mObjectType(eMediaSource)
, mMediaSource(aMediaSource)
@ -61,6 +70,7 @@ struct DataInfo
ObjectType mObjectType;
RefPtr<BlobImpl> mBlobImpl;
RefPtr<DOMMediaStream> mMediaStream;
RefPtr<MediaSource> mMediaSource;
nsCOMPtr<nsIPrincipal> mPrincipal;
@ -298,9 +308,10 @@ class BlobURLsReporter final : public nsIMemoryReporter
continue;
}
// Just report the path for the MediaSource.
// Just report the path for the DOMMediaStream or MediaSource.
nsAutoCString path;
path = "media-source-urls/";
path = iter.UserData()->mObjectType == DataInfo::eMediaSource
? "media-source-urls/" : "dom-media-stream-urls/";
BuildPath(path, key, info, aAnonymize);
NS_NAMED_LITERAL_CSTRING(desc,
@ -618,6 +629,22 @@ nsHostObjectProtocolHandler::AddDataEntry(BlobImpl* aBlobImpl,
return NS_OK;
}
/* static */ nsresult
nsHostObjectProtocolHandler::AddDataEntry(DOMMediaStream* aMediaStream,
nsIPrincipal* aPrincipal,
nsACString& aUri)
{
Init();
nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
NS_ENSURE_SUCCESS(rv, rv);
rv = AddDataEntryInternal(aUri, aMediaStream, aPrincipal);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
/* static */ nsresult
nsHostObjectProtocolHandler::AddDataEntry(MediaSource* aMediaSource,
nsIPrincipal* aPrincipal,
@ -797,6 +824,9 @@ nsHostObjectProtocolHandler::Traverse(const nsACString& aUri,
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mMediaSource");
aCallback.NoteXPCOMChild(res->mMediaSource);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCallback, "HostObjectProtocolHandler DataInfo.mMediaStream");
aCallback.NoteXPCOMChild(res->mMediaStream);
}
// -----------------------------------------------------------------------
@ -1044,6 +1074,19 @@ NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
return NS_OK;
}
nsresult
NS_GetStreamForMediaStreamURI(nsIURI* aURI, DOMMediaStream** aStream)
{
DataInfo* info = GetDataInfoFromURI(aURI);
if (!info || info->mObjectType != DataInfo::eMediaStream) {
return NS_ERROR_DOM_BAD_URI;
}
RefPtr<DOMMediaStream> mediaStream = info->mMediaStream;
mediaStream.forget(aStream);
return NS_OK;
}
NS_IMETHODIMP
nsFontTableProtocolHandler::NewURI(const nsACString& aSpec,
const char *aCharset,
@ -1144,6 +1187,11 @@ bool IsBlobURI(nsIURI* aUri)
return IsType(aUri, DataInfo::eBlobImpl);
}
bool IsMediaStreamURI(nsIURI* aUri)
{
return IsType(aUri, DataInfo::eMediaStream);
}
bool IsMediaSourceURI(nsIURI* aUri)
{
return IsType(aUri, DataInfo::eMediaSource);

View File

@ -23,6 +23,7 @@ class nsIPrincipal;
namespace mozilla {
class BlobURLsReporter;
class DOMMediaStream;
namespace dom {
class BlobImpl;
@ -64,6 +65,9 @@ public:
static nsresult AddDataEntry(mozilla::dom::BlobImpl* aBlobImpl,
nsIPrincipal* aPrincipal,
nsACString& aUri);
static nsresult AddDataEntry(mozilla::DOMMediaStream* aMediaStream,
nsIPrincipal* aPrincipal,
nsACString& aUri);
static nsresult AddDataEntry(mozilla::dom::MediaSource* aMediaSource,
nsIPrincipal* aPrincipal,
nsACString& aUri);
@ -112,6 +116,7 @@ public:
};
bool IsBlobURI(nsIURI* aUri);
bool IsMediaStreamURI(nsIURI* aUri);
bool IsMediaSourceURI(nsIURI* aUri);
inline bool IsRtspURI(nsIURI* aUri)
@ -135,6 +140,9 @@ NS_GetBlobForBlobURISpec(const nsACString& aSpec, mozilla::dom::BlobImpl** aBlob
extern nsresult
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
extern nsresult
NS_GetStreamForMediaStreamURI(nsIURI* aURI, mozilla::DOMMediaStream** aStream);
extern nsresult
NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource);

View File

@ -19,8 +19,9 @@
#include "nsProxyRelease.h"
/**
* These URIs refer to host objects with "blob" scheme. The underlying objects
* can be Blobs or MediaSources.
* These URIs refer to host objects: Blobs, with scheme "blob",
* MediaStreams, with scheme "mediastream", and MediaSources, with scheme
* "mediasource".
*/
class nsHostObjectURI final
: public mozilla::net::nsSimpleURI

View File

@ -2097,7 +2097,8 @@ void HTMLMediaElement::SelectResource()
mMediaSource = mSrcMediaSource;
DDLINKCHILD("mediasource", mMediaSource.get());
UpdatePreloadAction();
if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE && !mMediaSource) {
if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE &&
!IsMediaStreamURI(mLoadingSrc) && !mMediaSource) {
// preload:none media, suspend the load here before we make any
// network requests.
SuspendLoad();
@ -2426,7 +2427,8 @@ void HTMLMediaElement::LoadFromSourceChildren()
NS_ASSERTION(mNetworkState == NETWORK_LOADING,
"Network state should be loading");
if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE && !mMediaSource) {
if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE &&
!IsMediaStreamURI(mLoadingSrc) && !mMediaSource) {
// preload:none media, suspend the load here before we make any
// network requests.
SuspendLoad();
@ -2575,6 +2577,20 @@ HTMLMediaElement::LoadResource()
return rv;
}
if (IsMediaStreamURI(mLoadingSrc)) {
RefPtr<DOMMediaStream> stream;
nsresult rv = NS_GetStreamForMediaStreamURI(mLoadingSrc, getter_AddRefs(stream));
if (NS_FAILED(rv)) {
nsAutoString spec;
GetCurrentSrc(spec);
const char16_t* params[] = { spec.get() };
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
return MediaResult(rv, "MediaLoadInvalidURI");
}
SetupSrcMediaStreamPlayback(stream);
return NS_OK;
}
if (mMediaSource) {
MediaDecoderInit decoderInit(
this,

View File

@ -1133,6 +1133,9 @@ tags=msg capturestream
[test_streams_element_capture.html]
skip-if = toolkit == 'android' # bug 1372457
tags=msg capturestream
[test_streams_element_capture_createObjectURL.html]
skip-if = android_version == '15' || android_version == '17' || (android_version == '19' && debug) # android(bug 1232305)
tags=msg capturestream
[test_streams_element_capture_playback.html]
skip-if = toolkit == 'android' # android(bug 1232305)
tags=msg capturestream

View File

@ -0,0 +1,75 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test that a MediaStream captured from one element plays back in another</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">
SimpleTest.waitForExplicitFinish();
var manager = new MediaTestManager;
function checkDrawImage(vout) {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(vout, 0, 0);
var imgData = ctx.getImageData(0, 0, 1, 1);
is(imgData.data[3], 255, "Check video frame pixel has been drawn");
}
function isGreaterThanOrEqualEps(a, b, msg) {
ok(a >= b - 0.01,
"Got " + a + ", expected at least " + b + "; " + msg);
}
function startTest(test, token) {
manager.started(token);
var v = document.createElement('video');
var vout = document.createElement('video');
vout.token = token;
v.src = test.name;
v.preload = "metadata"
var stream;
var checkEnded = function() {
is(stream.currentTime, vout.currentTime, test.name + " stream final currentTime");
if (test.duration) {
isGreaterThanOrEqualEps(vout.currentTime, test.duration,
test.name + " current time at end");
}
is(vout.readyState, vout.HAVE_CURRENT_DATA, test.name + " checking readyState");
ok(vout.ended, test.name + " checking playback has ended");
if (test.type.match(/^video/)) {
checkDrawImage(vout);
}
vout.remove();
URL.revokeObjectURL(vout.src);
manager.finished(vout.token);
};
vout.addEventListener("ended", checkEnded);
document.body.appendChild(vout);
v.onloadedmetadata = function () {
stream = v.mozCaptureStreamUntilEnded();
is(stream.currentTime, 0, test.name + " stream initial currentTime");
vout.src = URL.createObjectURL(stream);
v.play();
vout.play();
};
}
SpecialPowers.pushPrefEnv(
{ "set": [["privacy.reduceTimerPrecision", false]]},
function() {
manager.runTests([getPlayableVideo(gSmallTests)], startTest);
});
</script>
</pre>
</body>
</html>

View File

@ -31,8 +31,9 @@ async function startTest() {
let video1 = document.getElementById('video1');
let video2 = document.getElementById('video2');
video1.srcObject = stream;
video2.srcObject = stream;
let src = URL.createObjectURL(stream);
video1.src = src;
video2.src = src;
video1.onplaying = () => video1.pause();

View File

@ -54,7 +54,7 @@ var startTest = function(test, token) {
}
if (v === v2) {
vout.srcObject = v2.mozCaptureStreamUntilEnded();
vout.src = URL.createObjectURL(v2.mozCaptureStreamUntilEnded());
v2.play();
vout.play();
}

View File

@ -63,6 +63,17 @@ URL::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
}
}
void
URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
nsAString& aResult, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
DeprecationWarning(aGlobal, nsIDocument::eURLCreateObjectURL_MediaStream);
URLMainThread::CreateObjectURL(aGlobal, aStream, aResult, aRv);
}
void
URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
nsAString& aResult, ErrorResult& aRv)

View File

@ -19,6 +19,7 @@ class nsIURI;
namespace mozilla {
class ErrorResult;
class DOMMediaStream;
namespace dom {
@ -60,6 +61,10 @@ public:
CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
nsAString& aResult, ErrorResult& aRv);
static void
CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
nsAString& aResult, ErrorResult& aRv);
static void
CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
nsAString& aResult, ErrorResult& aRv);

View File

@ -18,6 +18,34 @@
namespace mozilla {
namespace dom {
namespace {
template<typename T>
void
CreateObjectURLInternal(const GlobalObject& aGlobal, T aObject,
nsAString& aResult, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!global)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<nsIPrincipal> principal =
nsContentUtils::ObjectPrincipal(aGlobal.Get());
nsAutoCString url;
aRv = nsHostObjectProtocolHandler::AddDataEntry(aObject, principal, url);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
global->RegisterHostObjectURI(url);
CopyASCIItoUTF16(url, aResult);
}
} // anonymous namespace
/* static */ already_AddRefed<URLMainThread>
URLMainThread::Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase, ErrorResult& aRv)
@ -72,24 +100,16 @@ URLMainThread::CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
nsAString& aResult, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
CreateObjectURLInternal(aGlobal, aBlob.Impl(), aResult, aRv);
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!global)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<nsIPrincipal> principal =
nsContentUtils::ObjectPrincipal(aGlobal.Get());
nsAutoCString url;
aRv = nsHostObjectProtocolHandler::AddDataEntry(aBlob.Impl(), principal, url);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
global->RegisterHostObjectURI(url);
CopyASCIItoUTF16(url, aResult);
/* static */ void
URLMainThread::CreateObjectURL(const GlobalObject& aGlobal,
DOMMediaStream& aStream,
nsAString& aResult, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
CreateObjectURLInternal(aGlobal, &aStream, aResult, aRv);
}
/* static */ void

View File

@ -32,6 +32,10 @@ public:
CreateObjectURL(const GlobalObject& aGlobal, Blob& aBlob,
nsAString& aResult, ErrorResult& aRv);
static void
CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
nsAString& aResult, ErrorResult& aRv);
static void
CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
nsAString& aResult, ErrorResult& aRv);

View File

@ -6,6 +6,7 @@
* The origins of this IDL file are
* http://url.spec.whatwg.org/#api
* http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html#url
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
@ -44,6 +45,8 @@ partial interface URL {
[Throws]
static DOMString createObjectURL(Blob blob);
[Throws]
static DOMString createObjectURL(MediaStream stream);
[Throws]
static void revokeObjectURL(DOMString url);
[ChromeOnly, Throws]
static boolean isValidURL(DOMString url);