mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 448603. Support direct loading of Ogg audio and video files by creating a synthetic <video> document. r=doublec,sr=bzbarsky
This commit is contained in:
parent
d0fa1eee37
commit
c98e2689e7
@ -281,6 +281,15 @@
|
||||
|
||||
#endif // MOZ_SVG
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
|
||||
// {d899a152-9412-46b2-b651-2e71c5c2f05f}
|
||||
#define NS_VIDEODOCUMENT_CID \
|
||||
{ 0xd899a152, 0x9412, 0x46b2, \
|
||||
{ 0xb6, 0x51, 0x2e, 0x71, 0xc5, 0xc2, 0xf0, 0x5f } }
|
||||
|
||||
#endif
|
||||
|
||||
#define NS_SYNCLOADDOMSERVICE_CID \
|
||||
{ /* 0e4e7d00-f71a-439f-9178-1a71ff11b55f */ \
|
||||
0x0e4e7d00, 0xf71a, 0x439f, \
|
||||
|
@ -1262,6 +1262,11 @@ NS_NewSVGDocument(nsIDocument** aInstancePtrResult);
|
||||
nsresult
|
||||
NS_NewImageDocument(nsIDocument** aInstancePtrResult);
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
nsresult
|
||||
NS_NewVideoDocument(nsIDocument** aInstancePtrResult);
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager);
|
||||
|
@ -72,6 +72,4 @@ public:
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
protected:
|
||||
virtual nsresult InitializeDecoder(nsAString& aChosenMediaResource);
|
||||
};
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nsIDOMHTMLMediaElement.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsMediaDecoder.h"
|
||||
#include "nsIChannel.h"
|
||||
|
||||
// Define to output information on decoding and painting framerate
|
||||
/* #define DEBUG_FRAME_RATE 1 */
|
||||
@ -51,6 +52,16 @@ public:
|
||||
nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParser = PR_FALSE);
|
||||
virtual ~nsHTMLMediaElement();
|
||||
|
||||
/**
|
||||
* This is used when the browser is constructing a video element to play
|
||||
* a channel that we've already started loading. The src attribute and
|
||||
* <source> children are ignored.
|
||||
* @param aChannel the channel to use
|
||||
* @param aListener returns a stream listener that should receive
|
||||
* notifications for the stream
|
||||
*/
|
||||
nsresult LoadWithChannel(nsIChannel *aChannel, nsIStreamListener **aListener);
|
||||
|
||||
// nsIDOMHTMLMediaElement
|
||||
NS_DECL_NSIDOMHTMLMEDIAELEMENT
|
||||
|
||||
@ -147,9 +158,40 @@ public:
|
||||
void Freeze();
|
||||
void Thaw();
|
||||
|
||||
// Returns true if we can handle this MIME type in a <video> or <audio>
|
||||
// element
|
||||
static PRBool CanHandleMediaType(const char* aMIMEType);
|
||||
|
||||
/**
|
||||
* Initialize data for available media types
|
||||
*/
|
||||
static void InitMediaTypes();
|
||||
/**
|
||||
* Shutdown data for available media types
|
||||
*/
|
||||
static void ShutdownMediaTypes();
|
||||
|
||||
protected:
|
||||
nsresult PickMediaElement(nsAString& aChosenMediaResource);
|
||||
virtual nsresult InitializeDecoder(nsAString& aChosenMediaResource);
|
||||
/**
|
||||
* Figure out which resource to load (either the 'src' attribute or
|
||||
* a <source> child) and create the decoder for it.
|
||||
*/
|
||||
nsresult PickMediaElement();
|
||||
/**
|
||||
* Create a decoder for the given aMIMEType. Returns false if we
|
||||
* were unable to create the decoder.
|
||||
*/
|
||||
PRBool CreateDecoder(const nsACString& aMIMEType);
|
||||
/**
|
||||
* Initialize a decoder to load the given URI.
|
||||
*/
|
||||
nsresult InitializeDecoder(const nsAString& aURISpec);
|
||||
/**
|
||||
* Initialize a decoder to load the given channel. The decoder's stream
|
||||
* listener is returned via aListener.
|
||||
*/
|
||||
nsresult InitializeDecoderForChannel(nsIChannel *aChannel,
|
||||
nsIStreamListener **aListener);
|
||||
|
||||
nsRefPtr<nsMediaDecoder> mDecoder;
|
||||
|
||||
|
@ -73,8 +73,4 @@ public:
|
||||
// Returns the current video frame width and height.
|
||||
// If there is no video frame, returns the given default size.
|
||||
nsIntSize GetVideoSize(nsIntSize defaultSize);
|
||||
|
||||
protected:
|
||||
virtual nsresult InitializeDecoder(nsAString& aChosenMediaResource);
|
||||
|
||||
};
|
||||
|
@ -110,11 +110,3 @@ void nsHTMLAudioElement::UnbindFromTree(PRBool aDeep,
|
||||
|
||||
nsHTMLMediaElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsresult nsHTMLAudioElement::InitializeDecoder(nsAString& aChosenMediaResource)
|
||||
{
|
||||
if (mDecoder)
|
||||
mDecoder->ElementAvailable(this);
|
||||
|
||||
return nsHTMLMediaElement::InitializeDecoder(aChosenMediaResource);
|
||||
}
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIDOMProgressEvent.h"
|
||||
#include "nsHTMLMediaError.h"
|
||||
#include "nsICategoryManager.h"
|
||||
|
||||
#ifdef MOZ_OGG
|
||||
#include "nsOggDecoder.h"
|
||||
@ -220,6 +221,19 @@ NS_IMETHODIMP nsHTMLMediaElement::GetTotalBytes(PRUint32 *aTotalBytes)
|
||||
/* void load (); */
|
||||
NS_IMETHODIMP nsHTMLMediaElement::Load()
|
||||
{
|
||||
return LoadWithChannel(nsnull, nsnull);
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::LoadWithChannel(nsIChannel *aChannel,
|
||||
nsIStreamListener **aListener)
|
||||
{
|
||||
NS_ASSERTION((aChannel == nsnull) == (aListener == nsnull),
|
||||
"channel and listener should both be null or both non-null");
|
||||
|
||||
if (aListener) {
|
||||
*aListener = nsnull;
|
||||
}
|
||||
|
||||
if (mBegun) {
|
||||
mBegun = PR_FALSE;
|
||||
|
||||
@ -245,14 +259,12 @@ NS_IMETHODIMP nsHTMLMediaElement::Load()
|
||||
DispatchSimpleEvent(NS_LITERAL_STRING("emptied"));
|
||||
}
|
||||
|
||||
nsAutoString chosenMediaResource;
|
||||
nsresult rv = PickMediaElement(chosenMediaResource);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mNetworkState = nsIDOMHTMLMediaElement::LOADING;
|
||||
|
||||
// This causes the currentSrc attribute to become valid
|
||||
rv = InitializeDecoder(chosenMediaResource);
|
||||
nsresult rv;
|
||||
if (aChannel) {
|
||||
rv = InitializeDecoderForChannel(aChannel, aListener);
|
||||
} else {
|
||||
rv = PickMediaElement();
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mBegun = PR_TRUE;
|
||||
@ -564,7 +576,8 @@ nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aPar
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mIsDoneAddingChildren && mNetworkState == nsIDOMHTMLMediaElement::EMPTY) {
|
||||
if (mIsDoneAddingChildren &&
|
||||
mNetworkState == nsIDOMHTMLMediaElement::EMPTY) {
|
||||
Load();
|
||||
}
|
||||
|
||||
@ -580,16 +593,98 @@ void nsHTMLMediaElement::UnbindFromTree(PRBool aDeep,
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
#ifdef MOZ_OGG
|
||||
static const char gOggTypes[][16] = {
|
||||
"video/ogg",
|
||||
"audio/ogg",
|
||||
"application/ogg"
|
||||
};
|
||||
|
||||
nsresult nsHTMLMediaElement::PickMediaElement(nsAString& aChosenMediaResource)
|
||||
static PRBool IsOggType(const nsACString& aType)
|
||||
{
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(gOggTypes); ++i) {
|
||||
if (aType.EqualsASCII(gOggTypes[i]))
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* static */
|
||||
PRBool nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType)
|
||||
{
|
||||
#ifdef MOZ_OGG
|
||||
if (IsOggType(nsDependentCString(aMIMEType)))
|
||||
return PR_TRUE;
|
||||
#endif
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void nsHTMLMediaElement::InitMediaTypes()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
#ifdef MOZ_OGG
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(gOggTypes); i++) {
|
||||
catMan->AddCategoryEntry("Gecko-Content-Viewers", gOggTypes[i],
|
||||
"@mozilla.org/content/document-loader-factory;1",
|
||||
PR_FALSE, PR_TRUE, nsnull);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void nsHTMLMediaElement::ShutdownMediaTypes()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
#ifdef MOZ_OGG
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(gOggTypes); i++) {
|
||||
catMan->DeleteCategoryEntry("Gecko-Content-Viewers", gOggTypes[i], PR_FALSE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsHTMLMediaElement::CreateDecoder(const nsACString& aType)
|
||||
{
|
||||
#ifdef MOZ_OGG
|
||||
if (IsOggType(aType)) {
|
||||
mDecoder = new nsOggDecoder();
|
||||
if (mDecoder && !mDecoder->Init()) {
|
||||
mDecoder = nsnull;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return mDecoder != nsnull;
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
|
||||
nsIStreamListener **aListener)
|
||||
{
|
||||
nsCAutoString mimeType;
|
||||
aChannel->GetContentType(mimeType);
|
||||
|
||||
if (!CreateDecoder(mimeType))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mNetworkState = nsIDOMHTMLMediaElement::LOADING;
|
||||
mDecoder->ElementAvailable(this);
|
||||
|
||||
return mDecoder->Load(nsnull, aChannel, aListener);
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::PickMediaElement()
|
||||
{
|
||||
// Implements:
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#pick-a
|
||||
nsAutoString src;
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
|
||||
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
|
||||
aChosenMediaResource = src;
|
||||
|
||||
#ifdef MOZ_OGG
|
||||
// Currently assuming an Ogg file
|
||||
// TODO: Instantiate decoder based on type
|
||||
@ -604,7 +699,7 @@ nsresult nsHTMLMediaElement::PickMediaElement(nsAString& aChosenMediaResource)
|
||||
mDecoder = nsnull;
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
return InitializeDecoder(src);
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,31 +714,22 @@ nsresult nsHTMLMediaElement::PickMediaElement(nsAString& aChosenMediaResource)
|
||||
if (source) {
|
||||
if (source->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
|
||||
nsAutoString type;
|
||||
|
||||
if (source->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type)) {
|
||||
#if MOZ_OGG
|
||||
if (type.EqualsLiteral("video/ogg") || type.EqualsLiteral("application/ogg")) {
|
||||
nsAutoString src;
|
||||
if (source->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
|
||||
mDecoder = new nsOggDecoder();
|
||||
if (mDecoder && !mDecoder->Init()) {
|
||||
mDecoder = nsnull;
|
||||
}
|
||||
aChosenMediaResource = src;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
nsAutoString src;
|
||||
if (source->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type) &&
|
||||
source->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src) &&
|
||||
CreateDecoder(NS_ConvertUTF16toUTF8(type)))
|
||||
return InitializeDecoder(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::InitializeDecoder(nsAString& aChosenMediaResource)
|
||||
nsresult nsHTMLMediaElement::InitializeDecoder(const nsAString& aURISpec)
|
||||
{
|
||||
mNetworkState = nsIDOMHTMLMediaElement::LOADING;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = GetOwnerDoc();
|
||||
if (!doc) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
@ -653,15 +739,15 @@ nsresult nsHTMLMediaElement::InitializeDecoder(nsAString& aChosenMediaResource)
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIURI> baseURL = GetBaseURI();
|
||||
const nsAFlatCString &charset = doc->GetDocumentCharacterSet();
|
||||
rv = NS_NewURI(getter_AddRefs(uri),
|
||||
aChosenMediaResource,
|
||||
rv = NS_NewURI(getter_AddRefs(uri), aURISpec,
|
||||
charset.IsEmpty() ? nsnull : charset.get(),
|
||||
baseURL,
|
||||
nsContentUtils::GetIOService());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mDecoder) {
|
||||
rv = mDecoder->Load(uri);
|
||||
mDecoder->ElementAvailable(this);
|
||||
rv = mDecoder->Load(uri, nsnull, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
mDecoder = nsnull;
|
||||
}
|
||||
|
@ -134,12 +134,3 @@ void nsHTMLVideoElement::UnbindFromTree(PRBool aDeep,
|
||||
if (mDecoder)
|
||||
mDecoder->ElementUnavailable();
|
||||
}
|
||||
|
||||
nsresult nsHTMLVideoElement::InitializeDecoder(nsAString& aChosenMediaResource)
|
||||
{
|
||||
if (mDecoder)
|
||||
mDecoder->ElementAvailable(this);
|
||||
|
||||
return nsHTMLMediaElement::InitializeDecoder(aChosenMediaResource);
|
||||
}
|
||||
|
||||
|
@ -81,13 +81,17 @@ CPPSRCS = \
|
||||
nsHTMLContentSink.cpp \
|
||||
nsHTMLFragmentContentSink.cpp \
|
||||
nsHTMLDocument.cpp \
|
||||
nsImageDocument.cpp \
|
||||
nsMediaDocument.cpp \
|
||||
nsPluginDocument.cpp \
|
||||
nsImageDocument.cpp \
|
||||
nsWyciwygChannel.cpp \
|
||||
nsWyciwygProtocolHandler.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_MEDIA
|
||||
CPPSRCS += nsVideoDocument.cpp
|
||||
endif
|
||||
|
||||
EXPORTS = \
|
||||
nsIHTMLDocument.h \
|
||||
$(NULL)
|
||||
|
@ -120,7 +120,7 @@ public:
|
||||
|
||||
friend class ImageListener;
|
||||
protected:
|
||||
nsresult CreateSyntheticDocument();
|
||||
virtual nsresult CreateSyntheticDocument();
|
||||
|
||||
nsresult CheckOverflowing(PRBool changeState);
|
||||
|
||||
|
@ -105,7 +105,6 @@ public:
|
||||
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
protected:
|
||||
nsRefPtr<nsMediaDocument> mDocument;
|
||||
nsCOMPtr<nsIStreamListener> mNextStream;
|
||||
};
|
||||
|
140
content/html/document/src/nsVideoDocument.cpp
Normal file
140
content/html/document/src/nsVideoDocument.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsMediaDocument.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsHTMLMediaElement.h"
|
||||
|
||||
class nsVideoDocument : public nsMediaDocument
|
||||
{
|
||||
public:
|
||||
virtual nsresult StartDocumentLoad(const char* aCommand,
|
||||
nsIChannel* aChannel,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
nsISupports* aContainer,
|
||||
nsIStreamListener** aDocListener,
|
||||
PRBool aReset = PR_TRUE,
|
||||
nsIContentSink* aSink = nsnull);
|
||||
|
||||
protected:
|
||||
nsresult CreateSyntheticVideoDocument(nsIChannel* aChannel,
|
||||
nsIStreamListener** aListener);
|
||||
|
||||
nsRefPtr<nsMediaDocumentStreamListener> mStreamListener;
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsVideoDocument::StartDocumentLoad(const char* aCommand,
|
||||
nsIChannel* aChannel,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
nsISupports* aContainer,
|
||||
nsIStreamListener** aDocListener,
|
||||
PRBool aReset,
|
||||
nsIContentSink* aSink)
|
||||
{
|
||||
nsresult rv =
|
||||
nsMediaDocument::StartDocumentLoad(aCommand, aChannel, aLoadGroup,
|
||||
aContainer, aDocListener, aReset,
|
||||
aSink);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mStreamListener = new nsMediaDocumentStreamListener(this);
|
||||
if (!mStreamListener)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Create synthetic document
|
||||
rv = CreateSyntheticVideoDocument(aChannel,
|
||||
getter_AddRefs(mStreamListener->mNextStream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(*aDocListener = mStreamListener);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsVideoDocument::CreateSyntheticVideoDocument(nsIChannel* aChannel,
|
||||
nsIStreamListener** aListener)
|
||||
{
|
||||
// make our generic document
|
||||
nsresult rv = nsMediaDocument::CreateSyntheticDocument();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIContent* body = GetBodyContent();
|
||||
if (!body) {
|
||||
NS_WARNING("no body on video document!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// make content
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::video, nsnull,
|
||||
kNameSpaceID_None);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
|
||||
|
||||
nsRefPtr<nsHTMLMediaElement> element =
|
||||
static_cast<nsHTMLMediaElement*>(NS_NewHTMLVideoElement(nodeInfo, PR_FALSE));
|
||||
if (!element)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
element->SetAutoplay(PR_TRUE);
|
||||
element->SetControls(PR_TRUE);
|
||||
element->LoadWithChannel(aChannel, aListener);
|
||||
|
||||
return body->AppendChildTo(element, PR_FALSE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewVideoDocument(nsIDocument** aResult)
|
||||
{
|
||||
nsVideoDocument* doc = new nsVideoDocument();
|
||||
if (!doc) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(doc);
|
||||
nsresult rv = doc->Init();
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(doc);
|
||||
}
|
||||
|
||||
*aResult = doc;
|
||||
|
||||
return rv;
|
||||
}
|
@ -44,14 +44,24 @@
|
||||
|
||||
#include "oggplay/oggplay.h"
|
||||
|
||||
class nsIChannel;
|
||||
class nsIStreamListener;
|
||||
|
||||
class nsChannelReader : public OggPlayReader
|
||||
{
|
||||
public:
|
||||
nsChannelReader();
|
||||
~nsChannelReader();
|
||||
|
||||
// Initialize the reader with the given decoder and URI.
|
||||
nsresult Init(nsMediaDecoder* aDecoder, nsIURI* aURI);
|
||||
/**
|
||||
* Initialize the reader with the given decoder, URI, and
|
||||
* optional channel.
|
||||
* @param aChannel may be null
|
||||
* @param aStreamListener if aChannel is non-null, this will return
|
||||
* a stream listener which should be attached to the channel.
|
||||
*/
|
||||
nsresult Init(nsMediaDecoder* aDecoder, nsIURI* aURI, nsIChannel* aChannel,
|
||||
nsIStreamListener** aStreamListener);
|
||||
|
||||
// Cancel any blocking request currently in progress and cause that
|
||||
// request to return an error. Call on main thread only.
|
||||
|
@ -109,10 +109,13 @@ class nsMediaDecoder : public nsIObserver
|
||||
// Stop playback of a video, and stop download of video stream.
|
||||
virtual void Stop() = 0;
|
||||
|
||||
// Start downloading the video at the given URI. Decode
|
||||
// the downloaded data up to the point of the first frame
|
||||
// of data.
|
||||
virtual nsresult Load(nsIURI* aURI) = 0;
|
||||
// Start downloading the video. Decode the downloaded data up to the
|
||||
// point of the first frame of data.
|
||||
// Exactly one of aURI and aChannel must be null. aListener must be
|
||||
// null if and only if aChannel is.
|
||||
virtual nsresult Load(nsIURI* aURI,
|
||||
nsIChannel* aChannel,
|
||||
nsIStreamListener **aListener) = 0;
|
||||
|
||||
// Draw the latest video data. This is done
|
||||
// here instead of in nsVideoFrame so that the lock around the
|
||||
|
@ -70,7 +70,14 @@ public:
|
||||
|
||||
// These methods have the same thread calling requirements
|
||||
// as those with the same name in nsMediaStream
|
||||
virtual nsresult Open() = 0;
|
||||
|
||||
/**
|
||||
* @param aStreamListener if null, the strategy should open mChannel
|
||||
* itself. Otherwise, mChannel is already open and the strategy
|
||||
* should just return its stream listener in aStreamListener (or set
|
||||
* *aStreamListener to null, if it doesn't need a listener).
|
||||
*/
|
||||
virtual nsresult Open(nsIStreamListener** aStreamListener) = 0;
|
||||
virtual nsresult Close() = 0;
|
||||
virtual nsresult Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes) = 0;
|
||||
virtual nsresult Seek(PRInt32 aWhence, PRInt64 aOffset) = 0;
|
||||
@ -121,9 +128,15 @@ class nsMediaStream
|
||||
nsMediaStream();
|
||||
~nsMediaStream();
|
||||
|
||||
// Create a channel for the stream, reading data from the
|
||||
// media resource at the URI. Call on main thread only.
|
||||
nsresult Open(nsMediaDecoder *aDecoder, nsIURI* aURI);
|
||||
/**
|
||||
* Create a channel for the stream, reading data from the
|
||||
* media resource at the URI. Call on main thread only.
|
||||
* @param aChannel if non-null, this channel is used and aListener
|
||||
* is set to the listener we want for the channel. aURI must
|
||||
* be the URI for the channel, obtained via NS_GetFinalChannelURI.
|
||||
*/
|
||||
nsresult Open(nsMediaDecoder* aDecoder, nsIURI* aURI,
|
||||
nsIChannel* aChannel, nsIStreamListener** aListener);
|
||||
|
||||
// Close the stream, stop any listeners, channels, etc.
|
||||
// Call on main thread only.
|
||||
|
@ -297,34 +297,33 @@ class nsOggDecoder : public nsMediaDecoder
|
||||
|
||||
// This method must be called by the owning object before that
|
||||
// object disposes of this decoder object.
|
||||
void Shutdown();
|
||||
virtual void Shutdown();
|
||||
|
||||
float GetCurrentTime();
|
||||
virtual float GetCurrentTime();
|
||||
|
||||
// Start downloading the video at the given URI. Decode
|
||||
// the downloaded data up to the point of the first frame
|
||||
// of data.
|
||||
nsresult Load(nsIURI* aURI);
|
||||
virtual nsresult Load(nsIURI* aURI,
|
||||
nsIChannel* aChannel,
|
||||
nsIStreamListener **aListener);
|
||||
|
||||
// Start playback of a video. 'Load' must have previously been
|
||||
// called.
|
||||
nsresult Play();
|
||||
virtual nsresult Play();
|
||||
|
||||
// Stop playback of a video, and stop download of video stream.
|
||||
virtual void Stop();
|
||||
|
||||
// Seek to the time position in (seconds) from the start of the video.
|
||||
nsresult Seek(float time);
|
||||
virtual nsresult Seek(float time);
|
||||
|
||||
nsresult PlaybackRateChanged();
|
||||
virtual nsresult PlaybackRateChanged();
|
||||
|
||||
void Pause();
|
||||
float GetVolume();
|
||||
void SetVolume(float volume);
|
||||
float GetDuration();
|
||||
virtual void Pause();
|
||||
virtual float GetVolume();
|
||||
virtual void SetVolume(float volume);
|
||||
virtual float GetDuration();
|
||||
|
||||
void GetCurrentURI(nsIURI** aURI);
|
||||
nsIPrincipal* GetCurrentPrincipal();
|
||||
virtual void GetCurrentURI(nsIURI** aURI);
|
||||
virtual nsIPrincipal* GetCurrentPrincipal();
|
||||
|
||||
virtual void UpdateBytesDownloaded(PRUint64 aBytes);
|
||||
|
||||
|
@ -147,10 +147,12 @@ static int oggplay_channel_reader_duration(OggPlayReader* aReader)
|
||||
return me->duration();
|
||||
}
|
||||
|
||||
nsresult nsChannelReader::Init(nsMediaDecoder* aDecoder, nsIURI* aURI)
|
||||
nsresult nsChannelReader::Init(nsMediaDecoder* aDecoder, nsIURI* aURI,
|
||||
nsIChannel* aChannel,
|
||||
nsIStreamListener** aStreamListener)
|
||||
{
|
||||
mCurrentPosition = 0;
|
||||
return mStream.Open(aDecoder, aURI);
|
||||
return mStream.Open(aDecoder, aURI, aChannel, aStreamListener);
|
||||
}
|
||||
|
||||
nsChannelReader::~nsChannelReader()
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
|
||||
// These methods have the same thread calling requirements
|
||||
// as those with the same name in nsMediaStream
|
||||
virtual nsresult Open();
|
||||
virtual nsresult Open(nsIStreamListener** aStreamListener);
|
||||
virtual nsresult Close();
|
||||
virtual nsresult Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes);
|
||||
virtual nsresult Seek(PRInt32 aWhence, PRInt64 aOffset);
|
||||
@ -89,19 +89,26 @@ private:
|
||||
nsCOMPtr<nsIInputStream> mPipeInput;
|
||||
};
|
||||
|
||||
nsresult nsDefaultStreamStrategy::Open()
|
||||
nsresult nsDefaultStreamStrategy::Open(nsIStreamListener** aStreamListener)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aStreamListener) {
|
||||
*aStreamListener = nsnull;
|
||||
}
|
||||
|
||||
mListener = new nsChannelToPipeListener(mDecoder);
|
||||
NS_ENSURE_TRUE(mListener, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = mListener->Init();
|
||||
nsresult rv = mListener->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mChannel->AsyncOpen(mListener, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
||||
if (aStreamListener) {
|
||||
*aStreamListener = mListener;
|
||||
NS_ADDREF(mListener);
|
||||
} else {
|
||||
rv = mChannel->AsyncOpen(mListener, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = mListener->GetInputStream(getter_AddRefs(mPipeInput));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -189,7 +196,7 @@ public:
|
||||
|
||||
// These methods have the same thread calling requirements
|
||||
// as those with the same name in nsMediaStream
|
||||
virtual nsresult Open();
|
||||
virtual nsresult Open(nsIStreamListener** aStreamListener);
|
||||
virtual nsresult Close();
|
||||
virtual nsresult Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes);
|
||||
virtual nsresult Seek(PRInt32 aWhence, PRInt64 aOffset);
|
||||
@ -211,35 +218,54 @@ private:
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
nsresult nsFileStreamStrategy::Open()
|
||||
nsresult nsFileStreamStrategy::Open(nsIStreamListener** aStreamListener)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aStreamListener) {
|
||||
*aStreamListener = nsnull;
|
||||
}
|
||||
|
||||
rv = mChannel->Open(getter_AddRefs(mInput));
|
||||
nsresult rv;
|
||||
if (aStreamListener) {
|
||||
// The channel is already open. We need a synchronous stream that
|
||||
// implements nsISeekableStream, so we have to find the underlying
|
||||
// file and reopen it
|
||||
nsCOMPtr<nsIFileChannel> fc(do_QueryInterface(mChannel));
|
||||
if (!fc)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
rv = fc->GetFile(getter_AddRefs(file));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(mInput), file);
|
||||
} else {
|
||||
rv = mChannel->Open(getter_AddRefs(mInput));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mSeekable = do_QueryInterface(mInput);
|
||||
if (!mSeekable) {
|
||||
// XXX The file may just be a .url or similar
|
||||
// shortcut that points to a Web site. We need to fix this by
|
||||
// doing an async open and waiting until we locate the real resource,
|
||||
// then using that (if it's still a file!).
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Get the file size and inform the decoder
|
||||
nsCOMPtr<nsIFileChannel> fc(do_QueryInterface(mChannel));
|
||||
if (fc) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
rv = fc->GetFile(getter_AddRefs(file));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRInt64 size = 0;
|
||||
rv = file->GetFileSize(&size);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDecoder->SetTotalBytes(size);
|
||||
}
|
||||
}
|
||||
// Get the file size and inform the decoder. Only files up to 4GB are
|
||||
// supported here.
|
||||
PRUint32 size;
|
||||
rv = mInput->Available(&size);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mDecoder->SetTotalBytes(size);
|
||||
}
|
||||
|
||||
/* Get our principal */
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService("@mozilla.org/scriptsecuritymanager;1");
|
||||
if (secMan) {
|
||||
nsresult rv = secMan->GetChannelPrincipal(mChannel,
|
||||
getter_AddRefs(mPrincipal));
|
||||
rv = secMan->GetChannelPrincipal(mChannel,
|
||||
getter_AddRefs(mPrincipal));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -251,7 +277,7 @@ nsresult nsFileStreamStrategy::Open()
|
||||
NS_NEW_RUNNABLE_METHOD(nsMediaDecoder, mDecoder, ResourceLoaded);
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
|
||||
return mSeekable ? NS_OK : NS_ERROR_FAILURE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsFileStreamStrategy::Close()
|
||||
@ -324,7 +350,7 @@ public:
|
||||
|
||||
// These methods have the same thread calling requirements
|
||||
// as those with the same name in nsMediaStream
|
||||
virtual nsresult Open();
|
||||
virtual nsresult Open(nsIStreamListener** aListener);
|
||||
virtual nsresult Close();
|
||||
virtual nsresult Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes);
|
||||
virtual nsresult Seek(PRInt32 aWhence, PRInt64 aOffset);
|
||||
@ -383,18 +409,25 @@ void nsHttpStreamStrategy::Reset(nsIChannel* aChannel,
|
||||
mPipeInput = aStream;
|
||||
}
|
||||
|
||||
nsresult nsHttpStreamStrategy::Open()
|
||||
nsresult nsHttpStreamStrategy::Open(nsIStreamListener **aStreamListener)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aStreamListener) {
|
||||
*aStreamListener = nsnull;
|
||||
}
|
||||
|
||||
mListener = new nsChannelToPipeListener(mDecoder);
|
||||
NS_ENSURE_TRUE(mListener, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = mListener->Init();
|
||||
nsresult rv = mListener->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mChannel->AsyncOpen(mListener, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aStreamListener) {
|
||||
*aStreamListener = mListener;
|
||||
NS_ADDREF(*aStreamListener);
|
||||
} else {
|
||||
rv = mChannel->AsyncOpen(mListener, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = mListener->GetInputStream(getter_AddRefs(mPipeInput));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -684,21 +717,24 @@ nsMediaStream::~nsMediaStream()
|
||||
MOZ_COUNT_DTOR(nsMediaStream);
|
||||
}
|
||||
|
||||
nsresult nsMediaStream::Open(nsMediaDecoder* aDecoder, nsIURI* aURI)
|
||||
nsresult nsMediaStream::Open(nsMediaDecoder* aDecoder, nsIURI* aURI,
|
||||
nsIChannel* aChannel, nsIStreamListener** aListener)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(),
|
||||
"nsMediaStream::Open called on non-main thread");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
aURI,
|
||||
nsnull,
|
||||
nsnull,
|
||||
nsnull,
|
||||
nsIRequest::LOAD_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aChannel) {
|
||||
channel = aChannel;
|
||||
} else {
|
||||
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
aURI,
|
||||
nsnull,
|
||||
nsnull,
|
||||
nsnull,
|
||||
nsIRequest::LOAD_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(channel);
|
||||
nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(channel);
|
||||
@ -712,7 +748,7 @@ nsresult nsMediaStream::Open(nsMediaDecoder* aDecoder, nsIURI* aURI)
|
||||
mPlaybackRateCount = 0;
|
||||
mPlaybackRateStart = PR_IntervalNow();
|
||||
|
||||
return mStreamStrategy->Open();
|
||||
return mStreamStrategy->Open(aListener);
|
||||
}
|
||||
|
||||
nsresult nsMediaStream::Close()
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsOggDecoder.h"
|
||||
|
||||
/*
|
||||
@ -1165,10 +1166,26 @@ nsOggDecoder::~nsOggDecoder()
|
||||
nsAutoMonitor::DestroyMonitor(mMonitor);
|
||||
}
|
||||
|
||||
nsresult nsOggDecoder::Load(nsIURI* aURI)
|
||||
nsresult nsOggDecoder::Load(nsIURI* aURI, nsIChannel* aChannel,
|
||||
nsIStreamListener** aStreamListener)
|
||||
{
|
||||
nsresult rv;
|
||||
mURI = aURI;
|
||||
if (aStreamListener) {
|
||||
*aStreamListener = nsnull;
|
||||
}
|
||||
|
||||
if (aURI) {
|
||||
NS_ASSERTION(!aStreamListener, "No listener should be requested here");
|
||||
mURI = aURI;
|
||||
} else {
|
||||
NS_ASSERTION(aChannel, "Either a URI or a channel is required");
|
||||
NS_ASSERTION(aStreamListener, "A listener should be requested here");
|
||||
|
||||
// If the channel was redirected, we want the post-redirect URI;
|
||||
// but if the URI scheme was expanded, say from chrome: to jar:file:,
|
||||
// we want the original URI.
|
||||
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(mURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
StartProgress();
|
||||
|
||||
@ -1177,7 +1194,7 @@ nsresult nsOggDecoder::Load(nsIURI* aURI)
|
||||
mReader = new nsChannelReader();
|
||||
NS_ENSURE_TRUE(mReader, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = mReader->Init(this, aURI);
|
||||
nsresult rv = mReader->Init(this, mURI, aChannel, aStreamListener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = NS_NewThread(getter_AddRefs(mDecodeThread));
|
||||
@ -1457,9 +1474,12 @@ void nsOggDecoder::ChangeState(PlayState aState)
|
||||
// If we've completed playback then the decode and display threads
|
||||
// have been shutdown. To honor the state change request we need
|
||||
// to reload the resource and restart the threads.
|
||||
// Like seeking, this will require opening a new channel, which means
|
||||
// we may not actually get the same resource --- a server may send
|
||||
// us something different.
|
||||
mNextState = aState;
|
||||
mPlayState = PLAY_STATE_LOADING;
|
||||
Load(mURI);
|
||||
Load(mURI, nsnull, nsnull);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ _TEST_FILES = test_autoplay.html \
|
||||
test_seek6.html \
|
||||
test_seek7.html \
|
||||
test_seek8.html \
|
||||
test_standalone.html \
|
||||
test_timeupdate1.html \
|
||||
test_timeupdate2.html \
|
||||
test_timeupdate3.html \
|
||||
|
29
content/media/video/test/test_standalone.html
Normal file
29
content/media/video/test/test_standalone.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media test: standalone video documents</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="doTest()">
|
||||
|
||||
<iframe id="i" src="320x240.ogg"></iframe>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var elem = document.getElementById("i").contentDocument.body.firstChild;
|
||||
is(elem.tagName.toLowerCase(), "video", "Is video element");
|
||||
is(elem.currentSrc.substring(elem.currentSrc.length - 11), "320x240.ogg", "currentSrc");
|
||||
is(elem.controls, true, "Controls set");
|
||||
is(elem.autoplay, true, "Autoplay set");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -160,6 +160,7 @@ SHARED_LIBRARY_LIBS += \
|
||||
$(DEPTH)/media/libtheora/lib/$(LIB_PREFIX)theora.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/media/libvorbis/lib/$(LIB_PREFIX)vorbis.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
LOCAL_INCLUDES += -I$(DEPTH)/content/html/content/src
|
||||
endif
|
||||
|
||||
ifdef NS_PRINTING
|
||||
|
@ -56,6 +56,9 @@
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIViewSourceChannel.h"
|
||||
#ifdef MOZ_MEDIA
|
||||
#include "nsHTMLMediaElement.h"
|
||||
#endif
|
||||
|
||||
#include "imgILoader.h"
|
||||
#include "nsIParser.h"
|
||||
@ -78,6 +81,9 @@ static NS_DEFINE_IID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
|
||||
#ifdef MOZ_SVG
|
||||
static NS_DEFINE_IID(kSVGDocumentCID, NS_SVGDOCUMENT_CID);
|
||||
#endif
|
||||
#ifdef MOZ_MEDIA
|
||||
static NS_DEFINE_IID(kVideoDocumentCID, NS_VIDEODOCUMENT_CID);
|
||||
#endif
|
||||
static NS_DEFINE_IID(kImageDocumentCID, NS_IMAGEDOCUMENT_CID);
|
||||
static NS_DEFINE_IID(kXULDocumentCID, NS_XULDOCUMENT_CID);
|
||||
|
||||
@ -267,6 +273,15 @@ nsContentDLF::CreateInstance(const char* aCommand,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
if (nsHTMLMediaElement::CanHandleMediaType(aContentType)) {
|
||||
return CreateDocument(aCommand,
|
||||
aChannel, aLoadGroup,
|
||||
aContainer, kVideoDocumentCID,
|
||||
aDocListener, aDocViewer);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Try image types
|
||||
nsCOMPtr<imgILoader> loader(do_GetService("@mozilla.org/image/loader;1"));
|
||||
PRBool isReg = PR_FALSE;
|
||||
@ -286,7 +301,6 @@ nsContentDLF::CreateInstance(const char* aCommand,
|
||||
aDocListener, aDocViewer);
|
||||
}
|
||||
|
||||
|
||||
// If we get here, then we weren't able to create anything. Sorry!
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -530,6 +530,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsDataDocumentContentPolicy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsNoDataProtocolContentPolicy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSyncLoadService)
|
||||
MAKE_CTOR(CreatePluginDocument, nsIDocument, NS_NewPluginDocument)
|
||||
#ifdef MOZ_MEDIA
|
||||
MAKE_CTOR(CreateVideoDocument, nsIDocument, NS_NewVideoDocument)
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_CANVAS
|
||||
MAKE_CTOR(CreateCanvasRenderingContext2D, nsIDOMCanvasRenderingContext2D, NS_NewCanvasRenderingContext2D)
|
||||
@ -1282,6 +1285,13 @@ static const nsModuleComponentInfo gComponents[] = {
|
||||
nsnull,
|
||||
CreatePluginDocument },
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
{ "Video Document",
|
||||
NS_VIDEODOCUMENT_CID,
|
||||
nsnull,
|
||||
CreateVideoDocument },
|
||||
#endif
|
||||
|
||||
{ "Style sheet service",
|
||||
NS_STYLESHEETSERVICE_CID,
|
||||
NS_STYLESHEETSERVICE_CONTRACTID,
|
||||
|
@ -112,6 +112,7 @@ PRBool NS_SVGEnabled();
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
#include "nsMediaDecoder.h"
|
||||
#include "nsHTMLMediaElement.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_OGG
|
||||
@ -253,6 +254,7 @@ nsLayoutStatics::Initialize()
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsHTMLMediaElement::InitMediaTypes();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_OGG
|
||||
@ -339,6 +341,9 @@ nsLayoutStatics::Shutdown()
|
||||
|
||||
NS_ShutdownFocusSuppressor();
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
nsHTMLMediaElement::ShutdownMediaTypes();
|
||||
#endif
|
||||
#ifdef MOZ_OGG
|
||||
nsAudioStream::ShutdownLibrary();
|
||||
#endif
|
||||
|
@ -535,6 +535,9 @@ static nsExtraMimeTypeEntry extraMimeEntries [] =
|
||||
{ TEXT_XUL, "xul", "XML-Based User Interface Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
|
||||
{ TEXT_XML, "xml,xsl,xbl", "Extensible Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
|
||||
{ TEXT_CSS, "css", "Style Sheet", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
|
||||
{ "audio/ogg", "oga", "Ogg Audio", 0, 0 },
|
||||
{ "video/ogg", "ogv", "Ogg Video", 0, 0 },
|
||||
{ "audio/ogg", "ogg", "Ogg Audio", 0, 0 }
|
||||
};
|
||||
|
||||
#undef MAC_TYPE
|
||||
|
Loading…
Reference in New Issue
Block a user