mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 482885. Ensure media channels are in the document loadgroup. r=bzbarsky,r+sr=roc
--HG-- extra : rebase_source : da14c85f0efd3eda24739161f8195d24117da261
This commit is contained in:
parent
c7e46876e5
commit
ee8c4eae0d
@ -42,6 +42,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsILoadGroup.h"
|
||||
|
||||
// Define to output information on decoding and painting framerate
|
||||
/* #define DEBUG_FRAME_RATE 1 */
|
||||
@ -228,6 +229,11 @@ public:
|
||||
*/
|
||||
PRUint32 GetCurrentLoadID() { return mCurrentLoadID; }
|
||||
|
||||
/**
|
||||
* Returns the load group for this media element's owner document.
|
||||
* XXX XBL2 issue.
|
||||
*/
|
||||
already_AddRefed<nsILoadGroup> GetDocumentLoadGroup();
|
||||
|
||||
protected:
|
||||
class MediaLoadListener;
|
||||
@ -307,6 +313,10 @@ protected:
|
||||
|
||||
nsRefPtr<nsMediaDecoder> mDecoder;
|
||||
|
||||
// Holds a reference to the first channel we open to the media resource.
|
||||
// Once the decoder is created, control over the channel passes to the
|
||||
// decoder, and we null out this reference. We must store this in case
|
||||
// we need to cancel the channel before control of it passes to the decoder.
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
||||
// Error attribute
|
||||
|
@ -498,10 +498,11 @@ nsresult nsHTMLMediaElement::LoadResource(nsIURI* aURI)
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
if (NS_CP_REJECTED(shouldLoad)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
|
||||
rv = NS_NewChannel(getter_AddRefs(mChannel),
|
||||
aURI,
|
||||
nsnull,
|
||||
nsnull,
|
||||
loadGroup,
|
||||
nsnull,
|
||||
nsIRequest::LOAD_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
@ -1118,6 +1119,10 @@ nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Decoder successfully created, its nsMediaStream now has responsibility
|
||||
// for the channel, and the owning reference.
|
||||
mChannel = nsnull;
|
||||
|
||||
mDecoder->SetVolume(mMuted ? 0.0 : mVolume);
|
||||
|
||||
if (!mPaused) {
|
||||
@ -1577,8 +1582,17 @@ void nsHTMLMediaElement::ChangeDelayLoadStatus(PRBool aDelay) {
|
||||
mLoadBlockedDoc = GetOwnerDoc();
|
||||
mLoadBlockedDoc->BlockOnload();
|
||||
} else {
|
||||
if (mDecoder) {
|
||||
mDecoder->MoveLoadsToBackground();
|
||||
}
|
||||
NS_ASSERTION(mLoadBlockedDoc, "Need a doc to block on");
|
||||
mLoadBlockedDoc->UnblockOnload(PR_FALSE);
|
||||
mLoadBlockedDoc = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsILoadGroup> nsHTMLMediaElement::GetDocumentLoadGroup()
|
||||
{
|
||||
nsIDocument* doc = GetOwnerDoc();
|
||||
return doc ? doc->GetDocumentLoadGroup() : nsnull;
|
||||
}
|
||||
|
@ -223,6 +223,13 @@ class nsMediaDecoder : public nsIObserver
|
||||
// if it's available.
|
||||
nsHTMLMediaElement* GetMediaElement();
|
||||
|
||||
// Moves any existing channel loads into the background, so that they don't
|
||||
// block the load event. This is called when we stop delaying the load
|
||||
// event. Any new loads initiated (for example to seek) will also be in the
|
||||
// background. Implementations of this must call MoveLoadsToBackground() on
|
||||
// their nsMediaStream.
|
||||
virtual void MoveLoadsToBackground()=0;
|
||||
|
||||
protected:
|
||||
|
||||
// Start timer to update download progress information.
|
||||
|
@ -198,6 +198,10 @@ public:
|
||||
virtual nsresult Seek(PRInt32 aWhence, PRInt64 aOffset) = 0;
|
||||
// Report the current offset in bytes from the start of the stream.
|
||||
virtual PRInt64 Tell() = 0;
|
||||
// Moves any existing channel loads into the background, so that they don't
|
||||
// block the load event. Any new loads initiated (for example to seek)
|
||||
// will also be in the background.
|
||||
void MoveLoadsToBackground();
|
||||
|
||||
// These can be called on any thread.
|
||||
// Cached blocks associated with this stream will not be evicted
|
||||
@ -243,7 +247,8 @@ protected:
|
||||
nsMediaStream(nsMediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) :
|
||||
mDecoder(aDecoder),
|
||||
mChannel(aChannel),
|
||||
mURI(aURI)
|
||||
mURI(aURI),
|
||||
mLoadInBackground(PR_FALSE)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsMediaStream);
|
||||
}
|
||||
@ -268,6 +273,10 @@ protected:
|
||||
// URI in case the stream needs to be re-opened. Access from
|
||||
// main thread only.
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
|
||||
// PR_TRUE if MoveLoadsToBackground() has been called, i.e. the load event
|
||||
// has been fired, and all channel loads will be in the background.
|
||||
PRPackedBool mLoadInBackground;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -372,6 +372,9 @@ class nsOggDecoder : public nsMediaDecoder
|
||||
// main thread only.
|
||||
virtual void Resume();
|
||||
|
||||
// Tells our nsMediaStream to put all loads in the background.
|
||||
virtual void MoveLoadsToBackground();
|
||||
|
||||
protected:
|
||||
|
||||
// Returns the monitor for other threads to synchronise access to
|
||||
|
@ -220,6 +220,9 @@ class nsWaveDecoder : public nsMediaDecoder
|
||||
// Change the element's ready state as necessary. Main thread only.
|
||||
void UpdateReadyStateForData();
|
||||
|
||||
// Tells mStream to put all loads in the background.
|
||||
virtual void MoveLoadsToBackground();
|
||||
|
||||
private:
|
||||
// Notifies the element that seeking has started.
|
||||
void SeekingStarted();
|
||||
|
@ -457,15 +457,27 @@ nsMediaChannelStream::CacheClientSeek(PRInt64 aOffset)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Don't call on main thread");
|
||||
|
||||
nsLoadFlags loadFlags =
|
||||
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
|
||||
(mLoadInBackground ? nsIRequest::LOAD_BACKGROUND : 0);
|
||||
|
||||
CloseChannel();
|
||||
if (!mDecoder->GetMediaElement()) {
|
||||
|
||||
nsHTMLMediaElement* element = mDecoder->GetMediaElement();
|
||||
if (!element) {
|
||||
// The decoder is being shut down, so don't bother opening a new channel
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = element->GetDocumentLoadGroup();
|
||||
NS_ENSURE_TRUE(loadGroup, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsresult rv =
|
||||
NS_NewChannel(getter_AddRefs(mChannel), mURI, nsnull, nsnull, nsnull,
|
||||
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
|
||||
NS_NewChannel(getter_AddRefs(mChannel),
|
||||
mURI,
|
||||
nsnull,
|
||||
loadGroup,
|
||||
nsnull,
|
||||
loadFlags);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
return OpenChannel(nsnull, aOffset);
|
||||
@ -789,10 +801,13 @@ nsMediaStream::Open(nsMediaDecoder* aDecoder, nsIURI* aURI,
|
||||
if (aChannel) {
|
||||
channel = aChannel;
|
||||
} else {
|
||||
nsHTMLMediaElement* element = aDecoder->GetMediaElement();
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = element->GetDocumentLoadGroup();
|
||||
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
aURI,
|
||||
nsnull,
|
||||
nsnull,
|
||||
loadGroup,
|
||||
nsnull,
|
||||
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -826,3 +841,44 @@ already_AddRefed<nsIPrincipal> nsMediaStream::GetCurrentPrincipal()
|
||||
secMan->GetChannelPrincipal(mChannel, getter_AddRefs(principal));
|
||||
return principal.forget();
|
||||
}
|
||||
|
||||
void nsMediaStream::MoveLoadsToBackground() {
|
||||
NS_ASSERTION(!mLoadInBackground, "Why are you calling this more than once?");
|
||||
mLoadInBackground = PR_TRUE;
|
||||
if (!mChannel) {
|
||||
// No channel, resource is probably already loaded.
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsHTMLMediaElement* element = mDecoder->GetMediaElement();
|
||||
if (!element) {
|
||||
NS_WARNING("Null element in nsMediaStream::MoveLoadsToBackground()");
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
rv = mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetLoadGroup() failed!");
|
||||
nsresult status;
|
||||
mChannel->GetStatus(&status);
|
||||
// Note: if (NS_FAILED(status)), the channel won't be in the load group.
|
||||
PRBool isPending = PR_FALSE;
|
||||
if (loadGroup &&
|
||||
NS_SUCCEEDED(status) &&
|
||||
NS_SUCCEEDED(mChannel->IsPending(&isPending)) &&
|
||||
isPending) {
|
||||
rv = loadGroup->RemoveRequest(mChannel, nsnull, status);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "RemoveRequest() failed!");
|
||||
|
||||
nsLoadFlags loadFlags;
|
||||
rv = mChannel->GetLoadFlags(&loadFlags);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetLoadFlags() failed!");
|
||||
|
||||
loadFlags |= nsIRequest::LOAD_BACKGROUND;
|
||||
rv = mChannel->SetLoadFlags(loadFlags);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "SetLoadFlags() failed!");
|
||||
|
||||
rv = loadGroup->AddRequest(mChannel, nsnull);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "AddRequest() failed!");
|
||||
}
|
||||
}
|
||||
|
@ -1991,3 +1991,11 @@ void nsOggDecoder::StartProgressUpdates()
|
||||
mDecoderPosition = mPlaybackPosition = mReader->Stream()->Tell();
|
||||
}
|
||||
}
|
||||
|
||||
void nsOggDecoder::MoveLoadsToBackground()
|
||||
{
|
||||
if (mReader && mReader->Stream()) {
|
||||
mReader->Stream()->MoveLoadsToBackground();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1622,3 +1622,11 @@ nsWaveDecoder::Resume()
|
||||
mStream->Resume();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsWaveDecoder::MoveLoadsToBackground()
|
||||
{
|
||||
if (mStream) {
|
||||
mStream->MoveLoadsToBackground();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user