Merge m-c to b2g-inbound on a CLOSED TREE. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-07-30 17:17:58 -04:00
commit 2eff86efc2
252 changed files with 5872 additions and 5597 deletions

View File

@ -4,9 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/accessibility'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.accessibility += [
'AccessFu.jsm',
'Constants.jsm',
'ContentControl.jsm',

View File

@ -8,8 +8,6 @@ BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
DIRS += ["source/modules/system"]
JS_MODULES_PATH = 'modules/sdk'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.sdk += [
'source/app-extension/bootstrap.js',
]

View File

@ -4,8 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/sdk/system'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.sdk.system += [
'XulApp.js',
]

View File

@ -489,6 +489,7 @@
@BINPATH@/components/nsInputListAutoComplete.js
@BINPATH@/components/formautofill.manifest
@BINPATH@/components/FormAutofillContentService.js
@BINPATH@/components/FormAutofillStartup.js
@BINPATH@/components/contentSecurityPolicy.manifest
@BINPATH@/components/contentSecurityPolicy.js
@BINPATH@/components/contentAreaDropListener.manifest

View File

@ -2536,7 +2536,7 @@ let BrowserOnClick = {
try {
let reportURL = formatURL("browser.safebrowsing.malware.reportURL", true);
reportURL += location;
content.location = reportURL;
gBrowser.loadURI(reportURL);
} catch (e) {
Components.utils.reportError("Couldn't get malware report URL: " + e);
}
@ -2561,7 +2561,7 @@ let BrowserOnClick = {
*/
onE10sAboutNewTab: function(event, ownerDoc) {
let isTopFrame = (ownerDoc.defaultView.parent === ownerDoc.defaultView);
if (!isTopFrame || event.button != 0) {
if (!isTopFrame) {
return;
}
@ -2570,7 +2570,8 @@ let BrowserOnClick = {
if (anchorTarget instanceof HTMLAnchorElement &&
anchorTarget.classList.contains("newtab-link")) {
event.preventDefault();
openUILinkIn(anchorTarget.href, "current");
let where = whereToOpenLink(event, false, false);
openUILinkIn(anchorTarget.href, where);
}
},
@ -2601,11 +2602,11 @@ let BrowserOnClick = {
// Allow users to override and continue through to the site,
// but add a notify bar as a reminder, so that they don't lose
// track after, e.g., tab switching.
gBrowser.loadURIWithFlags(content.location.href,
gBrowser.loadURIWithFlags(gBrowser.currentURI.spec,
nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
null, null, null);
Services.perms.add(makeURI(content.location.href), "safe-browsing",
Services.perms.add(gBrowser.currentURI, "safe-browsing",
Ci.nsIPermissionManager.ALLOW_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION);
@ -2677,7 +2678,7 @@ function getMeOutOfHere() {
} catch(e) {
Components.utils.reportError("Couldn't get homepage pref: " + e);
}
content.location = url;
gBrowser.loadURI(url);
}
function BrowserFullScreen()

View File

@ -917,22 +917,6 @@
cui-areatype="toolbar"
aboutHomeOverrideTooltip="&abouthome.pageTitle;"/>
<!-- XXX Bug 1013989 will provide a label for the button -->
<!-- This uses badged to be compatible with the social api code it shares.
We may also want it to be badged in the future, for notification
purposes. -->
<toolbarbutton id="loop-call-button"
class="toolbarbutton-1 chromeclass-toolbar-additional"
persist="class"
type="badged"
removable="true"
tooltiptext="&loopCallButton.tooltip;"
oncommand="LoopUI.openCallPanel(event);"
cui-areatype="toolbar"
>
</toolbarbutton>
<toolbarbutton id="social-share-button"
class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&sharePageCmd.label;"

View File

@ -52,7 +52,7 @@ const kSubviewEvents = [
* The current version. We can use this to auto-add new default widgets as necessary.
* (would be const but isn't because of testing purposes)
*/
let kVersion = 0;
let kVersion = 1;
/**
* gPalette is a map of every widget that CustomizableUI.jsm knows about, keyed

View File

@ -898,6 +898,28 @@ const CustomizableWidgets = [{
let win = aEvent.view;
win.MailIntegration.sendLinkForWindow(win.content);
}
}, {
id: "loop-call-button",
type: "custom",
// XXX Bug 1013989 will provide a label for the button
label: "loop-call-button.label",
tooltiptext: "loop-call-button.tooltiptext",
defaultArea: CustomizableUI.AREA_NAVBAR,
introducedInVersion: 1,
onBuild: function(aDocument) {
let node = aDocument.createElementNS(kNSXUL, "toolbarbutton");
node.setAttribute("id", this.id);
node.classList.add("toolbarbutton-1");
node.classList.add("chromeclass-toolbar-additional");
node.setAttribute("type", "badged");
node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
node.setAttribute("tooltiptext", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
node.setAttribute("removable", "true");
node.addEventListener("command", function(event) {
aDocument.defaultView.LoopUI.openCallPanel(event);
});
return node;
}
}];
#ifdef XP_WIN

View File

@ -1,2 +1 @@
.module-cache
standalone/content/config.js

View File

@ -53,19 +53,19 @@ browser.jar:
content/browser/loop/shared/sounds/Firefox-Long.ogg (content/shared/sounds/Firefox-Long.ogg)
# Partner SDK assets
content/browser/loop/libs/sdk.js (content/libs/sdk.js)
content/browser/loop/sdk-content/css/ot.css (content/libs/sdk-content/css/ot.css)
content/browser/loop/sdk-content/js/dynamic_config.min.js (content/libs/sdk-content/js/dynamic_config.min.js)
content/browser/loop/sdk-content/images/rtc/access-denied-chrome.png (content/libs/sdk-content/images/rtc/access-denied-chrome.png)
content/browser/loop/sdk-content/images/rtc/access-denied-copy-firefox.png (content/libs/sdk-content/images/rtc/access-denied-copy-firefox.png)
content/browser/loop/sdk-content/images/rtc/access-denied-firefox.png (content/libs/sdk-content/images/rtc/access-denied-firefox.png)
content/browser/loop/sdk-content/images/rtc/access-predenied-chrome.png (content/libs/sdk-content/images/rtc/access-predenied-chrome.png)
content/browser/loop/sdk-content/images/rtc/access-prompt-chrome.png (content/libs/sdk-content/images/rtc/access-prompt-chrome.png)
content/browser/loop/sdk-content/images/rtc/audioonly-publisher.png (content/libs/sdk-content/images/rtc/audioonly-publisher.png)
content/browser/loop/sdk-content/images/rtc/audioonly-subscriber.png (content/libs/sdk-content/images/rtc/audioonly-subscriber.png)
content/browser/loop/sdk-content/images/rtc/buttons.png (content/libs/sdk-content/images/rtc/buttons.png)
content/browser/loop/sdk-content/images/rtc/loader.gif (content/libs/sdk-content/images/rtc/loader.gif)
content/browser/loop/sdk-content/images/rtc/mic-off.png (content/libs/sdk-content/images/rtc/mic-off.png)
content/browser/loop/sdk-content/images/rtc/mic-on.png (content/libs/sdk-content/images/rtc/mic-on.png)
content/browser/loop/sdk-content/images/rtc/speaker-off.png (content/libs/sdk-content/images/rtc/speaker-off.png)
content/browser/loop/sdk-content/images/rtc/speaker-on.png (content/libs/sdk-content/images/rtc/speaker-on.png)
content/browser/loop/libs/sdk.js (content/shared/libs/sdk.js)
content/browser/loop/sdk-content/css/ot.css (content/shared/libs/sdk-content/css/ot.css)
content/browser/loop/sdk-content/js/dynamic_config.min.js (content/shared/libs/sdk-content/js/dynamic_config.min.js)
content/browser/loop/sdk-content/images/rtc/access-denied-chrome.png (content/shared/libs/sdk-content/images/rtc/access-denied-chrome.png)
content/browser/loop/sdk-content/images/rtc/access-denied-copy-firefox.png (content/shared/libs/sdk-content/images/rtc/access-denied-copy-firefox.png)
content/browser/loop/sdk-content/images/rtc/access-denied-firefox.png (content/shared/libs/sdk-content/images/rtc/access-denied-firefox.png)
content/browser/loop/sdk-content/images/rtc/access-predenied-chrome.png (content/shared/libs/sdk-content/images/rtc/access-predenied-chrome.png)
content/browser/loop/sdk-content/images/rtc/access-prompt-chrome.png (content/shared/libs/sdk-content/images/rtc/access-prompt-chrome.png)
content/browser/loop/sdk-content/images/rtc/audioonly-publisher.png (content/shared/libs/sdk-content/images/rtc/audioonly-publisher.png)
content/browser/loop/sdk-content/images/rtc/audioonly-subscriber.png (content/shared/libs/sdk-content/images/rtc/audioonly-subscriber.png)
content/browser/loop/sdk-content/images/rtc/buttons.png (content/shared/libs/sdk-content/images/rtc/buttons.png)
content/browser/loop/sdk-content/images/rtc/loader.gif (content/shared/libs/sdk-content/images/rtc/loader.gif)
content/browser/loop/sdk-content/images/rtc/mic-off.png (content/shared/libs/sdk-content/images/rtc/mic-off.png)
content/browser/loop/sdk-content/images/rtc/mic-on.png (content/shared/libs/sdk-content/images/rtc/mic-on.png)
content/browser/loop/sdk-content/images/rtc/speaker-off.png (content/shared/libs/sdk-content/images/rtc/speaker-off.png)
content/browser/loop/sdk-content/images/rtc/speaker-on.png (content/shared/libs/sdk-content/images/rtc/speaker-on.png)

View File

@ -6,15 +6,13 @@
JAR_MANIFESTS += ['jar.mn']
JS_MODULES_PATH = 'modules/loop'
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
BROWSER_CHROME_MANIFESTS += [
'test/mochitest/browser.ini',
]
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.loop += [
'MozLoopAPI.jsm',
'MozLoopPushHandler.jsm',
'MozLoopService.jsm',

View File

@ -1,2 +1,5 @@
.module-cache
node_modules
*.pyc
content/config.js
content/VERSION.txt

View File

@ -21,6 +21,21 @@ runserver: config
frontend:
@echo "Not implemented yet."
# Try hg first, if not fall back to git.
SOURCE_STAMP := $(shell hg parent --template '{node|short}\n' 2> /dev/null)
ifndef SOURCE_STAMP
SOURCE_STAMP := $(shell git describe --always --tag)
endif
SOURCE_DATE := $(shell hg parent --template '{date|date}\n' 2> /dev/null)
ifndef SOURCE_DATE
SOURCE_DATE := $(shell git log -1 --format="%H%n%aD")
endif
version:
@echo $(SOURCE_STAMP) > content/VERSION.txt
@echo $(SOURCE_DATE) >> content/VERSION.txt
config:
@echo "var loop = loop || {};" > content/config.js
@echo "loop.config = loop.config || {};" >> content/config.js

View File

@ -22,7 +22,15 @@
<div id="main"></div>
<!-- libs -->
<script src="https://static.opentok.com/webrtc/v2.2/js/opentok.min.js"></script>
<script>
window.OTProperties = {
cdnURL: 'shared/libs/',
};
window.OTProperties.assetURL = window.OTProperties.cdnURL + 'sdk-content/';
window.OTProperties.configURL = window.OTProperties.assetURL + 'js/dynamic_config.min.js';
window.OTProperties.cssURL = window.OTProperties.assetURL + 'css/ot.css';
</script>
<script type="text/javascript" src="shared/libs/sdk.js"></script>
<script type="text/javascript" src="libs/webl10n-20130617.js"></script>
<script type="text/javascript" src="shared/libs/react-0.10.0.js"></script>
<script type="text/javascript" src="shared/libs/jquery-2.1.0.js"></script>

View File

@ -22,9 +22,7 @@ EXTRA_COMPONENTS += [
'nsSessionStore.manifest',
]
JS_MODULES_PATH = 'modules/sessionstore'
EXTRA_JS_MODULES = [
EXTRA_JS_MODULES.sessionstore = [
'ContentRestore.jsm',
'DocShellCapabilities.jsm',
'FrameTree.jsm',
@ -46,7 +44,7 @@ EXTRA_JS_MODULES = [
'Utils.jsm',
]
EXTRA_PP_JS_MODULES += [
EXTRA_PP_JS_MODULES.sessionstore += [
'SessionSaver.jsm',
'SessionStore.jsm',
]

View File

@ -4,9 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES = ['modules/utils.jsm']
JS_MODULES_PATH = 'modules/tabview'
EXTRA_JS_MODULES.tabview = ['modules/utils.jsm']
BROWSER_CHROME_MANIFESTS += [
'test/browser.ini',
]

View File

@ -2,9 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/translation'
EXTRA_JS_MODULES = [
EXTRA_JS_MODULES.translation = [
'BingTranslator.jsm',
'cld2/cld-worker.js',
'cld2/cld-worker.js.mem',

View File

@ -7,9 +7,7 @@
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
JS_MODULES_PATH = 'modules/devtools/app-manager'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools["app-manager"] += [
'app-projects.js',
'app-validator.js',
'builtin-adb-store.js',

View File

@ -3,9 +3,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/canvasdebugger'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.canvasdebugger += [
'panel.js'
]

View File

@ -2,9 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/commandline'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.commandline += [
'commands-index.js'
]

View File

@ -3,9 +3,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/debugger'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.debugger += [
'debugger-commands.js',
'panel.js'
]

View File

@ -4,9 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/eyedropper'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.eyedropper += [
'commands.js',
'eyedropper.js'
]

View File

@ -2,9 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/inspector'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.inspector += [
'breadcrumbs.js',
'inspector-commands.js',
'inspector-panel.js',

View File

@ -6,9 +6,7 @@
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
JS_MODULES_PATH = 'modules/devtools/markupview'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.markupview += [
'html-editor.js',
'markup-view.js',
]

View File

@ -38,8 +38,6 @@ EXTRA_COMPONENTS += [
JAR_MANIFESTS += ['jar.mn']
JS_MODULES_PATH = 'modules/devtools'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools += [
'main.js',
]

View File

@ -3,9 +3,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/netmonitor'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.netmonitor += [
'panel.js'
]

View File

@ -6,9 +6,7 @@
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
JS_MODULES_PATH = 'modules/devtools/profiler'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.profiler += [
'cleopatra.js',
'commands.js',
'consts.js',

View File

@ -2,9 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools += [
'resize-commands.js'
]

View File

@ -4,9 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/scratchpad'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.scratchpad += [
'scratchpad-commands.js',
'scratchpad-panel.js'
]

View File

@ -3,9 +3,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/shadereditor'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.shadereditor += [
'panel.js'
]

View File

@ -4,9 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/sourceeditor'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.sourceeditor += [
'autocomplete.js',
'css-autocompleter.js',
'css-tokenizer.js',

View File

@ -7,9 +7,7 @@
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
JS_MODULES_PATH = 'modules/devtools/styleinspector'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.styleinspector += [
'computed-view.js',
'css-parsing-utils.js',
'rule-view.js',

View File

@ -2,9 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/tilt'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.tilt += [
'tilt-commands.js',
'tilt-gl.js',
'tilt-math.js',

View File

@ -3,9 +3,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JS_MODULES_PATH = 'modules/devtools/webaudioeditor'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.webaudioeditor += [
'panel.js'
]

View File

@ -6,9 +6,7 @@
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
JS_MODULES_PATH = 'modules/devtools/webconsole'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.webconsole += [
'console-commands.js',
'console-output.js',
'hudservice.js',

View File

@ -83,19 +83,19 @@ function updateUI() {
document.querySelector("#type").classList.remove("hidden");
if (project.type == "runtimeApp") {
let manifest = AppManager.getProjectManifestURL(project);
let manifestURL = AppManager.getProjectManifestURL(project);
document.querySelector("#type").textContent = manifest.type || "web";
document.querySelector("#manifestURLHeader").classList.remove("hidden");
document.querySelector("#manifestURL").textContent = manifest;
document.querySelector("#manifestURL").textContent = manifestURL;
} else {
document.querySelector("#type").textContent = project.type + " " + (manifest.type || "web");
}
if (project.type == "packaged") {
let manifest = AppManager.getProjectManifestURL(project);
if (manifest) {
let manifestURL = AppManager.getProjectManifestURL(project);
if (manifestURL) {
document.querySelector("#manifestURLHeader").classList.remove("hidden");
document.querySelector("#manifestURL").textContent = manifest;
document.querySelector("#manifestURL").textContent = manifestURL;
}
}
}

View File

@ -58,6 +58,16 @@
<h2>&prefs_editor_title;</h2>
<ul>
<li>
<label><span>&prefs_options_keybindings;</span>
<select data-pref="devtools.editor.keymap">
<option value="default">&prefs_options_keybindings_default;</option>
<option value="vim">Vim</option>
<option value="emacs">Emacs</option>
<option value="sublime">Sublime</option>
</select>
</label>
</li>
<li>
<label><span>&prefs_options_tabsize;</span>
<select data-pref="devtools.editor.tabsize">

View File

@ -632,7 +632,7 @@ let UI = {
splitter.removeAttribute("hidden");
let iframe = document.createElement("iframe");
document.querySelector("window").insertBefore(iframe, splitter.nextSibling);
document.querySelector("notificationbox").insertBefore(iframe, splitter.nextSibling);
let host = devtools.Toolbox.HostType.CUSTOM;
let options = { customIframe: iframe };
this.toolboxIframe = iframe;

View File

@ -181,10 +181,9 @@
<iframe id="deck-panel-runtimedetails" flex="1" src="runtimedetails.xhtml"/>
<iframe id="deck-panel-monitor" flex="1" lazysrc="monitor.xhtml"/>
</deck>
<splitter hidden="true" class="devtools-horizontal-splitter" orient="vertical"/>
<!-- toolbox iframe will be inserted here -->
</notificationbox>
<splitter hidden="true" class="devtools-horizontal-splitter" orient="vertical"/>
<!-- toolbox iframe will be inserted here -->
</window>

View File

@ -117,6 +117,8 @@
<!ENTITY prefs_options_autocomplete_tooltip "Enable code autocompletion">
<!ENTITY prefs_options_autoclosebrackets "Autoclose brackets">
<!ENTITY prefs_options_autoclosebrackets_tooltip "Automatically insert closing brackets">
<!ENTITY prefs_options_keybindings "Keybindings">
<!ENTITY prefs_options_keybindings_default "Default">
<!-- Permissions Table -->
<!ENTITY permissionstable_title "Permissions Table">

View File

@ -12,9 +12,7 @@ DIRS += [
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
JS_MODULES_PATH = 'modules/devtools/webide'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.devtools.webide += [
'modules/addons.js',
'modules/app-manager.js',
'modules/remote-resources.js',

View File

@ -7,9 +7,7 @@ EXTRA_COMPONENTS += [
'ExperimentsService.js',
]
JS_MODULES_PATH = 'modules/experiments'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.experiments += [
'Experiments.jsm',
]

View File

@ -451,6 +451,7 @@
@BINPATH@/components/nsInputListAutoComplete.js
@BINPATH@/components/formautofill.manifest
@BINPATH@/components/FormAutofillContentService.js
@BINPATH@/components/FormAutofillStartup.js
@BINPATH@/components/contentSecurityPolicy.manifest
@BINPATH@/components/contentSecurityPolicy.js
@BINPATH@/components/contentAreaDropListener.manifest

View File

@ -715,8 +715,6 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY getUserMedia.selectMicrophone.accesskey "M">
<!ENTITY getUserMedia.allWindowsShared.message "All visible windows on your screen will be shared.">
<!ENTITY loopCallButton.tooltip "Invite someone to talk">
<!ENTITY mixedContentBlocked.moreinfo "Most websites will still work properly even when this content is blocked.">
<!ENTITY pointerLock.notification.message "Press ESC at any time to show it again.">

View File

@ -96,3 +96,6 @@ quit-button.tooltiptext.linux2 = Quit %1$S (%2$S)
# LOCALIZATION NOTE(quit-button.tooltiptext.mac): %1$S is the brand name (e.g. Firefox),
# %2$S is the keyboard shortcut
quit-button.tooltiptext.mac = Quit %1$S (%2$S)
loop-call-button.label = Invite someone to talk
loop-call-button.tooltiptext = Invite someone to talk

View File

@ -77,6 +77,18 @@ DEBUGGER_INFO = {
"requiresEscapedArgs": True
},
# Visual Studio Debugger Support
"devenv.exe": {
"interactive": True,
"args": "-debugexe"
},
# Visual C++ Express Debugger Support
"wdexpress.exe": {
"interactive": True,
"args": "-debugexe"
},
# valgrind doesn't explain much about leaks unless you set the
# '--leak-check=full' flag. But there are a lot of objects that are
# semi-deliberately leaked, so we set '--show-possibly-lost=no' to avoid

View File

@ -55,7 +55,6 @@ _MOZBUILD_EXTERNAL_VARIABLES := \
IS_COMPONENT \
JAR_MANIFEST \
JAVA_JAR_TARGETS \
JS_MODULES_PATH \
LD_VERSION_SCRIPT \
LIBRARY_NAME \
LIBS \

View File

@ -1221,10 +1221,8 @@ endif
################################################################################
# Copy each element of EXTRA_JS_MODULES to
# $(FINAL_TARGET)/$(JS_MODULES_PATH). JS_MODULES_PATH defaults to "modules"
# if it is undefined.
JS_MODULES_PATH ?= modules
FINAL_JS_MODULES_PATH := $(FINAL_TARGET)/$(JS_MODULES_PATH)
# $(FINAL_TARGET)/modules.
FINAL_JS_MODULES_PATH := $(FINAL_TARGET)/modules
ifdef EXTRA_JS_MODULES
ifndef NO_DIST_INSTALL

View File

@ -3844,7 +3844,6 @@ MOZ_PAY=
MOZ_AUDIO_CHANNEL_MANAGER=
NSS_NO_LIBPKIX=
MOZ_CONTENT_SANDBOX=
MOZ_GMP_SANDBOX=
JSGC_USE_EXACT_ROOTING=1
JSGC_GENERATIONAL=
@ -5083,6 +5082,20 @@ if test -n "$MOZ_WEBM"; then
MOZ_VPX=1
fi;
dnl ========================================================
dnl = Apple platform decoder support
dnl ========================================================
if test "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
MOZ_APPLEMEDIA=1
fi
if test -n "$MOZ_APPLEMEDIA"; then
AC_DEFINE(MOZ_APPLEMEDIA)
# hack in frameworks for fmp4 - see bug 1029974
# We load VideoToolbox and CoreMedia dynamically, so they don't appear here.
LDFLAGS="$LDFLAGS -framework AudioToolbox"
fi
dnl ========================================================
dnl = DirectShow support
dnl ========================================================
@ -5143,10 +5156,8 @@ fi;
dnl ========================================================
dnl = Built-in fragmented MP4 support.
dnl ========================================================
if test -n "$MOZ_WMF" -o -n "$MOZ_FFMPEG"; then
dnl Enable fragmented MP4 parser on Windows by default.
dnl We will also need to enable it on other platforms as we implement
dnl platform decoder support there too.
if test -n "$MOZ_WMF" -o -n "$MOZ_FFMPEG" -o -n "$MOZ_APPLEMEDIA"; then
dnl Enable fragmented MP4 parser on platforms with decoder support.
MOZ_FMP4=1
fi
@ -5189,22 +5200,6 @@ if test -n "$MOZ_ANDROID_OMX"; then
AC_DEFINE(MOZ_ANDROID_OMX)
fi
dnl ========================================================
dnl = Disable platform MP3 decoder on OSX
dnl ========================================================
if test "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
MOZ_APPLEMEDIA=1
fi
MOZ_ARG_DISABLE_BOOL(apple-media,
[ --disable-apple-media Disable support for Apple AudioToolbox/VideoToolbox],
MOZ_APPLEMEDIA=,
MOZ_APPLEMEDIA=1)
if test -n "$MOZ_APPLEMEDIA"; then
AC_DEFINE(MOZ_APPLEMEDIA)
fi
dnl ========================================================
dnl = Enable getUserMedia support
dnl ========================================================
@ -6406,28 +6401,6 @@ fi
AC_SUBST(MOZ_CONTENT_SANDBOX)
dnl ========================================================
dnl = Gecko Media Plugin sandboxing
dnl ========================================================
case $OS_TARGET in
WINNT)
MOZ_GMP_SANDBOX=1
;;
Linux)
case $CPU_ARCH in
x86_64|x86)
MOZ_GMP_SANDBOX=1
;;
esac
;;
esac
if test -n "$MOZ_GMP_SANDBOX"; then
AC_DEFINE(MOZ_GMP_SANDBOX)
fi
AC_SUBST(MOZ_GMP_SANDBOX)
dnl ========================================================
dnl =
dnl = Module specific options

View File

@ -748,16 +748,6 @@ private:
} // dom namespace
} // file namespace
class MOZ_STACK_CLASS nsDOMFileInternalUrlHolder {
public:
nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~nsDOMFileInternalUrlHolder();
nsAutoString mUrl;
private:
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class nsDOMFileList MOZ_FINAL : public nsIDOMFileList,
public nsWrapperCache
{

View File

@ -1064,21 +1064,3 @@ nsDOMFileList::Item(uint32_t aIndex, nsIDOMFile **aFile)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////
// nsDOMFileInternalUrlHolder implementation
nsDOMFileInternalUrlHolder::nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile,
nsIPrincipal* aPrincipal
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
aFile->GetInternalUrl(aPrincipal, mUrl);
}
nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() {
if (!mUrl.IsEmpty()) {
nsAutoCString narrowUrl;
CopyUTF16toUTF8(mUrl, narrowUrl);
nsBlobProtocolHandler::RemoveDataEntry(narrowUrl);
}
}

View File

@ -17,6 +17,10 @@
#ifdef MOZ_FFMPEG
#include "FFmpegRuntimeLinker.h"
#endif
#ifdef MOZ_APPLEMEDIA
#include "apple/AppleCMLinker.h"
#include "apple/AppleVTLinker.h"
#endif
namespace mozilla {
@ -102,6 +106,31 @@ IsFFmpegAvailable()
#endif
}
static bool
IsAppleAvailable()
{
#ifndef MOZ_APPLEMEDIA
// Not the right platform.
return false;
#else
if (!Preferences::GetBool("media.apple.mp4.enabled", false)) {
// Disabled by preference.
return false;
}
// Attempt to load the required frameworks.
bool haveCoreMedia = AppleCMLinker::Link();
if (!haveCoreMedia) {
return false;
}
bool haveVideoToolbox = AppleVTLinker::Link();
if (!haveVideoToolbox) {
return false;
}
// All hurdles cleared!
return true;
#endif
}
static bool
HavePlatformMPEGDecoders()
{
@ -111,6 +140,7 @@ HavePlatformMPEGDecoders()
IsVistaOrLater() ||
#endif
IsFFmpegAvailable() ||
IsAppleAvailable() ||
// TODO: Other platforms...
false;
}

View File

@ -11,6 +11,9 @@
#ifdef MOZ_FFMPEG
#include "FFmpegRuntimeLinker.h"
#endif
#ifdef MOZ_APPLEMEDIA
#include "AppleDecoderModule.h"
#endif
#include "mozilla/Preferences.h"
#include "EMEDecoderModule.h"
#include "mozilla/CDMProxy.h"
@ -42,6 +45,9 @@ PlatformDecoderModule::Init()
#ifdef XP_WIN
WMFDecoderModule::Init();
#endif
#ifdef MOZ_APPLEMEDIA
AppleDecoderModule::Init();
#endif
}
class CreateTaskQueueTask : public nsRunnable {
@ -116,6 +122,12 @@ PlatformDecoderModule::Create()
if (sFFmpegDecoderEnabled) {
return FFmpegRuntimeLinker::CreateDecoderModule();
}
#endif
#ifdef MOZ_APPLEMEDIA
nsAutoPtr<AppleDecoderModule> m(new AppleDecoderModule());
if (NS_SUCCEEDED(m->Startup())) {
return m.forget();
}
#endif
return nullptr;
}

View File

@ -0,0 +1,354 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <AudioToolbox/AudioToolbox.h>
#include "AppleUtils.h"
#include "MP4Reader.h"
#include "MP4Decoder.h"
#include "mozilla/RefPtr.h"
#include "mozilla/ReentrantMonitor.h"
#include "mp4_demuxer/DecoderData.h"
#include "nsIThread.h"
#include "AppleATDecoder.h"
#include "prlog.h"
#ifdef PR_LOGGING
PRLogModuleInfo* GetDemuxerLog();
#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
#else
#define LOG(...)
#endif
namespace mozilla {
AppleATDecoder::AppleATDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* anAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
: mConfig(aConfig)
, mTaskQueue(anAudioTaskQueue)
, mCallback(aCallback)
, mConverter(nullptr)
, mStream(nullptr)
, mCurrentAudioFrame(0)
, mSamplePosition(0)
, mHaveOutput(false)
{
MOZ_COUNT_CTOR(AppleATDecoder);
LOG("Creating Apple AudioToolbox AAC decoder");
LOG("Audio Decoder configuration: %s %d Hz %d channels %d bits per channel",
mConfig.mime_type,
mConfig.samples_per_second,
mConfig.channel_count,
mConfig.bits_per_sample);
// TODO: Verify aConfig.mime_type.
}
AppleATDecoder::~AppleATDecoder()
{
MOZ_COUNT_DTOR(AppleATDecoer);
MOZ_ASSERT(!mConverter);
MOZ_ASSERT(!mStream);
}
static void
_MetadataCallback(void *aDecoder,
AudioFileStreamID aStream,
AudioFileStreamPropertyID aProperty,
UInt32 *aFlags)
{
LOG("AppleATDecoder metadata callback");
AppleATDecoder* decoder = static_cast<AppleATDecoder*>(aDecoder);
decoder->MetadataCallback(aStream, aProperty, aFlags);
}
static void
_SampleCallback(void *aDecoder,
UInt32 aNumBytes, UInt32 aNumPackets,
const void *aData,
AudioStreamPacketDescription *aPackets)
{
LOG("AppleATDecoder sample callback %u bytes %u packets",
aNumBytes, aNumPackets);
AppleATDecoder* decoder = static_cast<AppleATDecoder*>(aDecoder);
decoder->SampleCallback(aNumBytes, aNumPackets, aData, aPackets);
}
nsresult
AppleATDecoder::Init()
{
LOG("Initializing Apple AudioToolbox AAC decoder");
AudioFileTypeID fileType = kAudioFileAAC_ADTSType;
OSStatus rv = AudioFileStreamOpen(this,
_MetadataCallback,
_SampleCallback,
fileType,
&mStream);
if (rv) {
NS_ERROR("Couldn't open AudioFileStream");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
AppleATDecoder::Input(mp4_demuxer::MP4Sample* aSample)
{
LOG("mp4 input sample %p %lld us %lld pts%s %llu bytes audio",
aSample,
aSample->duration,
aSample->composition_timestamp,
aSample->is_sync_point ? " keyframe" : "",
(unsigned long long)aSample->size);
// Queue a task to perform the actual decoding on a separate thread.
mTaskQueue->Dispatch(
NS_NewRunnableMethodWithArg<nsAutoPtr<mp4_demuxer::MP4Sample>>(
this,
&AppleATDecoder::SubmitSample,
nsAutoPtr<mp4_demuxer::MP4Sample>(aSample)));
return NS_OK;
}
nsresult
AppleATDecoder::Flush()
{
LOG("Flushing AudioToolbox AAC decoder");
OSStatus rv = AudioConverterReset(mConverter);
if (rv) {
LOG("Error %d resetting AudioConverter", rv);
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
AppleATDecoder::Drain()
{
LOG("Draining AudioToolbox AAC decoder");
mTaskQueue->AwaitIdle();
return Flush();
}
nsresult
AppleATDecoder::Shutdown()
{
LOG("Shutdown: Apple AudioToolbox AAC decoder");
OSStatus rv1 = AudioConverterDispose(mConverter);
if (rv1) {
LOG("error %d disposing of AudioConverter", rv1);
} else {
mConverter = nullptr;
}
OSStatus rv2 = AudioFileStreamClose(mStream);
if (rv2) {
LOG("error %d closing AudioFileStream", rv2);
} else {
mStream = nullptr;
}
return (rv1 && rv2) ? NS_OK : NS_ERROR_FAILURE;
}
void
AppleATDecoder::MetadataCallback(AudioFileStreamID aFileStream,
AudioFileStreamPropertyID aPropertyID,
UInt32* aFlags)
{
if (aPropertyID == kAudioFileStreamProperty_ReadyToProducePackets) {
SetupDecoder();
}
}
struct PassthroughUserData {
AppleATDecoder* mDecoder;
UInt32 mNumPackets;
UInt32 mDataSize;
const void *mData;
AudioStreamPacketDescription *mPacketDesc;
bool mDone;
};
// Error value we pass through the decoder to signal that nothing
// has gone wrong during decoding, but more data is needed.
const uint32_t kNeedMoreData = 'MOAR';
static OSStatus
_PassthroughInputDataCallback(AudioConverterRef aAudioConverter,
UInt32 *aNumDataPackets /* in/out */,
AudioBufferList *aData /* in/out */,
AudioStreamPacketDescription **aPacketDesc,
void *aUserData)
{
PassthroughUserData *userData = (PassthroughUserData *)aUserData;
if (userData->mDone) {
// We make sure this callback is run _once_, with all the data we received
// from |AudioFileStreamParseBytes|. When we return an error, the decoder
// simply passes the return value on to the calling method,
// |SampleCallback|; and flushes all of the audio frames it had
// buffered. It does not change the decoder's state.
LOG("requested too much data; returning\n");
*aNumDataPackets = 0;
return kNeedMoreData;
}
userData->mDone = true;
LOG("AudioConverter wants %u packets of audio data\n", *aNumDataPackets);
*aNumDataPackets = userData->mNumPackets;
*aPacketDesc = userData->mPacketDesc;
aData->mBuffers[0].mNumberChannels = userData->mDecoder->mConfig.channel_count;
aData->mBuffers[0].mDataByteSize = userData->mDataSize;
aData->mBuffers[0].mData = const_cast<void *>(userData->mData);
return noErr;
}
void
AppleATDecoder::SampleCallback(uint32_t aNumBytes,
uint32_t aNumPackets,
const void* aData,
AudioStreamPacketDescription* aPackets)
{
// Pick a multiple of the frame size close to a power of two
// for efficient allocation.
const uint32_t MAX_AUDIO_FRAMES = 128;
const uint32_t decodedSize = MAX_AUDIO_FRAMES * mConfig.channel_count *
sizeof(AudioDataValue);
// Descriptions for _decompressed_ audio packets. ignored.
nsAutoArrayPtr<AudioStreamPacketDescription>
packets(new AudioStreamPacketDescription[MAX_AUDIO_FRAMES]);
// This API insists on having packets spoon-fed to it from a callback.
// This structure exists only to pass our state and the result of the
// parser on to the callback above.
PassthroughUserData userData =
{ this, aNumPackets, aNumBytes, aData, aPackets, false };
do {
// Decompressed audio buffer
nsAutoArrayPtr<uint8_t> decoded(new uint8_t[decodedSize]);
AudioBufferList decBuffer;
decBuffer.mNumberBuffers = 1;
decBuffer.mBuffers[0].mNumberChannels = mConfig.channel_count;
decBuffer.mBuffers[0].mDataByteSize = decodedSize;
decBuffer.mBuffers[0].mData = decoded.get();
// in: the max number of packets we can handle from the decoder.
// out: the number of packets the decoder is actually returning.
UInt32 numFrames = MAX_AUDIO_FRAMES;
OSStatus rv = AudioConverterFillComplexBuffer(mConverter,
_PassthroughInputDataCallback,
&userData,
&numFrames /* in/out */,
&decBuffer,
packets.get());
if (rv && rv != kNeedMoreData) {
LOG("Error decoding audio stream: %#x\n", rv);
mCallback->Error();
break;
}
LOG("%d frames decoded", numFrames);
// If we decoded zero frames then AudioConverterFillComplexBuffer is out
// of data to provide. We drained its internal buffer completely on the
// last pass.
if (numFrames == 0 && rv == kNeedMoreData) {
LOG("FillComplexBuffer out of data exactly\n");
mCallback->InputExhausted();
break;
}
const int rate = mConfig.samples_per_second;
int64_t time = FramesToUsecs(mCurrentAudioFrame, rate).value();
int64_t duration = FramesToUsecs(numFrames, rate).value();
LOG("pushed audio at time %lfs; duration %lfs\n",
(double)time / USECS_PER_S, (double)duration / USECS_PER_S);
AudioData *audio = new AudioData(mSamplePosition,
time, duration, numFrames,
reinterpret_cast<AudioDataValue *>(decoded.forget()),
rate);
mCallback->Output(audio);
mHaveOutput = true;
mCurrentAudioFrame += numFrames;
if (rv == kNeedMoreData) {
// No error; we just need more data.
LOG("FillComplexBuffer out of data\n");
mCallback->InputExhausted();
break;
}
} while (true);
}
void
AppleATDecoder::SetupDecoder()
{
AudioStreamBasicDescription inputFormat, outputFormat;
// Fill in the input format description from the stream.
AppleUtils::GetProperty(mStream,
kAudioFileStreamProperty_DataFormat, &inputFormat);
// Fill in the output format manually.
PodZero(&outputFormat);
outputFormat.mFormatID = kAudioFormatLinearPCM;
outputFormat.mSampleRate = inputFormat.mSampleRate;
outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame;
#if defined(MOZ_SAMPLE_TYPE_FLOAT32)
outputFormat.mBitsPerChannel = 32;
outputFormat.mFormatFlags =
kLinearPCMFormatFlagIsFloat |
0;
#else
# error Unknown audio sample type
#endif
// Set up the decoder so it gives us one sample per frame
outputFormat.mFramesPerPacket = 1;
outputFormat.mBytesPerPacket = outputFormat.mBytesPerFrame
= outputFormat.mChannelsPerFrame * outputFormat.mBitsPerChannel / 8;
OSStatus rv = AudioConverterNew(&inputFormat, &outputFormat, &mConverter);
if (rv) {
LOG("Error %d constructing AudioConverter", rv);
mConverter = nullptr;
mCallback->Error();
}
mHaveOutput = false;
}
void
AppleATDecoder::SubmitSample(nsAutoPtr<mp4_demuxer::MP4Sample> aSample)
{
mSamplePosition = aSample->byte_offset;
OSStatus rv = AudioFileStreamParseBytes(mStream,
aSample->size,
aSample->data,
0);
if (rv != noErr) {
LOG("Error %d parsing audio data", rv);
mCallback->Error();
}
// Sometimes we need multiple input samples before AudioToolbox
// starts decoding. If we haven't seen any output yet, ask for
// more data here.
if (!mHaveOutput) {
mCallback->InputExhausted();
}
}
} // namespace mozilla

View File

@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_AppleATDecoder_h
#define mozilla_AppleATDecoder_h
#include <AudioToolbox/AudioToolbox.h>
#include "PlatformDecoderModule.h"
#include "mozilla/RefPtr.h"
#include "mozilla/ReentrantMonitor.h"
#include "nsIThread.h"
namespace mozilla {
class MediaTaskQueue;
class MediaDataDecoderCallback;
class AppleATDecoder : public MediaDataDecoder {
public:
AppleATDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aVideoTaskQueue,
MediaDataDecoderCallback* aCallback);
~AppleATDecoder();
virtual nsresult Init() MOZ_OVERRIDE;
virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
virtual nsresult Flush() MOZ_OVERRIDE;
virtual nsresult Drain() MOZ_OVERRIDE;
virtual nsresult Shutdown() MOZ_OVERRIDE;
// Internal callbacks for the platform C api. Don't call externally.
void MetadataCallback(AudioFileStreamID aFileStream,
AudioFileStreamPropertyID aPropertyID,
UInt32* aFlags);
void SampleCallback(uint32_t aNumBytes,
uint32_t aNumPackets,
const void* aData,
AudioStreamPacketDescription* aPackets);
// Callbacks also need access to the config.
const mp4_demuxer::AudioDecoderConfig& mConfig;
private:
RefPtr<MediaTaskQueue> mTaskQueue;
MediaDataDecoderCallback* mCallback;
AudioConverterRef mConverter;
AudioFileStreamID mStream;
uint64_t mCurrentAudioFrame;
int64_t mSamplePosition;
bool mHaveOutput;
void SetupDecoder();
void SubmitSample(nsAutoPtr<mp4_demuxer::MP4Sample> aSample);
};
} // namespace mozilla
#endif // mozilla_AppleATDecoder_h

View File

@ -0,0 +1,12 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Construct references to each of the CoreMedia symbols we use.
LINK_FUNC(CMVideoFormatDescriptionCreate)
LINK_FUNC(CMBlockBufferCreateWithMemoryBlock)
LINK_FUNC(CMSampleBufferCreate)
LINK_FUNC(CMTimeMake)

View File

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <dlfcn.h>
#include "AppleCMLinker.h"
#include "MainThreadUtils.h"
#include "nsDebug.h"
#ifdef PR_LOGGING
PRLogModuleInfo* GetDemuxerLog();
#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
#else
#define LOG(...)
#endif
namespace mozilla {
AppleCMLinker::LinkStatus
AppleCMLinker::sLinkStatus = LinkStatus_INIT;
void* AppleCMLinker::sLink = nullptr;
nsrefcnt AppleCMLinker::sRefCount = 0;
#define LINK_FUNC(func) typeof(func) func;
#include "AppleCMFunctions.h"
#undef LINK_FUNC
/* static */ bool
AppleCMLinker::Link()
{
// Bump our reference count every time we're called.
// Add a lock or change the thread assertion if
// you need to call this off the main thread.
MOZ_ASSERT(NS_IsMainThread());
++sRefCount;
if (sLinkStatus) {
return sLinkStatus == LinkStatus_SUCCEEDED;
}
const char* dlname =
"/System/Library/Frameworks/CoreMedia.framework/CoreMedia";
if (!(sLink = dlopen(dlname, RTLD_NOW | RTLD_LOCAL))) {
NS_WARNING("Couldn't load CoreMedia framework");
goto fail;
}
#define LINK_FUNC(func) \
func = (typeof(func))dlsym(sLink, #func); \
if (!func) { \
NS_WARNING("Couldn't load CoreMedia function " #func ); \
goto fail; \
}
#include "AppleCMFunctions.h"
#undef LINK_FUNC
LOG("Loaded CoreMedia framework.");
sLinkStatus = LinkStatus_SUCCEEDED;
return true;
fail:
Unlink();
sLinkStatus = LinkStatus_FAILED;
return false;
}
/* static */ void
AppleCMLinker::Unlink()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sLink && sRefCount > 0, "Unbalanced Unlink()");
--sRefCount;
if (sLink && sRefCount < 1) {
LOG("Unlinking CoreMedia framework.");
dlclose(sLink);
sLink = nullptr;
}
}
} // namespace mozilla

View File

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef AppleCMLinker_h
#define AppleCMLinker_h
extern "C" {
#pragma GCC visibility push(default)
#include <CoreMedia/CoreMedia.h>
#pragma GCC visibility pop
}
#include "nscore.h"
namespace mozilla {
class AppleCMLinker
{
public:
static bool Link();
static void Unlink();
private:
static void* sLink;
static nsrefcnt sRefCount;
static enum LinkStatus {
LinkStatus_INIT = 0,
LinkStatus_FAILED,
LinkStatus_SUCCEEDED
} sLinkStatus;
};
#define LINK_FUNC(func) extern typeof(func)* func;
#include "AppleCMFunctions.h"
#undef LINK_FUNC
} // namespace mozilla
#endif // AppleCMLinker_h

View File

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AppleATDecoder.h"
#include "AppleCMLinker.h"
#include "AppleDecoderModule.h"
#include "AppleVTDecoder.h"
#include "AppleVTLinker.h"
#include "mozilla/Preferences.h"
#include "mozilla/DebugOnly.h"
namespace mozilla {
bool AppleDecoderModule::sIsEnabled = false;
AppleDecoderModule::AppleDecoderModule()
{
}
AppleDecoderModule::~AppleDecoderModule()
{
}
/* static */
void
AppleDecoderModule::Init()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
sIsEnabled = Preferences::GetBool("media.apple.mp4.enabled", false);
if (!sIsEnabled) {
return;
}
// dlopen CoreMedia.framework if it's available.
sIsEnabled = AppleCMLinker::Link();
if (!sIsEnabled) {
return;
}
// dlopen VideoToolbox.framework if it's available.
sIsEnabled = AppleVTLinker::Link();
}
nsresult
AppleDecoderModule::Startup()
{
// We don't have any per-instance initialization to do.
// Check whether ::Init() above succeeded to know if
// we're functional.
if (!sIsEnabled) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
AppleDecoderModule::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
AppleVTLinker::Unlink();
AppleCMLinker::Unlink();
return NS_OK;
}
MediaDataDecoder*
AppleDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer,
MediaTaskQueue* aVideoTaskQueue,
MediaDataDecoderCallback* aCallback)
{
return new AppleVTDecoder(aConfig, aVideoTaskQueue, aCallback, aImageContainer);
}
MediaDataDecoder*
AppleDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
{
return new AppleATDecoder(aConfig, aAudioTaskQueue, aCallback);
}
} // namespace mozilla

View File

@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_AppleDecoderModule_h
#define mozilla_AppleDecoderModule_h
#include "PlatformDecoderModule.h"
namespace mozilla {
class AppleDecoderModule : public PlatformDecoderModule {
public:
AppleDecoderModule();
virtual ~AppleDecoderModule();
// Perform any per-instance initialization.
// Main thread only.
nsresult Startup();
// Called when the decoders have shutdown. Main thread only.
// Does this really need to be main thread only????
virtual nsresult Shutdown() MOZ_OVERRIDE;
// Decode thread.
virtual MediaDataDecoder*
CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
mozilla::layers::LayersBackend aLayersBackend,
mozilla::layers::ImageContainer* aImageContainer,
MediaTaskQueue* aVideoTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
// Decode thread.
virtual MediaDataDecoder* CreateAACDecoder(
const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
static void Init();
private:
static bool sIsEnabled;
};
} // namespace mozilla
#endif // mozilla_AppleDecoderModule_h

View File

@ -0,0 +1,84 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Utility functions to help with Apple API calls.
#include <AudioToolbox/AudioToolbox.h>
#include "AppleUtils.h"
#include "prlog.h"
#ifdef PR_LOGGING
PRLogModuleInfo* GetDemuxerLog();
#define WARN(...) PR_LOG(GetDemuxerLog(), PR_LOG_WARNING, (__VA_ARGS__))
#else
#define WARN(...)
#endif
#define PROPERTY_ID_FORMAT "%c%c%c%c"
#define PROPERTY_ID_PRINT(x) ((x) >> 24), \
((x) >> 16) & 0xff, \
((x) >> 8) & 0xff, \
(x) & 0xff
namespace mozilla {
nsresult
AppleUtils::GetProperty(AudioFileStreamID aAudioFileStream,
AudioFileStreamPropertyID aPropertyID,
void *aData)
{
UInt32 size;
Boolean writeable;
OSStatus rv = AudioFileStreamGetPropertyInfo(aAudioFileStream, aPropertyID,
&size, &writeable);
if (rv) {
WARN("Couldn't get property " PROPERTY_ID_FORMAT "\n",
PROPERTY_ID_PRINT(aPropertyID));
return NS_ERROR_FAILURE;
}
rv = AudioFileStreamGetProperty(aAudioFileStream, aPropertyID,
&size, aData);
return NS_OK;
}
void
AppleUtils::SetCFDict(CFMutableDictionaryRef dict,
const char* key,
const char* value)
{
// We avoid using the CFSTR macros because there's no way to release those.
AutoCFRelease<CFStringRef> keyRef =
CFStringCreateWithCString(NULL, key, kCFStringEncodingUTF8);
AutoCFRelease<CFStringRef> valueRef =
CFStringCreateWithCString(NULL, value, kCFStringEncodingUTF8);
CFDictionarySetValue(dict, keyRef, valueRef);
}
void
AppleUtils::SetCFDict(CFMutableDictionaryRef dict,
const char* key,
int32_t value)
{
AutoCFRelease<CFNumberRef> valueRef =
CFNumberCreate(NULL, kCFNumberSInt32Type, &value);
AutoCFRelease<CFStringRef> keyRef =
CFStringCreateWithCString(NULL, key, kCFStringEncodingUTF8);
CFDictionarySetValue(dict, keyRef, valueRef);
}
void
AppleUtils::SetCFDict(CFMutableDictionaryRef dict,
const char* key,
bool value)
{
AutoCFRelease<CFStringRef> keyRef =
CFStringCreateWithCString(NULL, key, kCFStringEncodingUTF8);
CFDictionarySetValue(dict, keyRef, value ? kCFBooleanTrue : kCFBooleanFalse);
}
} // namespace mozilla

View File

@ -0,0 +1,66 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Utility functions to help with Apple API calls.
#ifndef mozilla_AppleUtils_h
#define mozilla_AppleUtils_h
#include <AudioToolbox/AudioToolbox.h>
#include "nsError.h"
namespace mozilla {
struct AppleUtils {
// Helper to retrieve properties from AudioFileStream objects.
static nsresult GetProperty(AudioFileStreamID aAudioFileStream,
AudioFileStreamPropertyID aPropertyID,
void *aData);
// Helper to set a string, string pair on a CFMutableDictionaryRef.
static void SetCFDict(CFMutableDictionaryRef dict,
const char* key,
const char* value);
// Helper to set a string, int32_t pair on a CFMutableDictionaryRef.
static void SetCFDict(CFMutableDictionaryRef dict,
const char* key,
int32_t value);
// Helper to set a string, bool pair on a CFMutableDictionaryRef.
static void SetCFDict(CFMutableDictionaryRef dict,
const char* key,
bool value);
};
// Wrapper class to call CFRelease on reference types
// when they go out of scope.
template <class T>
class AutoCFRelease {
public:
AutoCFRelease(T aRef)
: mRef(aRef)
{
}
~AutoCFRelease()
{
if (mRef) {
CFRelease(mRef);
}
}
// Return the wrapped ref so it can be used as an in parameter.
operator T()
{
return mRef;
}
// Return a pointer to the wrapped ref for use as an out parameter.
T* receive()
{
return &mRef;
}
private:
T mRef;
};
} // namespace mozilla
#endif // mozilla_AppleUtils_h

View File

@ -0,0 +1,427 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <CoreFoundation/CFString.h>
#include "AppleUtils.h"
#include "mozilla/SHA1.h"
#include "mp4_demuxer/DecoderData.h"
#include "MP4Reader.h"
#include "MP4Decoder.h"
#include "nsAutoPtr.h"
#include "nsThreadUtils.h"
#include "AppleCMLinker.h"
#include "AppleVTDecoder.h"
#include "AppleVTLinker.h"
#include "prlog.h"
#include "MediaData.h"
#include "VideoUtils.h"
#ifdef PR_LOGGING
PRLogModuleInfo* GetDemuxerLog();
#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
#define LOG_MEDIA_SHA1
#else
#define LOG(...)
#endif
namespace mozilla {
AppleVTDecoder::AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
MediaTaskQueue* aVideoTaskQueue,
MediaDataDecoderCallback* aCallback,
layers::ImageContainer* aImageContainer)
: mConfig(aConfig)
, mTaskQueue(aVideoTaskQueue)
, mCallback(aCallback)
, mImageContainer(aImageContainer)
, mFormat(nullptr)
, mSession(nullptr)
{
MOZ_COUNT_CTOR(AppleVTDecoder);
// TODO: Verify aConfig.mime_type.
LOG("Creating AppleVTDecoder for %dx%d h.264 video",
mConfig.display_width,
mConfig.display_height
);
}
AppleVTDecoder::~AppleVTDecoder()
{
MOZ_COUNT_DTOR(AppleVTDecoder);
}
nsresult
AppleVTDecoder::Init()
{
nsresult rv = InitializeSession();
return rv;
}
nsresult
AppleVTDecoder::Shutdown()
{
if (mSession) {
LOG("%s: cleaning up session %p", __func__, mSession);
VTDecompressionSessionInvalidate(mSession);
CFRelease(mSession);
mSession = nullptr;
}
if (mFormat) {
LOG("%s: releasing format %p", __func__, mFormat);
CFRelease(mFormat);
mFormat = nullptr;
}
return NS_OK;
}
nsresult
AppleVTDecoder::Input(mp4_demuxer::MP4Sample* aSample)
{
LOG("mp4 input sample %p pts %lld duration %lld us%s %d bytes",
aSample,
aSample->composition_timestamp,
aSample->duration,
aSample->is_sync_point ? " keyframe" : "",
aSample->size);
#ifdef LOG_MEDIA_SHA1
SHA1Sum hash;
hash.update(aSample->data, aSample->size);
uint8_t digest_buf[SHA1Sum::kHashSize];
hash.finish(digest_buf);
nsAutoCString digest;
for (size_t i = 0; i < sizeof(digest_buf); i++) {
digest.AppendPrintf("%02x", digest_buf[i]);
}
LOG(" sha1 %s", digest.get());
#endif // LOG_MEDIA_SHA1
mTaskQueue->Dispatch(
NS_NewRunnableMethodWithArg<nsAutoPtr<mp4_demuxer::MP4Sample>>(
this,
&AppleVTDecoder::SubmitFrame,
nsAutoPtr<mp4_demuxer::MP4Sample>(aSample)));
return NS_OK;
}
nsresult
AppleVTDecoder::Flush()
{
mReorderQueue.Clear();
return Drain();
}
nsresult
AppleVTDecoder::Drain()
{
OSStatus rv = VTDecompressionSessionWaitForAsynchronousFrames(mSession);
if (rv != noErr) {
LOG("Error %d draining frames", rv);
return NS_ERROR_FAILURE;
}
return DrainReorderedFrames();
}
//
// Implementation details.
//
// Context object to hold a copy of sample metadata.
class FrameRef {
public:
Microseconds timestamp;
Microseconds duration;
int64_t byte_offset;
bool is_sync_point;
explicit FrameRef(mp4_demuxer::MP4Sample* aSample)
{
MOZ_ASSERT(aSample);
timestamp = aSample->composition_timestamp;
duration = aSample->duration;
byte_offset = aSample->byte_offset;
is_sync_point = aSample->is_sync_point;
}
};
// Callback passed to the VideoToolbox decoder for returning data.
// This needs to be static because the API takes a C-style pair of
// function and userdata pointers. This validates parameters and
// forwards the decoded image back to an object method.
static void
PlatformCallback(void* decompressionOutputRefCon,
void* sourceFrameRefCon,
OSStatus status,
VTDecodeInfoFlags flags,
CVImageBufferRef image,
CMTime presentationTimeStamp,
CMTime presentationDuration)
{
LOG("AppleVideoDecoder %s status %d flags %d", __func__, status, flags);
AppleVTDecoder* decoder =
static_cast<AppleVTDecoder*>(decompressionOutputRefCon);
nsAutoPtr<FrameRef> frameRef =
nsAutoPtr<FrameRef>(static_cast<FrameRef*>(sourceFrameRefCon));
LOG("mp4 output frame %lld pts %lld duration %lld us%s",
frameRef->byte_offset,
frameRef->timestamp,
frameRef->duration,
frameRef->is_sync_point ? " keyframe" : ""
);
// Validate our arguments.
if (status != noErr || !image) {
NS_WARNING("VideoToolbox decoder returned no data");
return;
}
if (flags & kVTDecodeInfo_FrameDropped) {
NS_WARNING(" ...frame dropped...");
}
MOZ_ASSERT(CFGetTypeID(image) == CVPixelBufferGetTypeID(),
"VideoToolbox returned an unexpected image type");
// Forward the data back to an object method which can access
// the correct MP4Reader callback.
decoder->OutputFrame(image, frameRef);
}
nsresult
AppleVTDecoder::DrainReorderedFrames()
{
while (!mReorderQueue.IsEmpty()) {
mCallback->Output(mReorderQueue.Pop());
}
return NS_OK;
}
// Copy and return a decoded frame.
nsresult
AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
nsAutoPtr<FrameRef> aFrameRef)
{
size_t width = CVPixelBufferGetWidth(aImage);
size_t height = CVPixelBufferGetHeight(aImage);
LOG(" got decoded frame data... %ux%u %s", width, height,
CVPixelBufferIsPlanar(aImage) ? "planar" : "chunked");
#ifdef DEBUG
size_t planes = CVPixelBufferGetPlaneCount(aImage);
for (size_t i = 0; i < planes; ++i) {
size_t stride = CVPixelBufferGetBytesPerRowOfPlane(aImage, i);
LOG(" plane %u %ux%u rowbytes %u",
(unsigned)i,
CVPixelBufferGetWidthOfPlane(aImage, i),
CVPixelBufferGetHeightOfPlane(aImage, i),
(unsigned)stride);
}
MOZ_ASSERT(planes == 2);
#endif // DEBUG
VideoData::YCbCrBuffer buffer;
// Lock the returned image data.
CVReturn rv = CVPixelBufferLockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
if (rv != kCVReturnSuccess) {
NS_ERROR("error locking pixel data");
mCallback->Error();
return NS_ERROR_FAILURE;
}
// Y plane.
buffer.mPlanes[0].mData =
static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 0));
buffer.mPlanes[0].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 0);
buffer.mPlanes[0].mWidth = width;
buffer.mPlanes[0].mHeight = height;
buffer.mPlanes[0].mOffset = 0;
buffer.mPlanes[0].mSkip = 0;
// Cb plane.
buffer.mPlanes[1].mData =
static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 1));
buffer.mPlanes[1].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 1);
buffer.mPlanes[1].mWidth = (width+1) / 2;
buffer.mPlanes[1].mHeight = (height+1) / 2;
buffer.mPlanes[1].mOffset = 0;
buffer.mPlanes[1].mSkip = 1;
// Cr plane.
buffer.mPlanes[2].mData =
static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 1));
buffer.mPlanes[2].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 1);
buffer.mPlanes[2].mWidth = (width+1) / 2;
buffer.mPlanes[2].mHeight = (height+1) / 2;
buffer.mPlanes[2].mOffset = 1;
buffer.mPlanes[2].mSkip = 1;
// Bounds.
VideoInfo info;
info.mDisplay = nsIntSize(width, height);
info.mHasVideo = true;
gfx::IntRect visible = gfx::IntRect(0,
0,
mConfig.display_width,
mConfig.display_height);
// Copy the image data into our own format.
nsAutoPtr<VideoData> data;
data =
VideoData::Create(info,
mImageContainer,
nullptr,
aFrameRef->byte_offset,
aFrameRef->timestamp,
aFrameRef->duration,
buffer,
aFrameRef->is_sync_point,
aFrameRef->timestamp,
visible);
// Unlock the returned image data.
CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
// Frames come out in DTS order but we need to output them
// in composition order.
mReorderQueue.Push(data.forget());
if (mReorderQueue.Length() > 2) {
VideoData* readyData = mReorderQueue.Pop();
mCallback->Output(readyData);
}
return NS_OK;
}
// Helper to fill in a timestamp structure.
static CMSampleTimingInfo
TimingInfoFromSample(mp4_demuxer::MP4Sample* aSample)
{
CMSampleTimingInfo timestamp;
timestamp.duration = CMTimeMake(aSample->duration, USECS_PER_S);
timestamp.presentationTimeStamp =
CMTimeMake(aSample->composition_timestamp, USECS_PER_S);
// No DTS value available from libstagefright.
timestamp.decodeTimeStamp = CMTimeMake(0, USECS_PER_S);
return timestamp;
}
nsresult
AppleVTDecoder::SubmitFrame(mp4_demuxer::MP4Sample* aSample)
{
// For some reason this gives me a double-free error with stagefright.
AutoCFRelease<CMBlockBufferRef> block = nullptr;
AutoCFRelease<CMSampleBufferRef> sample = nullptr;
VTDecodeInfoFlags flags;
OSStatus rv;
// FIXME: This copies the sample data. I think we can provide
// a custom block source which reuses the aSample buffer.
// But note that there may be a problem keeping the samples
// alive over multiple frames.
rv = CMBlockBufferCreateWithMemoryBlock(NULL // Struct allocator.
,aSample->data
,aSample->size
,kCFAllocatorNull // Block allocator.
,NULL // Block source.
,0 // Data offset.
,aSample->size
,false
,block.receive());
NS_ASSERTION(rv == noErr, "Couldn't create CMBlockBuffer");
CMSampleTimingInfo timestamp = TimingInfoFromSample(aSample);
rv = CMSampleBufferCreate(NULL, block, true, 0, 0, mFormat, 1, 1, &timestamp, 0, NULL, sample.receive());
NS_ASSERTION(rv == noErr, "Couldn't create CMSampleBuffer");
rv = VTDecompressionSessionDecodeFrame(mSession,
sample,
0,
new FrameRef(aSample),
&flags);
NS_ASSERTION(rv == noErr, "Couldn't pass frame to decoder");
// Ask for more data.
if (mTaskQueue->IsEmpty()) {
LOG("AppleVTDecoder task queue empty; requesting more data");
mCallback->InputExhausted();
}
return NS_OK;
}
nsresult
AppleVTDecoder::InitializeSession()
{
OSStatus rv;
AutoCFRelease<CFMutableDictionaryRef> extensions =
CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
AppleUtils::SetCFDict(extensions, "CVImageBufferChromaLocationBottomField", "left");
AppleUtils::SetCFDict(extensions, "CVImageBufferChromaLocationTopField", "left");
AppleUtils::SetCFDict(extensions, "FullRangeVideo", true);
AutoCFRelease<CFMutableDictionaryRef> atoms =
CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
AutoCFRelease<CFDataRef> avc_data = CFDataCreate(NULL,
mConfig.extra_data.begin(), mConfig.extra_data.length());
#ifdef LOG_MEDIA_SHA1
SHA1Sum avc_hash;
avc_hash.update(mConfig.extra_data.begin(), mConfig.extra_data.length());
uint8_t digest_buf[SHA1Sum::kHashSize];
avc_hash.finish(digest_buf);
nsAutoCString avc_digest;
for (size_t i = 0; i < sizeof(digest_buf); i++) {
avc_digest.AppendPrintf("%02x", digest_buf[i]);
}
LOG("AVCDecoderConfig %ld bytes sha1 %s",
mConfig.extra_data.length(), avc_digest.get());
#endif // LOG_MEDIA_SHA1
CFDictionarySetValue(atoms, CFSTR("avcC"), avc_data);
CFDictionarySetValue(extensions, CFSTR("SampleDescriptionExtensionAtoms"), atoms);
rv = CMVideoFormatDescriptionCreate(NULL, // Use default allocator.
kCMVideoCodecType_H264,
mConfig.display_width,
mConfig.display_height,
extensions,
&mFormat);
if (rv != noErr) {
NS_ERROR("Couldn't create format description!");
return NS_ERROR_FAILURE;
}
// Contruct video decoder selection spec.
AutoCFRelease<CFMutableDictionaryRef> spec =
CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
// This key is supported (or ignored) but not declared prior to OSX 10.9.
AutoCFRelease<CFStringRef>
kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder =
CFStringCreateWithCString(NULL, "EnableHardwareAcceleratedVideoDecoder",
kCFStringEncodingUTF8);
CFDictionarySetValue(spec,
kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder,
kCFBooleanTrue);
VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this };
rv = VTDecompressionSessionCreate(NULL, // Allocator.
mFormat,
spec, // Video decoder selection.
NULL, // Output video format.
&cb,
&mSession);
if (rv != noErr) {
NS_ERROR("Couldn't create decompression session!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
} // namespace mozilla

View File

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_AppleVTDecoder_h
#define mozilla_AppleVTDecoder_h
#include "PlatformDecoderModule.h"
#include "mozilla/RefPtr.h"
#include "mozilla/ReentrantMonitor.h"
#include "nsIThread.h"
#include "ReorderQueue.h"
#include "VideoToolbox/VideoToolbox.h"
namespace mozilla {
class MediaTaskQueue;
class MediaDataDecoderCallback;
namespace layers {
class ImageContainer;
}
class FrameRef;
class AppleVTDecoder : public MediaDataDecoder {
public:
AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
MediaTaskQueue* aVideoTaskQueue,
MediaDataDecoderCallback* aCallback,
layers::ImageContainer* aImageContainer);
~AppleVTDecoder();
virtual nsresult Init() MOZ_OVERRIDE;
virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
virtual nsresult Flush() MOZ_OVERRIDE;
virtual nsresult Drain() MOZ_OVERRIDE;
virtual nsresult Shutdown() MOZ_OVERRIDE;
// Return hook for VideoToolbox callback.
nsresult OutputFrame(CVPixelBufferRef aImage,
nsAutoPtr<FrameRef> frameRef);
private:
const mp4_demuxer::VideoDecoderConfig& mConfig;
RefPtr<MediaTaskQueue> mTaskQueue;
MediaDataDecoderCallback* mCallback;
layers::ImageContainer* mImageContainer;
CMVideoFormatDescriptionRef mFormat;
VTDecompressionSessionRef mSession;
ReorderQueue mReorderQueue;
// Method to pass a frame to VideoToolbox for decoding.
nsresult SubmitFrame(mp4_demuxer::MP4Sample* aSample);
// Method to set up the decompression session.
nsresult InitializeSession();
nsresult DrainReorderedFrames();
};
} // namespace mozilla
#endif // mozilla_AppleVTDecoder_h

View File

@ -0,0 +1,12 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Construct references to each of the VideoToolbox symbols we use.
LINK_FUNC(VTDecompressionSessionCreate)
LINK_FUNC(VTDecompressionSessionDecodeFrame)
LINK_FUNC(VTDecompressionSessionInvalidate)
LINK_FUNC(VTDecompressionSessionWaitForAsynchronousFrames)

View File

@ -0,0 +1,89 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <dlfcn.h>
#include "AppleVTLinker.h"
#include "MainThreadUtils.h"
#include "nsDebug.h"
#ifdef PR_LOGGING
PRLogModuleInfo* GetDemuxerLog();
#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
#else
#define LOG(...)
#endif
namespace mozilla {
AppleVTLinker::LinkStatus
AppleVTLinker::sLinkStatus = LinkStatus_INIT;
void* AppleVTLinker::sLink = nullptr;
nsrefcnt AppleVTLinker::sRefCount = 0;
#define LINK_FUNC(func) typeof(func) func;
#include "AppleVTFunctions.h"
#undef LINK_FUNC
/* static */ bool
AppleVTLinker::Link()
{
// Bump our reference count every time we're called.
// Add a lock or change the thread assertion if
// you need to call this off the main thread.
MOZ_ASSERT(NS_IsMainThread());
++sRefCount;
if (sLinkStatus) {
return sLinkStatus == LinkStatus_SUCCEEDED;
}
const char* dlname =
"/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox";
if (!(sLink = dlopen(dlname, RTLD_NOW | RTLD_LOCAL))) {
NS_WARNING("Couldn't load VideoToolbox framework");
goto fail;
}
#define LINK_FUNC(func) \
func = (typeof(func))dlsym(sLink, #func); \
if (!func) { \
NS_WARNING("Couldn't load VideoToolbox function " #func ); \
goto fail; \
}
#include "AppleVTFunctions.h"
#undef LINK_FUNC
LOG("Loaded VideoToolbox framework.");
sLinkStatus = LinkStatus_SUCCEEDED;
return true;
fail:
Unlink();
sLinkStatus = LinkStatus_FAILED;
return false;
}
/* static */ void
AppleVTLinker::Unlink()
{
// We'll be called by multiple Decoders, one intantiated for
// each media element. Therefore we receive must maintain a
// reference count to avoidunloading our symbols when other
// instances still need them.
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sLink && sRefCount > 0, "Unbalanced Unlink()");
--sRefCount;
if (sLink && sRefCount < 1) {
LOG("Unlinking VideoToolbox framework.");
dlclose(sLink);
sLink = nullptr;
}
}
} // namespace mozilla

View File

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef AppleVTLinker_h
#define AppleVTLinker_h
extern "C" {
#pragma GCC visibility push(default)
#include "VideoToolbox/VideoToolbox.h"
#pragma GCC visibility pop
}
#include "nscore.h"
namespace mozilla {
class AppleVTLinker
{
public:
static bool Link();
static void Unlink();
private:
static void* sLink;
static nsrefcnt sRefCount;
static enum LinkStatus {
LinkStatus_INIT = 0,
LinkStatus_FAILED,
LinkStatus_SUCCEEDED
} sLinkStatus;
};
#define LINK_FUNC(func) extern typeof(func)* func;
#include "AppleVTFunctions.h"
#undef LINK_FUNC
} // namespace mozilla
#endif // AppleVTLinker_h

View File

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Queue for ordering decoded video frames by presentation time.
// Decoders often return frames out of order, which we need to
// buffer so we can forward them in correct presentation order.
#ifndef mozilla_ReorderQueue_h
#define mozilla_ReorderQueue_h
#include <MediaData.h>
#include <nsTPriorityQueue.h>
namespace mozilla {
struct ReorderQueueComparator
{
bool LessThan(VideoData* const& a, VideoData* const& b) const
{
return a->mTime < b->mTime;
}
};
typedef nsTPriorityQueue<VideoData*, ReorderQueueComparator> ReorderQueue;
} // namespace mozilla
#endif // mozilla_ReorderQueue_h

View File

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Stub header for VideoToolbox framework API.
// We include our own copy so we can build on MacOS versions
// where it's not available.
#ifndef mozilla_VideoToolbox_VideoToolbox_h
#define mozilla_VideoToolbox_VideoToolbox_h
// CoreMedia is available starting in OS X 10.7,
// so we need to dlopen it as well to run on 10.6,
// but we can depend on the real framework headers at build time.
#include <CoreMedia/CMBase.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreVideo/CVPixelBuffer.h>
#include <CoreMedia/CMSampleBuffer.h>
#include <CoreMedia/CMFormatDescription.h>
#include <CoreMedia/CMTime.h>
typedef uint32_t VTDecodeFrameFlags;
typedef uint32_t VTDecodeInfoFlags;
enum {
kVTDecodeInfo_Asynchronous = 1UL << 0,
kVTDecodeInfo_FrameDropped = 1UL << 1,
};
typedef struct OpaqueVTDecompressionSession* VTDecompressionSessionRef;
typedef void (*VTDecompressionOutputCallback)(
void*,
void*,
OSStatus,
VTDecodeInfoFlags,
CVImageBufferRef,
CMTime,
CMTime
);
typedef struct VTDecompressionOutputCallbackRecord {
VTDecompressionOutputCallback decompressionOutputCallback;
void* decompressionOutputRefCon;
} VTDecompressionOutputCallbackRecord;
OSStatus
VTDecompressionSessionCreate(
CFAllocatorRef,
CMVideoFormatDescriptionRef,
CFDictionaryRef,
CFDictionaryRef,
const VTDecompressionOutputCallbackRecord*,
VTDecompressionSessionRef*
);
OSStatus
VTDecompressionSessionDecodeFrame(
VTDecompressionSessionRef,
CMSampleBufferRef,
VTDecodeFrameFlags,
void*,
VTDecodeInfoFlags*
);
OSStatus
VTDecompressionSessionWaitForAsynchronousFrames(
VTDecompressionSessionRef
);
void
VTDecompressionSessionInvalidate(
VTDecompressionSessionRef
);
#endif // mozilla_VideoToolbox_VideoToolbox_h

View File

@ -42,6 +42,22 @@ if CONFIG['MOZ_FFMPEG']:
'ffmpeg',
]
if CONFIG['MOZ_APPLEMEDIA']:
EXPORTS += [
'apple/AppleDecoderModule.h',
]
UNIFIED_SOURCES += [
'apple/AppleATDecoder.cpp',
'apple/AppleCMLinker.cpp',
'apple/AppleDecoderModule.cpp',
'apple/AppleUtils.cpp',
'apple/AppleVTDecoder.cpp',
'apple/AppleVTLinker.cpp',
]
LDFLAGS += [
'-framework AudioToolbox',
]
FINAL_LIBRARY = 'xul'
FAIL_ON_WARNINGS = True

View File

@ -26,8 +26,6 @@ using mozilla::dom::CrashReporterChild;
#if defined(XP_WIN)
#define TARGET_SANDBOX_EXPORTS
#include "mozilla/sandboxTarget.h"
#elif defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
#include "mozilla/Sandbox.h"
#endif
namespace mozilla {
@ -100,13 +98,6 @@ GMPChild::LoadPluginLibrary(const std::string& aPluginPath)
nsAutoCString nativePath;
libFile->GetNativePath(nativePath);
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
// Enable sandboxing here -- we know the plugin file's path, but
// this process's execution hasn't been affected by its content yet.
mozilla::SetMediaPluginSandbox(nativePath.get());
#endif
mLib = PR_LoadLibrary(nativePath.get());
if (!mLib) {
return false;

View File

@ -329,7 +329,6 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
static_cast<AudioNodeEngine*>(new DestinationNodeEngine(this));
mStream = graph->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM);
mStream->SetAudioChannelType(aChannel);
mStream->AddMainThreadListener(this);
mStream->AddAudioOutput(&gWebAudioOutputKey);
@ -539,6 +538,10 @@ AudioDestinationNode::SetMozAudioChannelType(AudioChannel aValue, ErrorResult& a
CheckAudioChannelPermissions(aValue)) {
mAudioChannel = aValue;
if (mStream) {
mStream->SetAudioChannelType(mAudioChannel);
}
if (mAudioChannelAgent) {
CreateAudioChannelAgent();
}

View File

@ -5,7 +5,7 @@
#include <stdint.h>
#include "mozilla/ArrayUtils.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/Likely.h"
@ -518,11 +518,14 @@ SVGSVGElement::SetCurrentScaleTranslate(float s, float x, float y)
if (doc) {
nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
if (presShell && IsRoot()) {
bool scaling = (mPreviousScale != mCurrentScale);
nsEventStatus status = nsEventStatus_eIgnore;
WidgetGUIEvent event(true, scaling ? NS_SVG_ZOOM : NS_SVG_SCROLL, 0);
event.eventStructType = scaling ? NS_SVGZOOM_EVENT : NS_EVENT;
presShell->HandleDOMEventWithTarget(this, &event, &status);
if (mPreviousScale != mCurrentScale) {
InternalSVGZoomEvent svgZoomEvent(true, NS_SVG_ZOOM);
presShell->HandleDOMEventWithTarget(this, &svgZoomEvent, &status);
} else {
WidgetEvent svgScrollEvent(true, NS_SVG_SCROLL);
presShell->HandleDOMEventWithTarget(this, &svgScrollEvent, &status);
}
InvalidateTransformNotifyFrame();
}
}

View File

@ -3,12 +3,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGZoomEvent.h"
#include "DOMSVGPoint.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "nsIPresShell.h"
#include "nsIDocument.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "mozilla/dom/SVGZoomEvent.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "prtime.h"
namespace mozilla {
@ -27,9 +28,9 @@ NS_INTERFACE_MAP_END_INHERITING(UIEvent)
SVGZoomEvent::SVGZoomEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetGUIEvent* aEvent)
InternalSVGZoomEvent* aEvent)
: UIEvent(aOwner, aPresContext,
aEvent ? aEvent : new WidgetGUIEvent(false, NS_SVG_ZOOM, 0))
aEvent ? aEvent : new InternalSVGZoomEvent(false, NS_SVG_ZOOM))
, mPreviousScale(0)
, mNewScale(0)
{
@ -38,12 +39,9 @@ SVGZoomEvent::SVGZoomEvent(EventTarget* aOwner,
}
else {
mEventIsInternal = true;
mEvent->eventStructType = NS_SVGZOOM_EVENT;
mEvent->time = PR_Now();
}
mEvent->mFlags.mCancelable = false;
// We must store the "Previous" and "New" values before this event is
// dispatched. Reading the values from the root 'svg' element after we've
// been dispatched is not an option since event handler code may change
@ -95,7 +93,7 @@ nsresult
NS_NewDOMSVGZoomEvent(nsIDOMEvent** aInstancePtrResult,
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
mozilla::WidgetGUIEvent* aEvent)
mozilla::InternalSVGZoomEvent* aEvent)
{
mozilla::dom::SVGZoomEvent* it =
new mozilla::dom::SVGZoomEvent(aOwner, aPresContext, aEvent);

View File

@ -28,7 +28,7 @@ public:
NS_DECL_ISUPPORTS_INHERITED
SVGZoomEvent(EventTarget* aOwner, nsPresContext* aPresContext,
WidgetGUIEvent* aEvent);
InternalSVGZoomEvent* aEvent);
// Forward to base class
NS_FORWARD_TO_UIEVENT

View File

@ -729,10 +729,10 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
aEvent->AsClipboardEvent());
case NS_SVGZOOM_EVENT:
return NS_NewDOMSVGZoomEvent(aDOMEvent, aOwner, aPresContext,
aEvent->AsGUIEvent());
aEvent->AsSVGZoomEvent());
case NS_SMIL_TIME_EVENT:
return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext, aEvent);
return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext,
aEvent->AsSMILTimeEvent());
case NS_COMMAND_EVENT:
return NS_NewDOMCommandEvent(aDOMEvent, aOwner, aPresContext,
aEvent->AsCommandEvent());

View File

@ -306,12 +306,12 @@ nsresult
NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult,
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
mozilla::WidgetGUIEvent* aEvent);
mozilla::InternalSVGZoomEvent* aEvent);
nsresult
NS_NewDOMTimeEvent(nsIDOMEvent** aResult,
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
mozilla::WidgetEvent* aEvent);
mozilla::InternalSMILTimeEvent* aEvent);
nsresult
NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult,
mozilla::dom::EventTarget* aOwner,

View File

@ -918,7 +918,7 @@ ContentChild::RecvSetProcessSandbox()
// at some point; see bug 880808.
#if defined(MOZ_CONTENT_SANDBOX)
#if defined(XP_LINUX)
SetContentProcessSandbox();
SetCurrentProcessSandbox();
#elif defined(XP_WIN)
mozilla::SandboxTarget::Instance()->StartSandbox();
#endif

View File

@ -46,9 +46,7 @@ EXTRA_COMPONENTS += [
'PeerConnection.manifest',
]
JS_MODULES_PATH = 'modules/media'
EXTRA_JS_MODULES += [
EXTRA_JS_MODULES.media += [
'IdpProxy.jsm',
'PeerConnectionIdp.jsm',
'RTCStatsReport.jsm',

View File

@ -19,7 +19,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
'android/SmsService.cpp',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
EXTRA_JS_MODULES = [
EXTRA_JS_MODULES += [
'gonk/mms_consts.js',
'gonk/MmsPduHelper.jsm',
'gonk/MobileMessageDB.jsm',

View File

@ -27,7 +27,7 @@ UNIFIED_SOURCES += [
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
EXTRA_JS_MODULES = [
EXTRA_JS_MODULES += [
'NetworkStatsDB.jsm',
'NetworkStatsService.jsm',
]

View File

@ -3,8 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/TimeEvent.h"
#include "mozilla/BasicEvents.h"
#include "nsIDocShell.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsPresContext.h"
@ -14,26 +14,18 @@ namespace dom {
TimeEvent::TimeEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent)
InternalSMILTimeEvent* aEvent)
: Event(aOwner, aPresContext,
aEvent ? aEvent : new InternalUIEvent(false, 0))
, mDetail(0)
aEvent ? aEvent : new InternalSMILTimeEvent(false, 0))
, mDetail(mEvent->AsSMILTimeEvent()->detail)
{
SetIsDOMBinding();
if (aEvent) {
mEventIsInternal = false;
} else {
mEventIsInternal = true;
mEvent->eventStructType = NS_SMIL_TIME_EVENT;
}
if (mEvent->eventStructType == NS_SMIL_TIME_EVENT) {
mDetail = mEvent->AsUIEvent()->detail;
}
mEvent->mFlags.mBubbles = false;
mEvent->mFlags.mCancelable = false;
if (mPresContext) {
nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell();
if (docShell) {
@ -92,7 +84,7 @@ nsresult
NS_NewDOMTimeEvent(nsIDOMEvent** aInstancePtrResult,
EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent)
InternalSMILTimeEvent* aEvent)
{
TimeEvent* it = new TimeEvent(aOwner, aPresContext, aEvent);
NS_ADDREF(it);

View File

@ -19,7 +19,7 @@ class TimeEvent MOZ_FINAL : public Event,
public:
TimeEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent);
InternalSMILTimeEvent* aEvent);
// nsISupports interface:
NS_DECL_ISUPPORTS_INHERITED

View File

@ -5,7 +5,7 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/dom/SVGAnimationElement.h"
#include "nsSMILTimedElement.h"
@ -92,8 +92,7 @@ namespace
NS_IMETHOD Run()
{
InternalUIEvent event(true, mMsg);
event.eventStructType = NS_SMIL_TIME_EVENT;
InternalSMILTimeEvent event(true, mMsg);
event.detail = mDetail;
nsPresContext* context = nullptr;

Some files were not shown because too many files have changed in this diff Show More