Compare commits
198
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30e287371f | ||
|
|
a9246d7b28 | ||
|
|
db1d73f05d | ||
|
|
72b14ea177 | ||
|
|
430c4a3f79 | ||
|
|
93ed92f63b | ||
|
|
4a1312c060 | ||
|
|
303e1ecf34 | ||
|
|
57b0e4a65b | ||
|
|
804a301068 | ||
|
|
aedb8a4d08 | ||
|
|
93072ab51e | ||
|
|
ca11a325bd | ||
|
|
3b088af0b1 | ||
|
|
09e52646e9 | ||
|
|
26ca6f4fcc | ||
|
|
b467d710ac | ||
|
|
f4f11fada8 | ||
|
|
43b3b47426 | ||
|
|
daa31cfd59 | ||
|
|
b4ad4b7293 | ||
|
|
a2947909e8 | ||
|
|
bc2d0521e7 | ||
|
|
95ca42dd06 | ||
|
|
0c0dfca015 | ||
|
|
17cd2e4d07 | ||
|
|
f305547835 | ||
|
|
5ee86104a8 | ||
|
|
0ab247bee9 | ||
|
|
5370edc560 | ||
|
|
f27b6cbd21 | ||
|
|
de3485ed67 | ||
|
|
7f8489bc11 | ||
|
|
8c1cf4cc02 | ||
|
|
b8fbac6365 | ||
|
|
c7cc4ef650 | ||
|
|
9d1789b62f | ||
|
|
9a1c99e1a2 | ||
|
|
abc435f18e | ||
|
|
2e6dab8672 | ||
|
|
e0b95b12da | ||
|
|
722ecd0d97 | ||
|
|
e72cc38641 | ||
|
|
ae227b8743 | ||
|
|
a268e57967 | ||
|
|
9f05dad78c | ||
|
|
ba0112d574 | ||
|
|
5b449bc031 | ||
|
|
b823c130c1 | ||
|
|
437d9da605 | ||
|
|
f49a57006f | ||
|
|
18096194f5 | ||
|
|
8ca0f22841 | ||
|
|
b4e9888d91 | ||
|
|
30b01396b4 | ||
|
|
9343129fbb | ||
|
|
e79ddda9de | ||
|
|
f84c92881d | ||
|
|
aeafa7fef8 | ||
|
|
ff3db332fe | ||
|
|
68d53612af | ||
|
|
0fb9b4abbf | ||
|
|
ab442f72b9 | ||
|
|
b85d16b615 | ||
|
|
cc7d9550bc | ||
|
|
bc2d2edbef | ||
|
|
bc5c6c7563 | ||
|
|
0d971f0c5a | ||
|
|
99d225ae7f | ||
|
|
4bb7951324 | ||
|
|
20c29f74b4 | ||
|
|
d9a4414ef0 | ||
|
|
56be1ceaef | ||
|
|
fd0ddefa03 | ||
|
|
00e3d12e1d | ||
|
|
3a81d02c0f | ||
|
|
5fbb929250 | ||
|
|
4cb28647fe | ||
|
|
002240592a | ||
|
|
8f95d938d5 | ||
|
|
c66294c51a | ||
|
|
abc96cf444 | ||
|
|
a3019dddc1 | ||
|
|
bd03f965a3 | ||
|
|
358d39d4bf | ||
|
|
77571794a3 | ||
|
|
a935ef810c | ||
|
|
eb731d1377 | ||
|
|
c275325fbf | ||
|
|
84da3d4817 | ||
|
|
c868ea1f58 | ||
|
|
d5e385dc73 | ||
|
|
d49758ace1 | ||
|
|
f3ee6e294f | ||
|
|
dea96fe9d3 | ||
|
|
29a5e8df12 | ||
|
|
51941fd085 | ||
|
|
64ea5dd93a | ||
|
|
a42d420ee5 | ||
|
|
060995dfff | ||
|
|
991bd7b460 | ||
|
|
db503078d0 | ||
|
|
8ee58d2591 | ||
|
|
c340a1dcd2 | ||
|
|
774a6aa4dd | ||
|
|
b2566429fc | ||
|
|
f66bcb4f23 | ||
|
|
0e7430735e | ||
|
|
905c7e8785 | ||
|
|
9d91a43142 | ||
|
|
53bac56f36 | ||
|
|
e85fff2f10 | ||
|
|
839236c912 | ||
|
|
1e3fddbe14 | ||
|
|
b5576d1485 | ||
|
|
524b466197 | ||
|
|
7d1b245754 | ||
|
|
64a0846a1c | ||
|
|
118bd414d4 | ||
|
|
3f319c5f29 | ||
|
|
8b06eaa8fc | ||
|
|
e62bd7c533 | ||
|
|
0839a82f80 | ||
|
|
4cbaf927d9 | ||
|
|
b4f364c385 | ||
|
|
6ede629146 | ||
|
|
c684599599 | ||
|
|
c9bfd79ae0 | ||
|
|
6d3f71d200 | ||
|
|
620e391be7 | ||
|
|
532a1355ce | ||
|
|
03367d9c41 | ||
|
|
6ebd205c8e | ||
|
|
7276ea00a7 | ||
|
|
7a5c56bc58 | ||
|
|
9e064c7045 | ||
|
|
6933bfe783 | ||
|
|
5e81fb065a | ||
|
|
f08b4276ea | ||
|
|
45d7dda330 | ||
|
|
a8f1878ff3 | ||
|
|
d0ec80aa86 | ||
|
|
a9257dea7d | ||
|
|
af5d12a154 | ||
|
|
fb4ebd7838 | ||
|
|
7ace23060a | ||
|
|
19504eed91 | ||
|
|
7c72b41e2c | ||
|
|
6fc971d8c0 | ||
|
|
a410f9e553 | ||
|
|
a00f48f894 | ||
|
|
699d64c8f3 | ||
|
|
c6bc9d5a8c | ||
|
|
e96431e1c1 | ||
|
|
773aa9dcc3 | ||
|
|
998086ca31 | ||
|
|
7abbbc6cf4 | ||
|
|
1873f5df88 | ||
|
|
f39980b4c7 | ||
|
|
40ac200988 | ||
|
|
4344b62a3a | ||
|
|
3267ae2ef7 | ||
|
|
1eb24b9f9c | ||
|
|
a9e11bdca7 | ||
|
|
02fb8a4ca3 | ||
|
|
d62f6b37bf | ||
|
|
aaae14d111 | ||
|
|
672c153d73 | ||
|
|
a1a2a6f9ce | ||
|
|
006caf963a | ||
|
|
b314539aa8 | ||
|
|
aac26aa7fa | ||
|
|
aefe484468 | ||
|
|
f9b633adcd | ||
|
|
a5f3d76fda | ||
|
|
2098629f2d | ||
|
|
c67dc90bb8 | ||
|
|
69945a779c | ||
|
|
f8de26bf0c | ||
|
|
603cc43e14 | ||
|
|
4b4d734897 | ||
|
|
cb629d38aa | ||
|
|
07b05ebc21 | ||
|
|
6debbcd228 | ||
|
|
6258c24c8c | ||
|
|
b5a5ea161a | ||
|
|
1462612e3c | ||
|
|
75d0cedb1a | ||
|
|
f660e617a3 | ||
|
|
a454e08683 | ||
|
|
5bbc63d590 | ||
|
|
b514d09a14 | ||
|
|
d828b69cd1 | ||
|
|
067ec2edd4 | ||
|
|
01719ee5c5 | ||
|
|
5e4e7df657 | ||
|
|
0c1671073e | ||
|
|
3a42d26c36 |
No files matched your search
@@ -11,9 +11,14 @@ def moz_jemalloc4(value):
|
||||
|
||||
option('--enable-jemalloc', env='MOZ_MEMORY',
|
||||
help='Replace system memory allocator with jemalloc')
|
||||
option('--enable-mimalloc',
|
||||
help='Replace system memory allocator with mimalloc')
|
||||
|
||||
@depends('--enable-jemalloc', target, build_project, c_compiler)
|
||||
def jemalloc(value, target, build_project, c_compiler):
|
||||
@depends('--enable-jemalloc', '--enable-mimalloc', target, build_project,
|
||||
c_compiler)
|
||||
def jemalloc(value, mimalloc, target, build_project, c_compiler):
|
||||
if value and mimalloc:
|
||||
die('--enable-jemalloc and --enable-mimalloc cannot be used together')
|
||||
if value.origin != 'default':
|
||||
return bool(value) or None
|
||||
|
||||
@@ -30,11 +35,38 @@ def jemalloc(value, target, build_project, c_compiler):
|
||||
if target.kernel == 'Linux':
|
||||
return True
|
||||
|
||||
@depends('--enable-mimalloc', '--enable-jemalloc', target)
|
||||
def mimalloc(value, jemalloc, target):
|
||||
if value and jemalloc:
|
||||
die('--enable-jemalloc and --enable-mimalloc cannot be used together')
|
||||
if value.origin != 'default':
|
||||
if not value:
|
||||
return None
|
||||
if target.kernel not in ('Darwin', 'WINNT', 'Linux', 'kFreeBSD', 'FreeBSD',
|
||||
'NetBSD', 'OpenBSD', 'DragonFly'):
|
||||
die('--enable-mimalloc is not supported on %s', target.kernel)
|
||||
return True
|
||||
|
||||
@depends('--enable-mimalloc', '--enable-jemalloc')
|
||||
def mimalloc_requires_disable(mimalloc, jemalloc):
|
||||
if not mimalloc:
|
||||
return
|
||||
if jemalloc or jemalloc.origin not in ('command-line', 'mozconfig'):
|
||||
die('--enable-mimalloc requires --disable-jemalloc to be passed explicitly')
|
||||
|
||||
|
||||
set_config('MOZ_MEMORY', jemalloc)
|
||||
set_define('MOZ_MEMORY', jemalloc)
|
||||
add_old_configure_assignment('MOZ_MEMORY', jemalloc)
|
||||
|
||||
@depends(mimalloc)
|
||||
def mimalloc_config(mimalloc):
|
||||
return True if mimalloc else False
|
||||
|
||||
set_config('MOZ_MIMALLOC', mimalloc_config)
|
||||
set_define('MOZ_MIMALLOC', mimalloc)
|
||||
add_old_configure_assignment('MOZ_MIMALLOC', mimalloc_config)
|
||||
|
||||
|
||||
# Because --enable-jemalloc doesn't use a default because of the dependency
|
||||
# on the target, we can't use a js_option for it to propagate to js/src
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
# Referenced by milestone.py.
|
||||
#--------------------------------------------------------
|
||||
|
||||
6.8.0
|
||||
6.8.1
|
||||
@@ -348,11 +348,7 @@ ifdef SHARED_LIBRARY
|
||||
ifdef IS_COMPONENT
|
||||
EXTRA_DSO_LDOPTS += -bundle
|
||||
else
|
||||
ifdef MOZ_IOS
|
||||
_LOADER_PATH := @rpath
|
||||
else
|
||||
_LOADER_PATH := @executable_path
|
||||
endif
|
||||
EXTRA_DSO_LDOPTS += -dynamiclib -install_name $(_LOADER_PATH)/$(SHARED_LIBRARY) -compatibility_version 1 -current_version 1 -single_module
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "mozilla/dom/MessageEventBinding.h"
|
||||
#include "mozilla/dom/nsCSPContext.h"
|
||||
#include "mozilla/dom/nsCSPUtils.h"
|
||||
#include "mozilla/dom/nsMixedContentBlocker.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
@@ -1604,10 +1605,10 @@ WebSocketImpl::Init(JSContext* aCx,
|
||||
mInnerWindowID);
|
||||
}
|
||||
|
||||
// Don't allow https:// to open ws://
|
||||
// Don't allow https:// to open ws://, except when explicitly preffed or a loopback address.
|
||||
if (!mIsServerSide && !mSecure &&
|
||||
!Preferences::GetBool("network.websocket.allowInsecureFromHTTPS",
|
||||
false)) {
|
||||
!Preferences::GetBool("network.websocket.allowInsecureFromHTTPS", false) &&
|
||||
!nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(mAsciiHost)) {
|
||||
// Confirmed we are opening plain ws:// and want to prevent this from a
|
||||
// secure context (e.g. https).
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
|
||||
@@ -101,6 +101,8 @@ GK_ATOM(animations, "animations")
|
||||
GK_ATOM(anonid, "anonid")
|
||||
GK_ATOM(anonlocation, "anonlocation")
|
||||
GK_ATOM(any, "any")
|
||||
GK_ATOM(any_hover, "any-hover")
|
||||
GK_ATOM(any_pointer, "any-pointer")
|
||||
GK_ATOM(applet, "applet")
|
||||
GK_ATOM(applyImports, "apply-imports")
|
||||
GK_ATOM(applyTemplates, "apply-templates")
|
||||
@@ -1533,6 +1535,7 @@ GK_ATOM(patternContentUnits, "patternContentUnits")
|
||||
GK_ATOM(patternTransform, "patternTransform")
|
||||
GK_ATOM(patternUnits, "patternUnits")
|
||||
GK_ATOM(pc, "pc")
|
||||
GK_ATOM(pointer, "pointer")
|
||||
GK_ATOM(pointer_events, "pointer-events")
|
||||
GK_ATOM(points, "points")
|
||||
GK_ATOM(pointsAtX, "pointsAtX")
|
||||
|
||||
@@ -111,3 +111,4 @@ MSG_DEF(MSG_PMO_INVALID_MEMBERS, 0, JSEXN_TYPEERR, "PerformanceMeasureOptions ca
|
||||
MSG_DEF(MSG_PMO_CONSTRUCTOR_INACCESSIBLE, 0, JSEXN_TYPEERR, "Can't access PerformanceMark constructor, performance is null.")
|
||||
MSG_DEF(MSG_PMO_UNEXPECTED_START_TIME, 0, JSEXN_TYPEERR, "Expected startTime >= 0.")
|
||||
MSG_DEF(MSG_PMO_INVALID_ATTR_FOR_NON_GLOBAL, 1, JSEXN_TYPEERR, "Cannot get PerformanceTiming attribute values for non-Window global object. Given: {0}.")
|
||||
MSG_DEF(MSG_NOT_SUBMIT_BUTTON, 0, JSEXN_TYPEERR, "The submitter is not a submit button.")
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "mozilla/dom/ScrollAreaEvent.h"
|
||||
#include "mozilla/dom/SimpleGestureEvent.h"
|
||||
#include "mozilla/dom/StorageEvent.h"
|
||||
#include "mozilla/dom/SubmitEvent.h"
|
||||
#include "mozilla/dom/TimeEvent.h"
|
||||
#include "mozilla/dom/TouchEvent.h"
|
||||
#include "mozilla/dom/TransitionEvent.h"
|
||||
@@ -1066,6 +1067,12 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
|
||||
case eAnimationEventClass:
|
||||
return NS_NewDOMAnimationEvent(aOwner, aPresContext,
|
||||
aEvent->AsAnimationEvent());
|
||||
case eFormEventClass:
|
||||
if (aEvent->mMessage == eFormSubmit) {
|
||||
return NS_NewDOMSubmitEvent(aOwner, aPresContext,
|
||||
aEvent->AsFormEvent());
|
||||
}
|
||||
return NS_NewDOMEvent(aOwner, aPresContext, aEvent);
|
||||
default:
|
||||
// For all other types of events, create a vanilla event object.
|
||||
return NS_NewDOMEvent(aOwner, aPresContext, aEvent);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "mozilla/dom/SubmitEvent.h"
|
||||
|
||||
#include "mozilla/ContentEvents.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(SubmitEvent, Event, mSubmitter)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(SubmitEvent, Event)
|
||||
NS_IMPL_RELEASE_INHERITED(SubmitEvent, Event)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SubmitEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(Event)
|
||||
|
||||
SubmitEvent::SubmitEvent(EventTarget* aOwner,
|
||||
nsPresContext* aPresContext,
|
||||
InternalFormEvent* aEvent)
|
||||
: Event(aOwner, aPresContext, aEvent)
|
||||
{
|
||||
if (aEvent) {
|
||||
nsIContent* originator = aEvent->mOriginator;
|
||||
if (originator && originator->IsHTMLElement()) {
|
||||
mSubmitter = static_cast<::nsGenericHTMLElement*>(originator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<SubmitEvent>
|
||||
SubmitEvent::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
const SubmitEventInit& aParam,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
RefPtr<SubmitEvent> e = new SubmitEvent(t, nullptr, nullptr);
|
||||
bool trusted = e->Init(t);
|
||||
e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
|
||||
e->mSubmitter = aParam.mSubmitter;
|
||||
e->SetTrusted(trusted);
|
||||
e->SetComposed(aParam.mComposed);
|
||||
return e.forget();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
already_AddRefed<SubmitEvent>
|
||||
NS_NewDOMSubmitEvent(EventTarget* aOwner,
|
||||
nsPresContext* aPresContext,
|
||||
InternalFormEvent* aEvent)
|
||||
{
|
||||
RefPtr<SubmitEvent> it = new SubmitEvent(aOwner, aPresContext, aEvent);
|
||||
return it.forget();
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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_dom_SubmitEvent_h_
|
||||
#define mozilla_dom_SubmitEvent_h_
|
||||
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/SubmitEventBinding.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
|
||||
class nsGenericHTMLElement;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class SubmitEvent final : public Event
|
||||
{
|
||||
public:
|
||||
SubmitEvent(EventTarget* aOwner,
|
||||
nsPresContext* aPresContext,
|
||||
InternalFormEvent* aEvent);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SubmitEvent, Event)
|
||||
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_EVENT
|
||||
|
||||
static already_AddRefed<SubmitEvent> Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
const SubmitEventInit& aParam,
|
||||
ErrorResult& aRv);
|
||||
|
||||
::nsGenericHTMLElement* GetSubmitter() const
|
||||
{
|
||||
return mSubmitter;
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
|
||||
{
|
||||
return SubmitEventBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
protected:
|
||||
~SubmitEvent() {}
|
||||
|
||||
private:
|
||||
RefPtr<::nsGenericHTMLElement> mSubmitter;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
already_AddRefed<mozilla::dom::SubmitEvent>
|
||||
NS_NewDOMSubmitEvent(mozilla::dom::EventTarget* aOwner,
|
||||
nsPresContext* aPresContext,
|
||||
mozilla::InternalFormEvent* aEvent);
|
||||
|
||||
#endif // mozilla_dom_SubmitEvent_h_
|
||||
@@ -65,6 +65,7 @@ EXPORTS.mozilla.dom += [
|
||||
'ScrollAreaEvent.h',
|
||||
'SimpleGestureEvent.h',
|
||||
'StorageEvent.h',
|
||||
'SubmitEvent.h',
|
||||
'TextClause.h',
|
||||
'Touch.h',
|
||||
'TouchEvent.h',
|
||||
@@ -115,6 +116,7 @@ UNIFIED_SOURCES += [
|
||||
'ScrollAreaEvent.cpp',
|
||||
'SimpleGestureEvent.cpp',
|
||||
'StorageEvent.cpp',
|
||||
'SubmitEvent.cpp',
|
||||
'TextClause.cpp',
|
||||
'TextComposition.cpp',
|
||||
'Touch.cpp',
|
||||
|
||||
@@ -170,6 +170,7 @@ skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
|
||||
skip-if = toolkit == 'android' #TIMED_OUT
|
||||
[test_eventctors.html]
|
||||
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
|
||||
[test_submit_event.html]
|
||||
[test_eventhandler_scoping.html]
|
||||
[test_eventTimeStamp.html]
|
||||
[test_focus_disabled.html]
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for SubmitEvent and submitter</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
var hasSimpleTest = typeof SimpleTest !== "undefined";
|
||||
function finishIfPossible() {
|
||||
if (hasSimpleTest) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
function okMaybe(cond, msg) {
|
||||
if (hasSimpleTest) {
|
||||
ok(cond, msg);
|
||||
} else {
|
||||
console.log((cond ? "OK: " : "FAIL: ") + msg);
|
||||
}
|
||||
}
|
||||
function isMaybe(a, b, msg) {
|
||||
if (hasSimpleTest) {
|
||||
is(a, b, msg);
|
||||
} else {
|
||||
console.log((a === b ? "OK: " : "FAIL: ") + msg + " (got " + a + " expected " + b + ")");
|
||||
}
|
||||
}
|
||||
if (hasSimpleTest) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
}
|
||||
|
||||
function testConstructor() {
|
||||
okMaybe("SubmitEvent" in window, "SubmitEvent constructor exists");
|
||||
|
||||
var button = document.createElement("button");
|
||||
var ev = new SubmitEvent("submit", { submitter: button, bubbles: true, cancelable: true });
|
||||
isMaybe(ev.type, "submit", "constructor type matches");
|
||||
okMaybe(!ev.isTrusted, "constructed SubmitEvent is not trusted");
|
||||
isMaybe(ev.submitter, button, "constructor submitter matches");
|
||||
|
||||
var ev2 = new SubmitEvent("submit");
|
||||
isMaybe(ev2.submitter, null, "default submitter is null");
|
||||
}
|
||||
|
||||
function testDispatch() {
|
||||
var form = document.createElement("form");
|
||||
var button = document.createElement("button");
|
||||
button.type = "submit";
|
||||
button.textContent = "Submit";
|
||||
form.appendChild(button);
|
||||
document.body.appendChild(form);
|
||||
|
||||
form.addEventListener("submit", function(e) {
|
||||
okMaybe(e instanceof SubmitEvent, "submit event is SubmitEvent");
|
||||
isMaybe(e.submitter, button, "submitter is the clicked button");
|
||||
e.preventDefault();
|
||||
form.remove();
|
||||
finishIfPossible();
|
||||
});
|
||||
|
||||
if (hasSimpleTest) {
|
||||
SimpleTest.executeSoon(function() {
|
||||
button.click();
|
||||
});
|
||||
} else {
|
||||
setTimeout(function() {
|
||||
button.click();
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
testConstructor();
|
||||
testDispatch();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -276,6 +276,41 @@ HTMLFormElement::Submit()
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
|
||||
void
|
||||
HTMLFormElement::RequestSubmit(nsGenericHTMLElement* aSubmitter,
|
||||
ErrorResult& aRv) {
|
||||
// 1. If submitter is not null, then:
|
||||
if (aSubmitter) {
|
||||
nsCOMPtr<nsIFormControl> fc = do_QueryObject(aSubmitter);
|
||||
|
||||
// 1.1. If submitter is not a submit button, then throw a TypeError.
|
||||
if (!fc || !fc->IsSubmitControl()) {
|
||||
aRv.ThrowTypeError<MSG_NOT_SUBMIT_BUTTON>();
|
||||
return;
|
||||
}
|
||||
|
||||
// 1.2. If submitter's form owner is not this form element, then throw a
|
||||
// "NotFoundError" DOMException.
|
||||
if (fc->GetFormElement() != this) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Otherwise, set submitter to this form element.
|
||||
// 3. Submit this form element, from submitter.
|
||||
// We go through the presShell here for the corner case a submit event
|
||||
// is pending while the window is being destroyed.
|
||||
InternalFormEvent event(true, eFormSubmit);
|
||||
event.mOriginator = aSubmitter;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIPresShell> presShell = GetComposedDoc()->GetShell();
|
||||
if (MOZ_LIKELY(presShell)) {
|
||||
presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLFormElement::Reset()
|
||||
{
|
||||
|
||||
@@ -391,6 +391,19 @@ public:
|
||||
|
||||
void Submit(ErrorResult& aRv);
|
||||
|
||||
/**
|
||||
* Requests to submit the form. Unlike submit(), this method includes
|
||||
* interactive constraint validation and firing a submit event,
|
||||
* either of which can cancel submission.
|
||||
*
|
||||
* @param aSubmitter The submitter argument can be used to point to a specific
|
||||
* submit button.
|
||||
* @param aRv An ErrorResult.
|
||||
* @see
|
||||
* https://html.spec.whatwg.org/multipage/forms.html#dom-form-requestsubmit
|
||||
*/
|
||||
void RequestSubmit(nsGenericHTMLElement* aSubmitter, ErrorResult& aRv);
|
||||
|
||||
// XPCOM Reset() is OK
|
||||
|
||||
bool CheckValidity()
|
||||
|
||||
@@ -371,6 +371,9 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(TrackType aTrack)
|
||||
case TrackType::kVideoTrack: {
|
||||
// Decoders use the layers backend to decide if they can use hardware decoding,
|
||||
// so specify LAYERS_NONE if we want to forcibly disable it.
|
||||
using Option = CreateDecoderParams::Option;
|
||||
using OptionSet = CreateDecoderParams::OptionSet;
|
||||
|
||||
data.mDecoder = mOwner->mPlatform->CreateDecoder({
|
||||
ownerData.mInfo
|
||||
? *ownerData.mInfo->GetAsVideoInfo()
|
||||
@@ -383,7 +386,10 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(TrackType aTrack)
|
||||
mOwner->mCrashHelper,
|
||||
#endif
|
||||
ownerData.mIsBlankDecode,
|
||||
&result
|
||||
&result,
|
||||
OptionSet(ownerData.mHardwareDecodingDisabled
|
||||
? Option::HardwareDecoderNotAllowed
|
||||
: Option::Default)
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -921,6 +927,8 @@ MediaFormatReader::NotifyNewOutput(TrackType aTrack, MediaData* aSample)
|
||||
decoder.mOutput.AppendElement(aSample);
|
||||
decoder.mNumSamplesOutput++;
|
||||
decoder.mNumOfConsecutiveError = 0;
|
||||
// We have decoded our first frame, we can now start to skip future errors.
|
||||
decoder.mFirstFrameTime.reset();
|
||||
ScheduleUpdate(aTrack);
|
||||
}
|
||||
|
||||
@@ -1415,7 +1423,7 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||
RefPtr<MediaData> output = decoder.mOutput[0];
|
||||
decoder.mOutput.RemoveElementAt(0);
|
||||
decoder.mSizeOfQueue -= 1;
|
||||
decoder.mLastSampleTime =
|
||||
decoder.mLastDecodedSampleTime =
|
||||
Some(TimeInterval(TimeUnit::FromMicroseconds(output->mTime),
|
||||
TimeUnit::FromMicroseconds(output->GetEndTime())));
|
||||
decoder.mNumSamplesOutputTotal++;
|
||||
@@ -1463,14 +1471,14 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||
LOG("Rejecting %s promise: EOS", TrackTypeToStr(aTrack));
|
||||
decoder.RejectPromise(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
|
||||
} else if (decoder.mWaitingForData) {
|
||||
if (wasDraining && decoder.mLastSampleTime &&
|
||||
if (wasDraining && decoder.mLastDecodedSampleTime &&
|
||||
!decoder.mNextStreamSourceID) {
|
||||
// We have completed draining the decoder following WaitingForData.
|
||||
// Set up the internal seek machinery to be able to resume from the
|
||||
// last sample decoded.
|
||||
LOG("Seeking to last sample time: %lld",
|
||||
decoder.mLastSampleTime.ref().mStart.ToMicroseconds());
|
||||
InternalSeek(aTrack, InternalSeekTarget(decoder.mLastSampleTime.ref(), true));
|
||||
decoder.mLastDecodedSampleTime.ref().mStart.ToMicroseconds());
|
||||
InternalSeek(aTrack, InternalSeekTarget(decoder.mLastDecodedSampleTime.ref(), true));
|
||||
}
|
||||
if (!decoder.mReceivedNewData) {
|
||||
LOG("Rejecting %s promise: WAITING_FOR_DATA", TrackTypeToStr(aTrack));
|
||||
@@ -1506,24 +1514,52 @@ MediaFormatReader::Update(TrackType aTrack)
|
||||
|
||||
if (decoder.mError && !decoder.HasFatalError()) {
|
||||
decoder.mDecodePending = false;
|
||||
bool needsNewDecoder = decoder.mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER;
|
||||
|
||||
MOZ_RELEASE_ASSERT(!decoder.HasInternalSeekPending(),
|
||||
"No error can occur while an internal seek is pending");
|
||||
|
||||
nsCString error;
|
||||
bool firstFrameDecodingFailedWithHardware =
|
||||
decoder.mFirstFrameTime &&
|
||||
decoder.mError.ref() == NS_ERROR_DOM_MEDIA_DECODE_ERR &&
|
||||
decoder.mDecoder && decoder.mDecoder->IsHardwareAccelerated(error) &&
|
||||
!decoder.mHardwareDecodingDisabled;
|
||||
bool needsNewDecoder =
|
||||
decoder.mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER ||
|
||||
firstFrameDecodingFailedWithHardware;
|
||||
if (!needsNewDecoder && ++decoder.mNumOfConsecutiveError > decoder.mMaxConsecutiveError) {
|
||||
NotifyError(aTrack, decoder.mError.ref());
|
||||
return;
|
||||
}
|
||||
if (firstFrameDecodingFailedWithHardware) {
|
||||
decoder.mHardwareDecodingDisabled = true;
|
||||
}
|
||||
decoder.mError.reset();
|
||||
LOG("%s decoded error count %d", TrackTypeToStr(aTrack),
|
||||
decoder.mNumOfConsecutiveError);
|
||||
|
||||
if (needsNewDecoder) {
|
||||
LOG("Error: Need new decoder");
|
||||
decoder.ShutdownDecoder();
|
||||
}
|
||||
if (decoder.mFirstFrameTime) {
|
||||
TimeInterval seekInterval = TimeInterval(decoder.mFirstFrameTime.ref(),
|
||||
decoder.mFirstFrameTime.ref());
|
||||
InternalSeek(aTrack, InternalSeekTarget(seekInterval, false));
|
||||
return;
|
||||
}
|
||||
|
||||
media::TimeUnit nextKeyframe;
|
||||
if (aTrack == TrackType::kVideoTrack && !decoder.HasInternalSeekPending() &&
|
||||
NS_SUCCEEDED(decoder.mTrackDemuxer->GetNextRandomAccessPoint(&nextKeyframe))) {
|
||||
if (needsNewDecoder) {
|
||||
decoder.ShutdownDecoder();
|
||||
}
|
||||
SkipVideoDemuxToNextKeyFrame(decoder.mLastSampleTime.refOr(TimeInterval()).Length());
|
||||
NS_SUCCEEDED(decoder.mTrackDemuxer->GetNextRandomAccessPoint(&nextKeyframe)) &&
|
||||
!nextKeyframe.IsInfinite()) {
|
||||
SkipVideoDemuxToNextKeyFrame(decoder.mLastDecodedSampleTime.refOr(TimeInterval()).Length());
|
||||
return;
|
||||
} else if (aTrack == TrackType::kAudioTrack) {
|
||||
decoder.Flush();
|
||||
} else {
|
||||
// We can't recover from this error.
|
||||
NotifyError(aTrack, NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1664,6 +1700,7 @@ MediaFormatReader::ResetDecode(TrackSet aTracks)
|
||||
|
||||
if (HasVideo() && aTracks.contains(TrackInfo::kVideoTrack)) {
|
||||
mVideo.ResetDemuxer();
|
||||
mVideo.mFirstFrameTime = Some(media::TimeUnit());
|
||||
Reset(TrackInfo::kVideoTrack);
|
||||
if (mVideo.HasPromise()) {
|
||||
mVideo.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
|
||||
@@ -1672,6 +1709,7 @@ MediaFormatReader::ResetDecode(TrackSet aTracks)
|
||||
|
||||
if (HasAudio() && aTracks.contains(TrackInfo::kAudioTrack)) {
|
||||
mAudio.ResetDemuxer();
|
||||
mVideo.mFirstFrameTime = Some(media::TimeUnit());
|
||||
Reset(TrackInfo::kAudioTrack);
|
||||
if (mAudio.HasPromise()) {
|
||||
mAudio.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
|
||||
@@ -2030,6 +2068,7 @@ MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
|
||||
LOGV("Video seeked to %lld", aTime.ToMicroseconds());
|
||||
mVideo.mSeekRequest.Complete();
|
||||
|
||||
mVideo.mFirstFrameTime = Some(aTime);
|
||||
mPreviousDecodedKeyframeTime_us = sNoPreviousDecodedKeyframe;
|
||||
|
||||
SetVideoDecodeThreshold();
|
||||
@@ -2111,6 +2150,7 @@ MediaFormatReader::OnAudioSeekCompleted(media::TimeUnit aTime)
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
LOGV("Audio seeked to %lld", aTime.ToMicroseconds());
|
||||
mAudio.mSeekRequest.Complete();
|
||||
mAudio.mFirstFrameTime = Some(aTime);
|
||||
mPendingSeekTime.reset();
|
||||
mSeekPromise.Resolve(aTime, __func__);
|
||||
}
|
||||
|
||||
@@ -235,6 +235,7 @@ private:
|
||||
, mDrainComplete(false)
|
||||
, mNumOfConsecutiveError(0)
|
||||
, mMaxConsecutiveError(aNumOfMaxError)
|
||||
, mFirstFrameTime(Some(media::TimeUnit()))
|
||||
, mNumSamplesInput(0)
|
||||
, mNumSamplesOutput(0)
|
||||
, mNumSamplesOutputTotal(0)
|
||||
@@ -243,6 +244,7 @@ private:
|
||||
, mIsHardwareAccelerated(false)
|
||||
, mLastStreamSourceID(UINT32_MAX)
|
||||
, mIsBlankDecode(false)
|
||||
, mHardwareDecodingDisabled(false)
|
||||
{}
|
||||
|
||||
MediaFormatReader* mOwner;
|
||||
@@ -316,6 +318,11 @@ private:
|
||||
|
||||
uint32_t mNumOfConsecutiveError;
|
||||
uint32_t mMaxConsecutiveError;
|
||||
// Set when we haven't yet decoded the first frame.
|
||||
// Cleared once the first frame has been decoded.
|
||||
// This is used to determine, upon error, if we should try again to decode
|
||||
// the frame, or skip to the next keyframe.
|
||||
Maybe<media::TimeUnit> mFirstFrameTime;
|
||||
|
||||
Maybe<MediaResult> mError;
|
||||
bool HasFatalError() const
|
||||
@@ -341,8 +348,8 @@ private:
|
||||
// Used for internal seeking when a change of stream is detected or when
|
||||
// encountering data discontinuity.
|
||||
Maybe<InternalSeekTarget> mTimeThreshold;
|
||||
// Time of last sample returned.
|
||||
Maybe<media::TimeInterval> mLastSampleTime;
|
||||
// Time of last decoded sample returned.
|
||||
Maybe<media::TimeInterval> mLastDecodedSampleTime;
|
||||
|
||||
// Decoded samples returned my mDecoder awaiting being returned to
|
||||
// state machine upon request.
|
||||
@@ -405,7 +412,7 @@ private:
|
||||
mDraining = false;
|
||||
mDrainComplete = false;
|
||||
mTimeThreshold.reset();
|
||||
mLastSampleTime.reset();
|
||||
mLastDecodedSampleTime.reset();
|
||||
mOutput.Clear();
|
||||
mNumSamplesInput = 0;
|
||||
mNumSamplesOutput = 0;
|
||||
@@ -437,6 +444,7 @@ private:
|
||||
Maybe<media::TimeUnit> mFirstDemuxedSampleTime;
|
||||
// Use BlankDecoderModule or not.
|
||||
bool mIsBlankDecode;
|
||||
bool mHardwareDecodingDisabled;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define GMP_DEVICE_BINDING_h_
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "ImageContainer.h"
|
||||
#include "MediaDecoderReader.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "mozilla/EnumSet.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/layers/KnowsCompositor.h"
|
||||
@@ -47,6 +48,13 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
|
||||
: mConfig(aConfig)
|
||||
{}
|
||||
|
||||
enum class Option
|
||||
{
|
||||
Default,
|
||||
HardwareDecoderNotAllowed,
|
||||
};
|
||||
using OptionSet = EnumSet<Option>;
|
||||
|
||||
template <typename T1, typename... Ts>
|
||||
CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
|
||||
: mConfig(aConfig)
|
||||
@@ -85,6 +93,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
|
||||
RefPtr<GMPCrashHelper> mCrashHelper;
|
||||
#endif
|
||||
bool mUseBlankDecoder = false;
|
||||
OptionSet mOptions = OptionSet(Option::Default);
|
||||
|
||||
private:
|
||||
void Set(TaskQueue* aTaskQueue) { mTaskQueue = aTaskQueue; }
|
||||
@@ -96,6 +105,7 @@ private:
|
||||
void Set(GMPCrashHelper* aCrashHelper) { mCrashHelper = aCrashHelper; }
|
||||
#endif
|
||||
void Set(bool aUseBlankDecoder) { mUseBlankDecoder = aUseBlankDecoder; }
|
||||
void Set(OptionSet aOptions) { mOptions = aOptions; }
|
||||
void Set(layers::KnowsCompositor* aKnowsCompositor) { mKnowsCompositor = aKnowsCompositor; }
|
||||
template <typename T1, typename T2, typename... Ts>
|
||||
void Set(T1&& a1, T2&& a2, Ts&&... args)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VPXDecoder.h"
|
||||
#include "mp4_demuxer/BitReader.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "nsError.h"
|
||||
#include "TimeUnits.h"
|
||||
@@ -383,5 +384,32 @@ VPXDecoder::GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec)
|
||||
return nsIntSize(si.w, si.h);
|
||||
}
|
||||
|
||||
/* static */
|
||||
int
|
||||
VPXDecoder::GetVP9Profile(Span<const uint8_t> aBuffer)
|
||||
{
|
||||
if (aBuffer.Length() < 2) {
|
||||
// Can't be good.
|
||||
return -1;
|
||||
}
|
||||
mp4_demuxer::BitReader br(aBuffer.Elements(), aBuffer.Length() * 8);
|
||||
|
||||
uint32_t frameMarker = br.ReadBits(2); // frame_marker
|
||||
if (frameMarker != 2) {
|
||||
// That's not a valid vp9 header.
|
||||
return -1;
|
||||
}
|
||||
uint32_t profile = br.ReadBits(1); // profile_low_bit
|
||||
profile |= br.ReadBits(1) << 1; // profile_high_bit
|
||||
if (profile == 3) {
|
||||
profile += br.ReadBits(1); // reserved_zero
|
||||
if (profile > 3) {
|
||||
// reserved_zero wasn't zero.
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
#undef LOG
|
||||
@@ -53,6 +53,10 @@ public:
|
||||
// Return the frame dimensions for a sample for the specified codec.
|
||||
static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec);
|
||||
|
||||
// Return the VP9 profile as per https://www.webmproject.org/vp9/profiles/
|
||||
// Return negative value if error.
|
||||
static int GetVP9Profile(Span<const uint8_t> aBuffer);
|
||||
|
||||
private:
|
||||
void ProcessDecode(MediaRawData* aSample);
|
||||
MediaResult DoDecode(MediaRawData* aSample);
|
||||
|
||||
@@ -40,11 +40,7 @@ AppleVTDecoder::AppleVTDecoder(const VideoInfo& aConfig,
|
||||
, mMaxRefFrames(mp4_demuxer::H264::ComputeMaxRefFrames(aConfig.mExtraData))
|
||||
, mImageContainer(aImageContainer)
|
||||
, mIsShutDown(false)
|
||||
#ifdef MOZ_WIDGET_UIKIT
|
||||
, mUseSoftwareImages(true)
|
||||
#else
|
||||
, mUseSoftwareImages(false)
|
||||
#endif
|
||||
, mIsFlushing(false)
|
||||
, mMonitor("AppleVideoDecoder")
|
||||
, mFormat(nullptr)
|
||||
@@ -356,7 +352,6 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
|
||||
// Unlock the returned image data.
|
||||
CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
|
||||
} else {
|
||||
#ifndef MOZ_WIDGET_UIKIT
|
||||
IOSurfacePtr surface = MacIOSurfaceLib::CVPixelBufferGetIOSurface(aImage);
|
||||
MOZ_ASSERT(surface, "Decoder didn't return an IOSurface backed buffer");
|
||||
|
||||
@@ -373,9 +368,6 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
|
||||
aFrameRef.is_sync_point,
|
||||
aFrameRef.decode_timestamp.ToMicroseconds(),
|
||||
visible);
|
||||
#else
|
||||
MOZ_ASSERT_UNREACHABLE("No MacIOSurface on iOS");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
|
||||
@@ -91,11 +91,12 @@ WMFDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<WMFVideoMFTManager> manager(
|
||||
new WMFVideoMFTManager(aParams.VideoConfig(),
|
||||
aParams.mKnowsCompositor,
|
||||
aParams.mImageContainer,
|
||||
sDXVAEnabled));
|
||||
nsAutoPtr<WMFVideoMFTManager> manager(new WMFVideoMFTManager(
|
||||
aParams.VideoConfig(),
|
||||
aParams.mKnowsCompositor,
|
||||
aParams.mImageContainer,
|
||||
sDXVAEnabled && !aParams.mOptions.contains(
|
||||
CreateDecoderParams::Option::HardwareDecoderNotAllowed)));
|
||||
|
||||
if (!manager->Init()) {
|
||||
return nullptr;
|
||||
|
||||
@@ -576,6 +576,16 @@ WMFVideoMFTManager::Input(MediaRawData* aSample)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (mStreamType == VP9 && aSample->mKeyframe) {
|
||||
// Check the VP9 profile. the VP9 MFT can only handle correctly profile 0
|
||||
// and 2 (yuv420 8/10/12 bits)
|
||||
int profile =
|
||||
VPXDecoder::GetVP9Profile(MakeSpan(aSample->Data(), aSample->Size()));
|
||||
if (profile != 0 && profile != 2) {
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = mDecoder->CreateInputSample(aSample->Data(),
|
||||
uint32_t(aSample->Size()),
|
||||
aSample->mTime,
|
||||
@@ -990,7 +1000,12 @@ WMFVideoMFTManager::Output(int64_t aStreamOffset,
|
||||
aOutData = frame;
|
||||
// Set the potentially corrected pts and duration.
|
||||
aOutData->mTime = pts.ToMicroseconds();
|
||||
aOutData->mDuration = duration.ToMicroseconds();
|
||||
// The VP9 decoder doesn't provide a valid duration. AS VP9 doesn't have a
|
||||
// concept of pts vs dts and have no latency. We can as such use the last
|
||||
// known input duration.
|
||||
aOutData->mDuration = (mStreamType == VP9 && duration == media::TimeUnit())
|
||||
? mLastDuration
|
||||
: duration.ToMicroseconds();
|
||||
|
||||
if (mNullOutputCount) {
|
||||
mGotValidOutputAfterNullOutput = true;
|
||||
|
||||
@@ -100,6 +100,45 @@ public:
|
||||
uint32_t mChunksToProcess = 0;
|
||||
};
|
||||
|
||||
/* static */ already_AddRefed<AnalyserNode>
|
||||
AnalyserNode::Create(AudioContext& aAudioContext,
|
||||
const AnalyserOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<AnalyserNode> analyserNode = new AnalyserNode(&aAudioContext);
|
||||
|
||||
analyserNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
analyserNode->SetFftSize(aOptions.mFftSize, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
analyserNode->SetMinDecibels(aOptions.mMinDecibels, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
analyserNode->SetMaxDecibels(aOptions.mMaxDecibels, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
analyserNode->SetSmoothingTimeConstant(aOptions.mSmoothingTimeConstant, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return analyserNode.forget();
|
||||
}
|
||||
|
||||
AnalyserNode::AnalyserNode(AudioContext* aContext)
|
||||
: AudioNode(aContext,
|
||||
1,
|
||||
|
||||
@@ -14,16 +14,26 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct AnalyserOptions;
|
||||
|
||||
class AnalyserNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit AnalyserNode(AudioContext* aContext);
|
||||
static already_AddRefed<AnalyserNode>
|
||||
Create(AudioContext& aAudioContext, const AnalyserOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
static already_AddRefed<AnalyserNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const AnalyserOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
void GetFloatFrequencyData(const Float32Array& aArray);
|
||||
void GetByteFrequencyData(const Uint8Array& aArray);
|
||||
void GetFloatTimeDomainData(const Float32Array& aArray);
|
||||
@@ -61,10 +71,9 @@ public:
|
||||
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
~AnalyserNode() {}
|
||||
|
||||
private:
|
||||
~AnalyserNode() = default;
|
||||
|
||||
friend class AnalyserNodeEngine;
|
||||
void AppendChunk(const AudioChunk& aChunk);
|
||||
bool AllocateBuffer();
|
||||
@@ -73,6 +82,8 @@ private:
|
||||
void GetTimeDomainData(float* aData, size_t aLength);
|
||||
|
||||
private:
|
||||
explicit AnalyserNode(AudioContext* aContext);
|
||||
|
||||
FFTBlock mAnalysisBlock;
|
||||
nsTArray<AudioChunk> mChunks;
|
||||
double mMinDecibels;
|
||||
|
||||
@@ -178,6 +178,24 @@ AudioBuffer::~AudioBuffer()
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<AudioBuffer>
|
||||
AudioBuffer::Constructor(const GlobalObject& aGlobal,
|
||||
AudioContext& aAudioContext,
|
||||
const AudioBufferOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!aOptions.mNumberOfChannels) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
float sampleRate = aOptions.mSampleRate.WasPassed()
|
||||
? aOptions.mSampleRate.Value()
|
||||
: aAudioContext.SampleRate();
|
||||
return Create(&aAudioContext, aOptions.mNumberOfChannels, aOptions.mLength,
|
||||
sampleRate, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
AudioBuffer::ClearJSChannels()
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@ class ThreadSharedFloatArrayBufferList;
|
||||
|
||||
namespace dom {
|
||||
|
||||
struct AudioBufferOptions;
|
||||
class AudioContext;
|
||||
|
||||
/**
|
||||
@@ -56,6 +57,10 @@ public:
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AudioBuffer)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioBuffer)
|
||||
|
||||
static already_AddRefed<AudioBuffer>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const AudioBufferOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
nsPIDOMWindowInner* GetParentObject() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> parentObject = do_QueryReferent(mOwnerWindow);
|
||||
@@ -134,4 +139,3 @@ protected:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -607,10 +607,30 @@ AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* aContext)
|
||||
mStream->AddMainThreadListener(this);
|
||||
}
|
||||
|
||||
AudioBufferSourceNode::~AudioBufferSourceNode()
|
||||
/* static */ already_AddRefed<AudioBufferSourceNode>
|
||||
AudioBufferSourceNode::Create(JSContext* aCx, AudioContext& aAudioContext,
|
||||
const AudioBufferSourceOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
}
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<AudioBufferSourceNode> audioNode = new AudioBufferSourceNode(&aAudioContext);
|
||||
|
||||
if (aOptions.mBuffer.WasPassed()) {
|
||||
MOZ_ASSERT(aCx);
|
||||
audioNode->SetBuffer(aCx, aOptions.mBuffer.Value());
|
||||
}
|
||||
|
||||
audioNode->Detune()->SetValue(aOptions.mDetune);
|
||||
audioNode->SetLoop(aOptions.mLoop);
|
||||
audioNode->SetLoopEnd(aOptions.mLoopEnd);
|
||||
audioNode->SetLoopStart(aOptions.mLoopStart);
|
||||
audioNode->PlaybackRate()->SetValue(aOptions.mPlaybackRate);
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
void
|
||||
AudioBufferSourceNode::DestroyMediaStream()
|
||||
{
|
||||
|
||||
@@ -12,13 +12,16 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct AudioBufferSourceOptions;
|
||||
class AudioParam;
|
||||
|
||||
class AudioBufferSourceNode final : public AudioNode,
|
||||
public MainThreadMediaStreamListener
|
||||
class AudioBufferSourceNode final : public AudioNode
|
||||
, public MainThreadMediaStreamListener
|
||||
{
|
||||
public:
|
||||
explicit AudioBufferSourceNode(AudioContext* aContext);
|
||||
static already_AddRefed<AudioBufferSourceNode>
|
||||
Create(JSContext* aCx, AudioContext& aAudioContext,
|
||||
const AudioBufferSourceOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
void DestroyMediaStream() override;
|
||||
|
||||
@@ -33,6 +36,13 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioBufferSourceNode, AudioNode)
|
||||
|
||||
static already_AddRefed<AudioBufferSourceNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const AudioBufferSourceOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aGlobal.Context(), aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void Start(double aWhen, double aOffset,
|
||||
@@ -98,10 +108,10 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~AudioBufferSourceNode();
|
||||
|
||||
private:
|
||||
explicit AudioBufferSourceNode(AudioContext* aContext);
|
||||
~AudioBufferSourceNode() = default;
|
||||
|
||||
friend class AudioBufferSourceNodeEngine;
|
||||
// START is sent during Start().
|
||||
// STOP is sent during Stop().
|
||||
@@ -129,7 +139,6 @@ private:
|
||||
void SendBufferParameterToStream(JSContext* aCx);
|
||||
void SendOffsetAndDurationParametersToStream(AudioNodeStream* aStream);
|
||||
|
||||
private:
|
||||
double mLoopStart;
|
||||
double mLoopEnd;
|
||||
double mOffset;
|
||||
@@ -145,4 +154,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,10 +11,26 @@
|
||||
#include "mozilla/OwningNonNull.h"
|
||||
|
||||
#include "mozilla/dom/AnalyserNode.h"
|
||||
#include "mozilla/dom/AnalyserNodeBinding.h"
|
||||
#include "mozilla/dom/AudioBufferSourceNodeBinding.h"
|
||||
#include "mozilla/dom/AudioContextBinding.h"
|
||||
#include "mozilla/dom/BiquadFilterNodeBinding.h"
|
||||
#include "mozilla/dom/ChannelMergerNodeBinding.h"
|
||||
#include "mozilla/dom/ChannelSplitterNodeBinding.h"
|
||||
#include "mozilla/dom/ConvolverNodeBinding.h"
|
||||
#include "mozilla/dom/DelayNodeBinding.h"
|
||||
#include "mozilla/dom/DynamicsCompressorNodeBinding.h"
|
||||
#include "mozilla/dom/GainNodeBinding.h"
|
||||
#include "mozilla/dom/IIRFilterNodeBinding.h"
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
#include "mozilla/dom/MediaElementAudioSourceNodeBinding.h"
|
||||
#include "mozilla/dom/MediaStreamAudioSourceNodeBinding.h"
|
||||
#include "mozilla/dom/OfflineAudioContextBinding.h"
|
||||
#include "mozilla/dom/OscillatorNodeBinding.h"
|
||||
#include "mozilla/dom/PannerNodeBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/StereoPannerNodeBinding.h"
|
||||
#include "mozilla/dom/WaveShaperNodeBinding.h"
|
||||
|
||||
#include "AudioBuffer.h"
|
||||
#include "AudioBufferSourceNode.h"
|
||||
@@ -245,13 +261,9 @@ bool AudioContext::CheckClosed(ErrorResult& aRv)
|
||||
already_AddRefed<AudioBufferSourceNode>
|
||||
AudioContext::CreateBufferSource(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<AudioBufferSourceNode> bufferNode =
|
||||
new AudioBufferSourceNode(this);
|
||||
return bufferNode.forget();
|
||||
return AudioBufferSourceNode::Create(nullptr, *this,
|
||||
AudioBufferSourceOptions(),
|
||||
aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<ConstantSourceNode>
|
||||
@@ -303,18 +315,8 @@ bool IsValidBufferSize(uint32_t aBufferSize) {
|
||||
already_AddRefed<MediaStreamAudioDestinationNode>
|
||||
AudioContext::CreateMediaStreamDestination(ErrorResult& aRv)
|
||||
{
|
||||
if (mIsOffline) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<MediaStreamAudioDestinationNode> node =
|
||||
new MediaStreamAudioDestinationNode(this);
|
||||
return node.forget();
|
||||
return MediaStreamAudioDestinationNode::Create(*this, AudioNodeOptions(),
|
||||
aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<ScriptProcessorNode>
|
||||
@@ -344,181 +346,93 @@ AudioContext::CreateScriptProcessor(uint32_t aBufferSize,
|
||||
already_AddRefed<AnalyserNode>
|
||||
AudioContext::CreateAnalyser(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<AnalyserNode> analyserNode = new AnalyserNode(this);
|
||||
return analyserNode.forget();
|
||||
return AnalyserNode::Create(*this, AnalyserOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<StereoPannerNode>
|
||||
AudioContext::CreateStereoPanner(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<StereoPannerNode> stereoPannerNode = new StereoPannerNode(this);
|
||||
return stereoPannerNode.forget();
|
||||
return StereoPannerNode::Create(*this, StereoPannerOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<MediaElementAudioSourceNode>
|
||||
AudioContext::CreateMediaElementSource(HTMLMediaElement& aMediaElement,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (mIsOffline) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
MediaElementAudioSourceOptions options;
|
||||
options.mMediaElement = aMediaElement;
|
||||
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DOMMediaStream> stream =
|
||||
aMediaElement.CaptureAudio(aRv, mDestination->Stream()->Graph());
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
return MediaElementAudioSourceNode::Create(this, stream, aRv);
|
||||
return MediaElementAudioSourceNode::Create(*this, options, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<MediaStreamAudioSourceNode>
|
||||
AudioContext::CreateMediaStreamSource(DOMMediaStream& aMediaStream,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (mIsOffline) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
MediaStreamAudioSourceOptions options;
|
||||
options.mMediaStream = aMediaStream;
|
||||
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return MediaStreamAudioSourceNode::Create(this, &aMediaStream, aRv);
|
||||
return MediaStreamAudioSourceNode::Create(*this, options, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<GainNode>
|
||||
AudioContext::CreateGain(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<GainNode> gainNode = new GainNode(this);
|
||||
return gainNode.forget();
|
||||
return GainNode::Create(*this, GainOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<WaveShaperNode>
|
||||
AudioContext::CreateWaveShaper(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<WaveShaperNode> waveShaperNode = new WaveShaperNode(this);
|
||||
return waveShaperNode.forget();
|
||||
return WaveShaperNode::Create(*this, WaveShaperOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<DelayNode>
|
||||
AudioContext::CreateDelay(double aMaxDelayTime, ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aMaxDelayTime > 0. && aMaxDelayTime < 180.) {
|
||||
RefPtr<DelayNode> delayNode = new DelayNode(this, aMaxDelayTime);
|
||||
return delayNode.forget();
|
||||
}
|
||||
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
DelayOptions options;
|
||||
options.mMaxDelayTime = aMaxDelayTime;
|
||||
return DelayNode::Create(*this, options, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<PannerNode>
|
||||
AudioContext::CreatePanner(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<PannerNode> pannerNode = new PannerNode(this);
|
||||
mPannerNodes.PutEntry(pannerNode);
|
||||
return pannerNode.forget();
|
||||
return PannerNode::Create(*this, PannerOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<ConvolverNode>
|
||||
AudioContext::CreateConvolver(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ConvolverNode> convolverNode = new ConvolverNode(this);
|
||||
return convolverNode.forget();
|
||||
return ConvolverNode::Create(nullptr, *this, ConvolverOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<ChannelSplitterNode>
|
||||
AudioContext::CreateChannelSplitter(uint32_t aNumberOfOutputs, ErrorResult& aRv)
|
||||
{
|
||||
if (aNumberOfOutputs == 0 ||
|
||||
aNumberOfOutputs > WebAudioUtils::MaxChannelCount) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ChannelSplitterNode> splitterNode =
|
||||
new ChannelSplitterNode(this, aNumberOfOutputs);
|
||||
return splitterNode.forget();
|
||||
ChannelSplitterOptions options;
|
||||
options.mNumberOfOutputs = aNumberOfOutputs;
|
||||
return ChannelSplitterNode::Create(*this, options, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<ChannelMergerNode>
|
||||
AudioContext::CreateChannelMerger(uint32_t aNumberOfInputs, ErrorResult& aRv)
|
||||
{
|
||||
if (aNumberOfInputs == 0 ||
|
||||
aNumberOfInputs > WebAudioUtils::MaxChannelCount) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ChannelMergerNode> mergerNode =
|
||||
new ChannelMergerNode(this, aNumberOfInputs);
|
||||
return mergerNode.forget();
|
||||
ChannelMergerOptions options;
|
||||
options.mNumberOfInputs = aNumberOfInputs;
|
||||
return ChannelMergerNode::Create(*this, options, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<DynamicsCompressorNode>
|
||||
AudioContext::CreateDynamicsCompressor(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DynamicsCompressorNode> compressorNode =
|
||||
new DynamicsCompressorNode(this);
|
||||
return compressorNode.forget();
|
||||
return DynamicsCompressorNode::Create(*this, DynamicsCompressorOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<BiquadFilterNode>
|
||||
AudioContext::CreateBiquadFilter(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<BiquadFilterNode> filterNode =
|
||||
new BiquadFilterNode(this);
|
||||
return filterNode.forget();
|
||||
return BiquadFilterNode::Create(*this, BiquadFilterOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<IIRFilterNode>
|
||||
@@ -526,47 +440,16 @@ AudioContext::CreateIIRFilter(const mozilla::dom::binding_detail::AutoSequence<d
|
||||
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aFeedforward.Length() == 0 || aFeedforward.Length() > 20) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aFeedback.Length() == 0 || aFeedback.Length() > 20) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool feedforwardAllZeros = true;
|
||||
for (size_t i = 0; i < aFeedforward.Length(); ++i) {
|
||||
if (aFeedforward.Elements()[i] != 0.0) {
|
||||
feedforwardAllZeros = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (feedforwardAllZeros || aFeedback.Elements()[0] == 0.0) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<IIRFilterNode> filterNode =
|
||||
new IIRFilterNode(this, aFeedforward, aFeedback);
|
||||
return filterNode.forget();
|
||||
IIRFilterOptions options;
|
||||
options.mFeedforward = aFeedforward;
|
||||
options.mFeedback = aFeedback;
|
||||
return IIRFilterNode::Create(*this, options, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<OscillatorNode>
|
||||
AudioContext::CreateOscillator(ErrorResult& aRv)
|
||||
{
|
||||
if (CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<OscillatorNode> oscillatorNode =
|
||||
new OscillatorNode(this);
|
||||
return oscillatorNode.forget();
|
||||
return OscillatorNode::Create(*this, OscillatorOptions(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<PeriodicWave>
|
||||
|
||||
@@ -316,6 +316,8 @@ public:
|
||||
IMPL_EVENT_HANDLER(mozinterruptbegin)
|
||||
IMPL_EVENT_HANDLER(mozinterruptend)
|
||||
|
||||
bool CheckClosed(ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
void DisconnectFromWindow();
|
||||
void RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob);
|
||||
@@ -326,8 +328,6 @@ private:
|
||||
|
||||
friend struct ::mozilla::WebAudioDecodeJob;
|
||||
|
||||
bool CheckClosed(ErrorResult& aRv);
|
||||
|
||||
nsTArray<MediaStream*> GetAllStreams() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -71,6 +71,28 @@ AudioNode::~AudioNode()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioNode::Initialize(const AudioNodeOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
if (aOptions.mChannelCount.WasPassed()) {
|
||||
SetChannelCount(aOptions.mChannelCount.Value(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aOptions.mChannelCountMode.WasPassed()) {
|
||||
SetChannelCountModeValue(aOptions.mChannelCountMode.Value(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aOptions.mChannelInterpretation.WasPassed()) {
|
||||
SetChannelInterpretationValue(aOptions.mChannelInterpretation.Value());
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
AudioNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
|
||||
@@ -250,6 +250,9 @@ private:
|
||||
bool DisconnectFromOutputIfConnected(uint32_t aOutputIndex, uint32_t aInputIndex);
|
||||
|
||||
protected:
|
||||
// Helper for the Constructors for nodes.
|
||||
void Initialize(const AudioNodeOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
// Helpers for sending different value types to streams
|
||||
void SendDoubleParameterToStream(uint32_t aIndex, double aValue);
|
||||
void SendInt32ParameterToStream(uint32_t aIndex, int32_t aValue);
|
||||
|
||||
@@ -262,8 +262,29 @@ BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
BiquadFilterNode::~BiquadFilterNode()
|
||||
/* static */ already_AddRefed<BiquadFilterNode>
|
||||
BiquadFilterNode::Create(AudioContext& aAudioContext,
|
||||
const BiquadFilterOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<BiquadFilterNode> audioNode = new BiquadFilterNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioNode->SetType(aOptions.mType);
|
||||
audioNode->Q()->SetValue(aOptions.mQ);
|
||||
audioNode->Detune()->SetValue(aOptions.mDetune);
|
||||
audioNode->Frequency()->SetValue(aOptions.mFrequency);
|
||||
audioNode->Gain()->SetValue(aOptions.mGain);
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -14,15 +14,25 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct BiquadFilterOptions;
|
||||
|
||||
class BiquadFilterNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit BiquadFilterNode(AudioContext* aContext);
|
||||
static already_AddRefed<BiquadFilterNode>
|
||||
Create(AudioContext& aAudioContext, const BiquadFilterOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BiquadFilterNode, AudioNode)
|
||||
|
||||
static already_AddRefed<BiquadFilterNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const BiquadFilterOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
BiquadFilterType Type() const
|
||||
@@ -63,10 +73,10 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~BiquadFilterNode();
|
||||
|
||||
private:
|
||||
explicit BiquadFilterNode(AudioContext* aContext);
|
||||
~BiquadFilterNode() = default;
|
||||
|
||||
BiquadFilterType mType;
|
||||
RefPtr<AudioParam> mFrequency;
|
||||
RefPtr<AudioParam> mDetune;
|
||||
@@ -78,4 +88,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -74,8 +74,30 @@ ChannelMergerNode::ChannelMergerNode(AudioContext* aContext,
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
ChannelMergerNode::~ChannelMergerNode()
|
||||
/* static */ already_AddRefed<ChannelMergerNode>
|
||||
ChannelMergerNode::Create(AudioContext& aAudioContext,
|
||||
const ChannelMergerOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mNumberOfInputs == 0 ||
|
||||
aOptions.mNumberOfInputs > WebAudioUtils::MaxChannelCount) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ChannelMergerNode> audioNode =
|
||||
new ChannelMergerNode(&aAudioContext, aOptions.mNumberOfInputs);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
@@ -86,4 +108,3 @@ ChannelMergerNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -12,15 +12,24 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct ChannelMergerOptions;
|
||||
|
||||
class ChannelMergerNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
ChannelMergerNode(AudioContext* aContext,
|
||||
uint16_t aInputCount);
|
||||
static already_AddRefed<ChannelMergerNode>
|
||||
Create(AudioContext& aAudioContext, const ChannelMergerOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
static already_AddRefed<ChannelMergerNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const ChannelMergerOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
uint16_t NumberOfInputs() const override { return mInputCount; }
|
||||
@@ -35,10 +44,11 @@ public:
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~ChannelMergerNode();
|
||||
|
||||
private:
|
||||
ChannelMergerNode(AudioContext* aContext,
|
||||
uint16_t aInputCount);
|
||||
~ChannelMergerNode() = default;
|
||||
|
||||
const uint16_t mInputCount;
|
||||
};
|
||||
|
||||
@@ -46,4 +56,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -65,8 +65,30 @@ ChannelSplitterNode::ChannelSplitterNode(AudioContext* aContext,
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
ChannelSplitterNode::~ChannelSplitterNode()
|
||||
/* static */ already_AddRefed<ChannelSplitterNode>
|
||||
ChannelSplitterNode::Create(AudioContext& aAudioContext,
|
||||
const ChannelSplitterOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mNumberOfOutputs == 0 ||
|
||||
aOptions.mNumberOfOutputs > WebAudioUtils::MaxChannelCount) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ChannelSplitterNode> audioNode =
|
||||
new ChannelSplitterNode(&aAudioContext, aOptions.mNumberOfOutputs);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
@@ -77,4 +99,3 @@ ChannelSplitterNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProt
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -12,15 +12,24 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct ChannelSplitterOptions;
|
||||
|
||||
class ChannelSplitterNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
ChannelSplitterNode(AudioContext* aContext,
|
||||
uint16_t aOutputCount);
|
||||
static already_AddRefed<ChannelSplitterNode>
|
||||
Create(AudioContext& aAudioContext, const ChannelSplitterOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
static already_AddRefed<ChannelSplitterNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const ChannelSplitterOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
uint16_t NumberOfOutputs() const override { return mOutputCount; }
|
||||
@@ -35,10 +44,11 @@ public:
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~ChannelSplitterNode();
|
||||
|
||||
private:
|
||||
ChannelSplitterNode(AudioContext* aContext,
|
||||
uint16_t aOutputCount);
|
||||
~ChannelSplitterNode() = default;
|
||||
|
||||
const uint16_t mOutputCount;
|
||||
};
|
||||
|
||||
@@ -46,4 +56,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -203,8 +203,34 @@ ConvolverNode::ConvolverNode(AudioContext* aContext)
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
ConvolverNode::~ConvolverNode()
|
||||
/* static */ already_AddRefed<ConvolverNode>
|
||||
ConvolverNode::Create(JSContext* aCx, AudioContext& aAudioContext,
|
||||
const ConvolverOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ConvolverNode> audioNode = new ConvolverNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This must be done before setting the buffer.
|
||||
audioNode->SetNormalize(!aOptions.mDisableNormalization);
|
||||
|
||||
if (aOptions.mBuffer.WasPassed()) {
|
||||
MOZ_ASSERT(aCx);
|
||||
audioNode->SetBuffer(aCx, aOptions.mBuffer.Value(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -291,4 +317,3 @@ ConvolverNode::SetNormalize(bool aNormalize)
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -12,14 +12,26 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct ConvolverOptions;
|
||||
|
||||
class ConvolverNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit ConvolverNode(AudioContext* aContext);
|
||||
static already_AddRefed<ConvolverNode>
|
||||
Create(JSContext* aCx, AudioContext& aAudioContext,
|
||||
const ConvolverOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ConvolverNode, AudioNode);
|
||||
|
||||
static already_AddRefed<ConvolverNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const ConvolverOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aGlobal.Context(), aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
AudioBuffer* GetBuffer(JSContext* aCx) const
|
||||
@@ -27,7 +39,7 @@ public:
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
void SetBuffer(JSContext* aCx, AudioBuffer* aBufferi, ErrorResult& aRv);
|
||||
void SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv);
|
||||
|
||||
bool Normalize() const
|
||||
{
|
||||
@@ -61,10 +73,10 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~ConvolverNode();
|
||||
|
||||
private:
|
||||
explicit ConvolverNode(AudioContext* aContext);
|
||||
~ConvolverNode() = default;
|
||||
|
||||
RefPtr<AudioBuffer> mBuffer;
|
||||
bool mNormalize;
|
||||
};
|
||||
@@ -74,4 +86,3 @@ private:
|
||||
} //end namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -205,8 +205,30 @@ DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay)
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
DelayNode::~DelayNode()
|
||||
/* static */ already_AddRefed<DelayNode>
|
||||
DelayNode::Create(AudioContext& aAudioContext,
|
||||
const DelayOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mMaxDelayTime <= 0. || aOptions.mMaxDelayTime >= 180.) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DelayNode> audioNode = new DelayNode(&aAudioContext,
|
||||
aOptions.mMaxDelayTime);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioNode->DelayTime()->SetValue(aOptions.mDelayTime);
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -13,15 +13,25 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct DelayOptions;
|
||||
|
||||
class DelayNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
DelayNode(AudioContext* aContext, double aMaxDelay);
|
||||
static already_AddRefed<DelayNode>
|
||||
Create(AudioContext& aAudioContext, const DelayOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DelayNode, AudioNode)
|
||||
|
||||
static already_AddRefed<DelayNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const DelayOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
AudioParam* DelayTime() const
|
||||
@@ -37,13 +47,12 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~DelayNode();
|
||||
|
||||
private:
|
||||
DelayNode(AudioContext* aContext, double aMaxDelay);
|
||||
~DelayNode() = default;
|
||||
|
||||
friend class DelayNodeEngine;
|
||||
|
||||
private:
|
||||
RefPtr<AudioParam> mDelay;
|
||||
};
|
||||
|
||||
@@ -51,4 +60,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -204,8 +204,30 @@ DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* aContext)
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
DynamicsCompressorNode::~DynamicsCompressorNode()
|
||||
/* static */ already_AddRefed<DynamicsCompressorNode>
|
||||
DynamicsCompressorNode::Create(AudioContext& aAudioContext,
|
||||
const DynamicsCompressorOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DynamicsCompressorNode> audioNode =
|
||||
new DynamicsCompressorNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioNode->Attack()->SetValue(aOptions.mAttack);
|
||||
audioNode->Knee()->SetValue(aOptions.mKnee);
|
||||
audioNode->Ratio()->SetValue(aOptions.mRatio);
|
||||
audioNode->GetRelease()->SetValue(aOptions.mRelease);
|
||||
audioNode->Threshold()->SetValue(aOptions.mThreshold);
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -13,15 +13,25 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct DynamicsCompressorOptions;
|
||||
|
||||
class DynamicsCompressorNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit DynamicsCompressorNode(AudioContext* aContext);
|
||||
static already_AddRefed<DynamicsCompressorNode>
|
||||
Create(AudioContext& aAudioContext, const DynamicsCompressorOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DynamicsCompressorNode, AudioNode)
|
||||
|
||||
static already_AddRefed<DynamicsCompressorNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const DynamicsCompressorOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
AudioParam* Threshold() const
|
||||
@@ -69,10 +79,10 @@ public:
|
||||
mReduction = aReduction;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~DynamicsCompressorNode();
|
||||
|
||||
private:
|
||||
explicit DynamicsCompressorNode(AudioContext* aContext);
|
||||
~DynamicsCompressorNode() = default;
|
||||
|
||||
RefPtr<AudioParam> mThreshold;
|
||||
RefPtr<AudioParam> mKnee;
|
||||
RefPtr<AudioParam> mRatio;
|
||||
@@ -85,4 +95,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -128,8 +128,24 @@ GainNode::GainNode(AudioContext* aContext)
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
GainNode::~GainNode()
|
||||
/* static */ already_AddRefed<GainNode>
|
||||
GainNode::Create(AudioContext& aAudioContext,
|
||||
const GainOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<GainNode> audioNode = new GainNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioNode->Gain()->SetValue(aOptions.mGain);
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -13,15 +13,25 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct GainOptions;
|
||||
|
||||
class GainNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit GainNode(AudioContext* aContext);
|
||||
static already_AddRefed<GainNode>
|
||||
Create(AudioContext& aAudioContext, const GainOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GainNode, AudioNode)
|
||||
|
||||
static already_AddRefed<GainNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const GainOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
AudioParam* Gain() const
|
||||
@@ -37,10 +47,10 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~GainNode();
|
||||
|
||||
private:
|
||||
explicit GainNode(AudioContext* aContext);
|
||||
~GainNode() = default;
|
||||
|
||||
RefPtr<AudioParam> mGain;
|
||||
};
|
||||
|
||||
@@ -48,4 +58,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -138,8 +138,8 @@ private:
|
||||
};
|
||||
|
||||
IIRFilterNode::IIRFilterNode(AudioContext* aContext,
|
||||
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedforward,
|
||||
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback)
|
||||
const Sequence<double>& aFeedforward,
|
||||
const Sequence<double>& aFeedback)
|
||||
: AudioNode(aContext,
|
||||
2,
|
||||
ChannelCountMode::Max,
|
||||
@@ -173,8 +173,46 @@ IIRFilterNode::IIRFilterNode(AudioContext* aContext,
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
IIRFilterNode::~IIRFilterNode()
|
||||
/* static */ already_AddRefed<IIRFilterNode>
|
||||
IIRFilterNode::Create(AudioContext& aAudioContext,
|
||||
const IIRFilterOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mFeedforward.Length() == 0 || aOptions.mFeedforward.Length() > 20) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mFeedback.Length() == 0 || aOptions.mFeedback.Length() > 20) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool feedforwardAllZeros = true;
|
||||
for (size_t i = 0; i < aOptions.mFeedforward.Length(); ++i) {
|
||||
if (aOptions.mFeedforward.Elements()[i] != 0.0) {
|
||||
feedforwardAllZeros = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (feedforwardAllZeros || aOptions.mFeedback.Elements()[0] == 0.0) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<IIRFilterNode> audioNode =
|
||||
new IIRFilterNode(&aAudioContext, aOptions.mFeedforward, aOptions.mFeedback);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -14,18 +14,25 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct IIRFilterOptions;
|
||||
|
||||
class IIRFilterNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit IIRFilterNode(AudioContext* aContext,
|
||||
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedforward,
|
||||
const mozilla::dom::binding_detail::AutoSequence<double>& aFeedback);
|
||||
static already_AddRefed<IIRFilterNode>
|
||||
Create(AudioContext& aAudioContext, const IIRFilterOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
static already_AddRefed<IIRFilterNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const IIRFilterOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void GetFrequencyResponse(const Float32Array& aFrequencyHz,
|
||||
const Float32Array& aMagResponse,
|
||||
@@ -39,16 +46,17 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~IIRFilterNode();
|
||||
|
||||
private:
|
||||
nsTArray<double> mFeedback;
|
||||
nsTArray<double> mFeedforward;
|
||||
IIRFilterNode(AudioContext* aContext,
|
||||
const Sequence<double>& aFeedforward,
|
||||
const Sequence<double>& aFeedback);
|
||||
~IIRFilterNode() = default;
|
||||
|
||||
nsTArray<double> mFeedback;
|
||||
nsTArray<double> mFeedforward;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -262,6 +262,9 @@ public:
|
||||
}
|
||||
void operator=(SpeexResamplerState* aResampler)
|
||||
{
|
||||
if (mResampler) {
|
||||
speex_resampler_destroy(mResampler);
|
||||
}
|
||||
mResampler = aResampler;
|
||||
}
|
||||
|
||||
@@ -400,6 +403,28 @@ MediaDecodeTask::FinishDecode()
|
||||
while ((mediaData = mAudioQueue.PopFront())) {
|
||||
RefPtr<AudioData> audioData = mediaData->As<AudioData>();
|
||||
audioData->EnsureAudioBuffer(); // could lead to a copy :(
|
||||
|
||||
if (audioData->mChannels != channelCount) {
|
||||
if (audioData->mChannels > channelCount) {
|
||||
MOZ_LOG(gMediaDecoderLog,
|
||||
LogLevel::Error,
|
||||
("MediaDecodeTask: Channel count increased from %u to %u mid-stream; "
|
||||
"this is fatal, stopping decode", channelCount, audioData->mChannels));
|
||||
ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent);
|
||||
return;
|
||||
}
|
||||
MOZ_LOG(gMediaDecoderLog,
|
||||
LogLevel::Verbose,
|
||||
("MediaDecodeTask: Channel count changed from %u to %u mid-stream, reinitializing resampler",
|
||||
channelCount, audioData->mChannels));
|
||||
channelCount = audioData->mChannels;
|
||||
if (sampleRate != destSampleRate) {
|
||||
resampler = speex_resampler_init(channelCount, sampleRate, destSampleRate,
|
||||
SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr);
|
||||
speex_resampler_skip_zeros(resampler);
|
||||
}
|
||||
}
|
||||
|
||||
AudioDataValue* bufferData = static_cast<AudioDataValue*>
|
||||
(audioData->mAudioBuffer->Data());
|
||||
|
||||
|
||||
@@ -15,13 +15,29 @@ MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* aContext)
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<MediaElementAudioSourceNode>
|
||||
MediaElementAudioSourceNode::Create(AudioContext* aContext,
|
||||
DOMMediaStream* aStream, ErrorResult& aRv)
|
||||
MediaElementAudioSourceNode::Create(AudioContext& aAudioContext,
|
||||
const MediaElementAudioSourceOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<MediaElementAudioSourceNode> node =
|
||||
new MediaElementAudioSourceNode(aContext);
|
||||
if (aAudioContext.IsOffline()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
node->Init(aStream, aRv);
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<MediaElementAudioSourceNode> node =
|
||||
new MediaElementAudioSourceNode(&aAudioContext);
|
||||
|
||||
RefPtr<DOMMediaStream> stream =
|
||||
aOptions.mMediaElement->CaptureAudio(aRv, aAudioContext.Destination()->Stream()->Graph());
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
node->Init(stream, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -11,11 +11,23 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct MediaElementAudioSourceOptions;
|
||||
|
||||
class MediaElementAudioSourceNode final : public MediaStreamAudioSourceNode
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<MediaElementAudioSourceNode>
|
||||
Create(AudioContext* aContext, DOMMediaStream* aStream, ErrorResult& aRv);
|
||||
Create(AudioContext& aAudioContext,
|
||||
const MediaElementAudioSourceOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<MediaElementAudioSourceNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const MediaElementAudioSourceOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioDestinationTrackSource :
|
||||
class AudioDestinationTrackSource final :
|
||||
public MediaStreamTrackSource
|
||||
{
|
||||
public:
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~AudioDestinationTrackSource() {}
|
||||
~AudioDestinationTrackSource() = default;
|
||||
|
||||
RefPtr<MediaStreamAudioDestinationNode> mNode;
|
||||
};
|
||||
@@ -101,8 +101,29 @@ MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* a
|
||||
mPort = outputStream->AllocateInputPort(mStream, AudioNodeStream::AUDIO_TRACK);
|
||||
}
|
||||
|
||||
MediaStreamAudioDestinationNode::~MediaStreamAudioDestinationNode()
|
||||
/* static */ already_AddRefed<MediaStreamAudioDestinationNode>
|
||||
MediaStreamAudioDestinationNode::Create(AudioContext& aAudioContext,
|
||||
const AudioNodeOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.IsOffline()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<MediaStreamAudioDestinationNode> audioNode =
|
||||
new MediaStreamAudioDestinationNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -11,14 +11,26 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct AudioNodeOptions;
|
||||
|
||||
class MediaStreamAudioDestinationNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit MediaStreamAudioDestinationNode(AudioContext* aContext);
|
||||
static already_AddRefed<MediaStreamAudioDestinationNode>
|
||||
Create(AudioContext& aAudioContext, const AudioNodeOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamAudioDestinationNode, AudioNode)
|
||||
|
||||
static already_AddRefed<MediaStreamAudioDestinationNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const AudioNodeOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
uint16_t NumberOfOutputs() const final override
|
||||
@@ -41,10 +53,10 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~MediaStreamAudioDestinationNode();
|
||||
|
||||
private:
|
||||
explicit MediaStreamAudioDestinationNode(AudioContext* aContext);
|
||||
~MediaStreamAudioDestinationNode() = default;
|
||||
|
||||
RefPtr<DOMMediaStream> mDOMStream;
|
||||
RefPtr<MediaInputPort> mPort;
|
||||
};
|
||||
|
||||
@@ -44,13 +44,23 @@ MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* aContext)
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<MediaStreamAudioSourceNode>
|
||||
MediaStreamAudioSourceNode::Create(AudioContext* aContext,
|
||||
DOMMediaStream* aStream, ErrorResult& aRv)
|
||||
MediaStreamAudioSourceNode::Create(AudioContext& aAudioContext,
|
||||
const MediaStreamAudioSourceOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<MediaStreamAudioSourceNode> node =
|
||||
new MediaStreamAudioSourceNode(aContext);
|
||||
if (aAudioContext.IsOffline()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
node->Init(aStream, aRv);
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<MediaStreamAudioSourceNode> node =
|
||||
new MediaStreamAudioSourceNode(&aAudioContext);
|
||||
|
||||
node->Init(aOptions.mMediaStream, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct MediaStreamAudioSourceOptions;
|
||||
|
||||
class MediaStreamAudioSourceNodeEngine final : public AudioNodeEngine
|
||||
{
|
||||
public:
|
||||
@@ -45,11 +48,19 @@ class MediaStreamAudioSourceNode : public AudioNode,
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<MediaStreamAudioSourceNode>
|
||||
Create(AudioContext* aContext, DOMMediaStream* aStream, ErrorResult& aRv);
|
||||
Create(AudioContext& aContext, const MediaStreamAudioSourceOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamAudioSourceNode, AudioNode)
|
||||
|
||||
static already_AddRefed<MediaStreamAudioSourceNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const MediaStreamAudioSourceOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void DestroyMediaStream() override;
|
||||
|
||||
@@ -425,8 +425,35 @@ OscillatorNode::OscillatorNode(AudioContext* aContext)
|
||||
mStream->AddMainThreadListener(this);
|
||||
}
|
||||
|
||||
OscillatorNode::~OscillatorNode()
|
||||
/* static */ already_AddRefed<OscillatorNode>
|
||||
OscillatorNode::Create(AudioContext& aAudioContext,
|
||||
const OscillatorOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<OscillatorNode> audioNode = new OscillatorNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioNode->SetType(aOptions.mType, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioNode->Frequency()->SetValue(aOptions.mFrequency);
|
||||
audioNode->Detune()->SetValue(aOptions.mDetune);
|
||||
|
||||
if (aOptions.mPeriodicWave.WasPassed()) {
|
||||
audioNode->SetPeriodicWave(aOptions.mPeriodicWave.Value());
|
||||
}
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -15,16 +15,26 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct OscillatorOptions;
|
||||
|
||||
class OscillatorNode final : public AudioNode,
|
||||
public MainThreadMediaStreamListener
|
||||
{
|
||||
public:
|
||||
explicit OscillatorNode(AudioContext* aContext);
|
||||
static already_AddRefed<OscillatorNode>
|
||||
Create(AudioContext& aAudioContext, const OscillatorOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OscillatorNode, AudioNode)
|
||||
|
||||
static already_AddRefed<OscillatorNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const OscillatorOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void DestroyMediaStream() override;
|
||||
@@ -81,14 +91,13 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~OscillatorNode();
|
||||
|
||||
private:
|
||||
explicit OscillatorNode(AudioContext* aContext);
|
||||
~OscillatorNode() = default;
|
||||
|
||||
void SendTypeToStream();
|
||||
void SendPeriodicWaveToStream();
|
||||
|
||||
private:
|
||||
OscillatorType mType;
|
||||
RefPtr<PeriodicWave> mPeriodicWave;
|
||||
RefPtr<AudioParam> mFrequency;
|
||||
@@ -100,4 +109,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -329,6 +329,38 @@ PannerNode::~PannerNode()
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<PannerNode>
|
||||
PannerNode::Create(AudioContext& aAudioContext,
|
||||
const PannerOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<PannerNode> audioNode = new PannerNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioNode->SetPanningModel(aOptions.mPanningModel);
|
||||
audioNode->SetDistanceModel(aOptions.mDistanceModel);
|
||||
audioNode->SetPosition(aOptions.mPositionX, aOptions.mPositionY,
|
||||
aOptions.mPositionZ);
|
||||
audioNode->SetOrientation(aOptions.mOrientationX, aOptions.mOrientationY,
|
||||
aOptions.mOrientationZ);
|
||||
audioNode->SetRefDistance(aOptions.mRefDistance);
|
||||
audioNode->SetMaxDistance(aOptions.mMaxDistance);
|
||||
audioNode->SetRolloffFactor(aOptions.mRolloffFactor);
|
||||
audioNode->SetConeInnerAngle(aOptions.mConeInnerAngle);
|
||||
audioNode->SetConeOuterAngle(aOptions.mConeOuterAngle);
|
||||
audioNode->SetConeOuterGain(aOptions.mConeOuterGain);
|
||||
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
void PannerNode::SetPanningModel(PanningModelType aPanningModel)
|
||||
{
|
||||
mPanningModel = aPanningModel;
|
||||
@@ -784,4 +816,3 @@ PannerNode::SendDopplerToSourcesIfNeeded()
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -19,13 +19,24 @@ namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
class AudioBufferSourceNode;
|
||||
struct PannerOptions;
|
||||
|
||||
class PannerNode final : public AudioNode,
|
||||
public SupportsWeakPtr<PannerNode>
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<PannerNode>
|
||||
Create(AudioContext& aAudioContext, const PannerOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PannerNode)
|
||||
explicit PannerNode(AudioContext* aContext);
|
||||
|
||||
static already_AddRefed<PannerNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const PannerOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
@@ -229,10 +240,10 @@ public:
|
||||
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~PannerNode();
|
||||
|
||||
private:
|
||||
explicit PannerNode(AudioContext* aContext);
|
||||
~PannerNode();
|
||||
|
||||
friend class AudioListener;
|
||||
friend class PannerNodeEngine;
|
||||
enum EngineParameters {
|
||||
@@ -292,4 +303,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,6 +43,32 @@ PeriodicWave::PeriodicWave(AudioContext* aContext,
|
||||
mCoefficients->SetData(1, nullptr, free, buffer+aLength);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<PeriodicWave>
|
||||
PeriodicWave::Constructor(const GlobalObject& aGlobal,
|
||||
AudioContext& aAudioContext,
|
||||
const PeriodicWaveOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!aOptions.mReal.WasPassed() || !aOptions.mImag.WasPassed() ||
|
||||
aOptions.mReal.Value().Length() != aOptions.mImag.Value().Length() ||
|
||||
aOptions.mReal.Value().Length() == 0) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<PeriodicWave> wave =
|
||||
new PeriodicWave(&aAudioContext, aOptions.mReal.Value().Elements(),
|
||||
aOptions.mImag.Value().Elements(),
|
||||
aOptions.mReal.Value().Length(),
|
||||
aOptions.mDisableNormalization,
|
||||
aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return wave.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
PeriodicWave::SizeOfExcludingThisIfNotShared(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
@@ -70,4 +96,3 @@ PeriodicWave::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -16,6 +16,9 @@ namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct PeriodicWaveOptions;
|
||||
|
||||
class PeriodicWave final : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
@@ -29,6 +32,10 @@ public:
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PeriodicWave)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(PeriodicWave)
|
||||
|
||||
static already_AddRefed<PeriodicWave>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const PeriodicWaveOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
AudioContext* GetParentObject() const
|
||||
{
|
||||
return mContext;
|
||||
@@ -55,7 +62,7 @@ public:
|
||||
size_t SizeOfIncludingThisIfNotShared(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
~PeriodicWave() {}
|
||||
~PeriodicWave() = default;
|
||||
|
||||
RefPtr<AudioContext> mContext;
|
||||
RefPtr<ThreadSharedFloatArrayBufferList> mCoefficients;
|
||||
|
||||
@@ -182,8 +182,24 @@ StereoPannerNode::StereoPannerNode(AudioContext* aContext)
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
StereoPannerNode::~StereoPannerNode()
|
||||
/* static */ already_AddRefed<StereoPannerNode>
|
||||
StereoPannerNode::Create(AudioContext& aAudioContext,
|
||||
const StereoPannerOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<StereoPannerNode> audioNode = new StereoPannerNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioNode->Pan()->SetValue(aOptions.mPan);
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -13,12 +13,23 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct StereoPannerOptions;
|
||||
|
||||
class StereoPannerNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
static already_AddRefed<StereoPannerNode>
|
||||
Create(AudioContext& aAudioContext, const StereoPannerOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(StereoPannerNode)
|
||||
explicit StereoPannerNode(AudioContext* aContext);
|
||||
|
||||
static already_AddRefed<StereoPannerNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const StereoPannerOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
@@ -55,10 +66,10 @@ public:
|
||||
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
protected:
|
||||
virtual ~StereoPannerNode();
|
||||
|
||||
private:
|
||||
explicit StereoPannerNode(AudioContext* aContext);
|
||||
~StereoPannerNode() = default;
|
||||
|
||||
RefPtr<AudioParam> mPan;
|
||||
};
|
||||
|
||||
@@ -66,4 +77,3 @@ private:
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(WaveShaperNode)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WaveShaperNode, AudioNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->ClearCurve();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WaveShaperNode, AudioNode)
|
||||
@@ -26,7 +25,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WaveShaperNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCurve)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WaveShaperNode)
|
||||
@@ -313,27 +311,39 @@ WaveShaperNode::WaveShaperNode(AudioContext* aContext)
|
||||
2,
|
||||
ChannelCountMode::Max,
|
||||
ChannelInterpretation::Speakers)
|
||||
, mCurve(nullptr)
|
||||
, mType(OverSampleType::None)
|
||||
{
|
||||
mozilla::HoldJSObjects(this);
|
||||
|
||||
WaveShaperNodeEngine* engine = new WaveShaperNodeEngine(this);
|
||||
mStream = AudioNodeStream::Create(aContext, engine,
|
||||
AudioNodeStream::NO_STREAM_FLAGS,
|
||||
aContext->Graph());
|
||||
}
|
||||
|
||||
WaveShaperNode::~WaveShaperNode()
|
||||
/* static */ already_AddRefed<WaveShaperNode>
|
||||
WaveShaperNode::Create(AudioContext& aAudioContext,
|
||||
const WaveShaperOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
ClearCurve();
|
||||
}
|
||||
if (aAudioContext.CheckClosed(aRv)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
WaveShaperNode::ClearCurve()
|
||||
{
|
||||
mCurve = nullptr;
|
||||
mozilla::DropJSObjects(this);
|
||||
RefPtr<WaveShaperNode> audioNode = new WaveShaperNode(&aAudioContext);
|
||||
|
||||
audioNode->Initialize(aOptions, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mCurve.WasPassed()) {
|
||||
audioNode->SetCurveInternal(aOptions.mCurve.Value(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
audioNode->SetOversample(aOptions.mOversample);
|
||||
return audioNode.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
@@ -345,45 +355,85 @@ WaveShaperNode::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
void
|
||||
WaveShaperNode::SetCurve(const Nullable<Float32Array>& aCurve, ErrorResult& aRv)
|
||||
{
|
||||
nsTArray<float> curve;
|
||||
if (!aCurve.IsNull()) {
|
||||
const Float32Array& floats = aCurve.Value();
|
||||
// Let's purge the cached value for the curve attribute.
|
||||
WaveShaperNodeBinding::ClearCachedCurveValue(this);
|
||||
|
||||
floats.ComputeLengthAndData();
|
||||
if (floats.IsShared()) {
|
||||
// Throw if the object is mapping shared memory (must opt in).
|
||||
aRv.ThrowTypeError<MSG_TYPEDARRAY_IS_SHARED>(NS_LITERAL_STRING("Argument of WaveShaperNode.setCurve"));
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t argLength = floats.Length();
|
||||
if (argLength < 2) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!curve.SetLength(argLength, fallible)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
PodCopy(curve.Elements(), floats.Data(), floats.Length());
|
||||
|
||||
mCurve = floats.Obj();
|
||||
} else {
|
||||
mCurve = nullptr;
|
||||
if (aCurve.IsNull()) {
|
||||
CleanCurveInternal();
|
||||
return;
|
||||
}
|
||||
|
||||
const Float32Array& floats = aCurve.Value();
|
||||
|
||||
floats.ComputeLengthAndData();
|
||||
if (floats.IsShared()) {
|
||||
// Throw if the object is mapping shared memory (must opt in).
|
||||
aRv.ThrowTypeError<MSG_TYPEDARRAY_IS_SHARED>(NS_LITERAL_STRING("Argument of WaveShaperNode.setCurve"));
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<float> curve;
|
||||
uint32_t argLength = floats.Length();
|
||||
if (!curve.SetLength(argLength, fallible)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
PodCopy(curve.Elements(), floats.Data(), argLength);
|
||||
SetCurveInternal(curve, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
WaveShaperNode::SetCurveInternal(const nsTArray<float>& aCurve,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (aCurve.Length() < 2) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
mCurve = aCurve;
|
||||
SendCurveToStream();
|
||||
}
|
||||
|
||||
void
|
||||
WaveShaperNode::CleanCurveInternal()
|
||||
{
|
||||
mCurve.Clear();
|
||||
SendCurveToStream();
|
||||
}
|
||||
|
||||
void
|
||||
WaveShaperNode::SendCurveToStream()
|
||||
{
|
||||
AudioNodeStream* ns = mStream;
|
||||
MOZ_ASSERT(ns, "Why don't we have a stream here?");
|
||||
ns->SetRawArrayData(curve);
|
||||
|
||||
nsTArray<float> copyCurve(mCurve);
|
||||
ns->SetRawArrayData(copyCurve);
|
||||
}
|
||||
|
||||
void
|
||||
WaveShaperNode::GetCurve(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval)
|
||||
{
|
||||
// Let's return a null value if the list is empty.
|
||||
if (mCurve.IsEmpty()) {
|
||||
aRetval.set(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mCurve.Length() >= 2);
|
||||
aRetval.set(Float32Array::Create(aCx, this, mCurve.Length(),
|
||||
mCurve.Elements()));
|
||||
}
|
||||
|
||||
void
|
||||
WaveShaperNode::SetOversample(OverSampleType aType)
|
||||
{
|
||||
mType = aType;
|
||||
SendInt32ParameterToStream(WaveShaperNodeEngine::TYPE, static_cast<int32_t>(aType));
|
||||
SendInt32ParameterToStream(WaveShaperNodeEngine::TYPE,
|
||||
static_cast<int32_t>(aType));
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -14,21 +14,28 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
struct WaveShaperOptions;
|
||||
|
||||
class WaveShaperNode final : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit WaveShaperNode(AudioContext *aContext);
|
||||
static already_AddRefed<WaveShaperNode>
|
||||
Create(AudioContext& aAudioContext, const WaveShaperOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WaveShaperNode, AudioNode)
|
||||
|
||||
static already_AddRefed<WaveShaperNode>
|
||||
Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
|
||||
const WaveShaperOptions& aOptions, ErrorResult& aRv)
|
||||
{
|
||||
return Create(aAudioContext, aOptions, aRv);
|
||||
}
|
||||
|
||||
JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void GetCurve(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval) const
|
||||
{
|
||||
aRetval.set(mCurve);
|
||||
}
|
||||
void GetCurve(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval);
|
||||
void SetCurve(const Nullable<Float32Array>& aData, ErrorResult& aRv);
|
||||
|
||||
OverSampleType Oversample() const
|
||||
@@ -54,14 +61,17 @@ public:
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WaveShaperNode();
|
||||
|
||||
private:
|
||||
void ClearCurve();
|
||||
explicit WaveShaperNode(AudioContext *aContext);
|
||||
~WaveShaperNode() = default;
|
||||
|
||||
private:
|
||||
JS::Heap<JSObject*> mCurve;
|
||||
void SetCurveInternal(const nsTArray<float>& aCurve,
|
||||
ErrorResult& aRv);
|
||||
void CleanCurveInternal();
|
||||
|
||||
void SendCurveToStream();
|
||||
|
||||
nsTArray<float> mCurve;
|
||||
OverSampleType mType;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
|
||||
function testNode() {
|
||||
var context = new AudioContext();
|
||||
var buffer = context.createBuffer(1, 2048, context.sampleRate);
|
||||
for (var i = 0; i < 2048; ++i) {
|
||||
@@ -84,7 +82,7 @@ addLoadEvent(function() {
|
||||
analyser.maxDecibels = -101;
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
|
||||
is(analyser.smoothingTimeConstant, 0.8, "Correct default value for smoothingTimeConstant");
|
||||
ok(Math.abs(analyser.smoothingTimeConstant - 0.8) < 0.001, "Correct default value for smoothingTimeConstant");
|
||||
expectException(function() {
|
||||
analyser.smoothingTimeConstant = -0.1;
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
@@ -93,6 +91,83 @@ addLoadEvent(function() {
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
analyser.smoothingTimeConstant = 0;
|
||||
analyser.smoothingTimeConstant = 1;
|
||||
}
|
||||
|
||||
function testConstructor() {
|
||||
var context = new AudioContext();
|
||||
|
||||
var analyser = new AnalyserNode(context);
|
||||
is(analyser.channelCount, 1, "analyser node has 1 input channels by default");
|
||||
is(analyser.channelCountMode, "max", "Correct channelCountMode for the analyser node");
|
||||
is(analyser.channelInterpretation, "speakers", "Correct channelCountInterpretation for the analyser node");
|
||||
|
||||
is(analyser.fftSize, 2048, "Correct default value for fftSize");
|
||||
is(analyser.frequencyBinCount, 1024, "Correct default value for frequencyBinCount");
|
||||
is(analyser.minDecibels, -100, "Correct default value for minDecibels");
|
||||
is(analyser.maxDecibels, -30, "Correct default value for maxDecibels");
|
||||
ok(Math.abs(analyser.smoothingTimeConstant - 0.8) < 0.001, "Correct default value for smoothingTimeConstant");
|
||||
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 0 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 1 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 8 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 100 }); // non-power of two
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 2049 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 4097 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 8193 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 16385 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 32769 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { fftSize: 65536 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
analyser = new AnalyserNode(context, { fftSize: 1024 });
|
||||
is(analyser.frequencyBinCount, 512, "Correct new value for frequencyBinCount");
|
||||
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { minDecibels: -30 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { minDecibels: -29 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { maxDecibels: -100 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { maxDecibels: -101 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { smoothingTimeConstant: -0.1 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
expectException(function() {
|
||||
analyser = new AnalyserNode(context, { smoothingTimeConstant: -1.1 });
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
analyser = new AnalyserNode(context, { smoothingTimeConstant: 0 });
|
||||
analyser = new AnalyserNode(context, { smoothingTimeConstant: 1 });
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
|
||||
testNode();
|
||||
testConstructor();
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
@@ -19,12 +19,8 @@ var gTest = {
|
||||
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
|
||||
}
|
||||
|
||||
var source = context.createBufferSource();
|
||||
source.buffer = buffer;
|
||||
var source = new AudioBufferSourceNode(context, {buffer: buffer, loop: true, loopStart: buffer.duration * 0.25, loopEnd: buffer.duration * 0.75 });
|
||||
source.start(0);
|
||||
source.loop = true;
|
||||
source.loopStart = buffer.duration * 0.25;
|
||||
source.loopEnd = buffer.duration * 0.75;
|
||||
return source;
|
||||
},
|
||||
createExpectedBuffers: function(context) {
|
||||
|
||||
@@ -24,7 +24,7 @@ var gTest = {
|
||||
buffers.push(buffer);
|
||||
}
|
||||
|
||||
var merger = context.createChannelMerger();
|
||||
var merger = new ChannelMergerNode(context);
|
||||
is(merger.channelCount, 1, "merger node has 1 input channels");
|
||||
is(merger.channelCountMode, "explicit", "Correct channelCountMode for the merger node");
|
||||
is(merger.channelInterpretation, "speakers", "Correct channelCountInterpretation for the merger node");
|
||||
|
||||
@@ -29,7 +29,7 @@ addLoadEvent(function() {
|
||||
|
||||
var source = context.createBufferSource();
|
||||
|
||||
var splitter = context.createChannelSplitter();
|
||||
var splitter = new ChannelSplitterNode(context);
|
||||
is(splitter.channelCount, 2, "splitter node has 2 input channels by default");
|
||||
is(splitter.channelCountMode, "max", "Correct channelCountMode for the splitter node");
|
||||
is(splitter.channelInterpretation, "speakers", "Correct channelCountInterpretation for the splitter node");
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
var context = new AudioContext();
|
||||
var conv = context.createConvolver();
|
||||
var conv = new ConvolverNode(context);
|
||||
|
||||
is(conv.channelCount, 2, "Convolver node has 2 input channels by default");
|
||||
is(conv.channelCountMode, "clamped-max", "Correct channelCountMode for the Convolver node");
|
||||
|
||||
@@ -14,6 +14,19 @@ var gTest = {
|
||||
length: 4096,
|
||||
numberOfChannels: 1,
|
||||
createGraph: function(context) {
|
||||
var delay = new DelayNode(context);
|
||||
ok(delay.delayTime, "The audioparam member must exist");
|
||||
is(delay.delayTime.value, 0, "Correct initial value");
|
||||
is(delay.delayTime.defaultValue, 0, "Correct default value");
|
||||
delay.delayTime.value = 0.5;
|
||||
is(delay.delayTime.value, 0.5, "Correct initial value");
|
||||
is(delay.delayTime.defaultValue, 0, "Correct default value");
|
||||
|
||||
delay = new DelayNode(context, { delayTime: 0.5 });
|
||||
ok(delay.delayTime, "The audioparam member must exist");
|
||||
is(delay.delayTime.value, 0.5, "Correct initial value");
|
||||
is(delay.delayTime.defaultValue, 0, "Correct default value");
|
||||
|
||||
var buffer = context.createBuffer(1, 2048, context.sampleRate);
|
||||
for (var i = 0; i < 2048; ++i) {
|
||||
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
|
||||
@@ -21,7 +34,7 @@ var gTest = {
|
||||
|
||||
var source = context.createBufferSource();
|
||||
|
||||
var delay = context.createDelay();
|
||||
delay = context.createDelay();
|
||||
|
||||
source.buffer = buffer;
|
||||
|
||||
@@ -49,6 +62,20 @@ var gTest = {
|
||||
expectException(function() {
|
||||
context.createDelay(-1);
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
|
||||
expectException(function() {
|
||||
new DelayNode(context, { maxDelayTime: 0 });
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
expectException(function() {
|
||||
new DelayNode(context, { maxDelayTime: 180 });
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
expectTypeError(function() {
|
||||
new DelayNode(context, { maxDelayTime: NaN });
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
expectException(function() {
|
||||
new DelayNode(context, { maxDelayTime: -1 });
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
|
||||
context.createDelay(1); // should not throw
|
||||
|
||||
// Delay the source stream by 2048 frames
|
||||
|
||||
@@ -20,7 +20,7 @@ addLoadEvent(function() {
|
||||
var osc = context.createOscillator();
|
||||
var sp = context.createScriptProcessor();
|
||||
|
||||
var compressor = context.createDynamicsCompressor();
|
||||
var compressor = new DynamicsCompressorNode(context);
|
||||
|
||||
osc.connect(compressor);
|
||||
osc.connect(sp);
|
||||
|
||||
@@ -14,17 +14,32 @@ var gTest = {
|
||||
length: 2048,
|
||||
numberOfChannels: 1,
|
||||
createGraph: function(context) {
|
||||
|
||||
var gain = new GainNode(context);
|
||||
ok(gain.gain, "The audioparam member must exist");
|
||||
is(gain.gain.value, 1.0, "Correct initial value");
|
||||
is(gain.gain.defaultValue, 1.0, "Correct default value");
|
||||
gain.gain.value = 0.5;
|
||||
is(gain.gain.value, 0.5, "Correct initial value");
|
||||
is(gain.gain.defaultValue, 1.0, "Correct default value");
|
||||
|
||||
gain = new GainNode(context, { gain: 0.5 });
|
||||
ok(gain.gain, "The audioparam member must exist");
|
||||
is(gain.gain.value, 0.5, "Correct initial value");
|
||||
is(gain.gain.defaultValue, 1.0, "Correct default value");
|
||||
gain.gain.value = 0.5;
|
||||
is(gain.gain.value, 0.5, "Correct initial value");
|
||||
is(gain.gain.defaultValue, 1.0, "Correct default value");
|
||||
|
||||
var buffer = context.createBuffer(1, 2048, context.sampleRate);
|
||||
for (var i = 0; i < 2048; ++i) {
|
||||
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
|
||||
}
|
||||
|
||||
var source = context.createBufferSource();
|
||||
|
||||
var gain = context.createGain();
|
||||
|
||||
source.buffer = buffer;
|
||||
|
||||
gain = context.createGain();
|
||||
source.connect(gain);
|
||||
|
||||
ok(gain.gain, "The audioparam member must exist");
|
||||
|
||||
@@ -56,7 +56,7 @@ function test() {
|
||||
}
|
||||
|
||||
audio.onloadedmetadata = function() {
|
||||
var node = context.createMediaElementSource(audio);
|
||||
var node = new MediaElementAudioSourceNode(context, { mediaElement: audio });
|
||||
var sp = context.createScriptProcessor(2048, 1);
|
||||
node.connect(sp);
|
||||
// Use a fuzz factor of 100 to account for samples that just happen to be zero
|
||||
|
||||
@@ -23,7 +23,7 @@ addLoadEvent(function() {
|
||||
var source = context.createBufferSource();
|
||||
source.buffer = buffer;
|
||||
|
||||
var dest = context.createMediaStreamDestination();
|
||||
var dest = new MediaStreamAudioDestinationNode(context);
|
||||
source.connect(dest);
|
||||
|
||||
var elem = document.getElementById('audioelem');
|
||||
|
||||
@@ -31,7 +31,7 @@ var gTest = {
|
||||
source.connect(dest);
|
||||
source.start(0);
|
||||
|
||||
var mediaStreamSource = context.createMediaStreamSource(dest.stream);
|
||||
var mediaStreamSource = new MediaStreamAudioSourceNode(context, { mediaStream: dest.stream });
|
||||
// channelCount and channelCountMode should have no effect
|
||||
mediaStreamSource.channelCount = 1;
|
||||
mediaStreamSource.channelCountMode = "explicit";
|
||||
|
||||
@@ -14,7 +14,7 @@ SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
|
||||
var context = new AudioContext();
|
||||
var osc = context.createOscillator();
|
||||
var osc = new OscillatorNode(context);
|
||||
|
||||
is(osc.channelCount, 2, "Oscillator node has 2 input channels by default");
|
||||
is(osc.channelCountMode, "max", "Correct channelCountMode for the Oscillator node");
|
||||
|
||||
@@ -25,7 +25,7 @@ addLoadEvent(function() {
|
||||
|
||||
var source = context.createBufferSource();
|
||||
|
||||
var panner = context.createPanner();
|
||||
var panner = new PannerNode(context);
|
||||
|
||||
source.buffer = buffer;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ function applyMonoToStereoPanning(c, panning) {
|
||||
|
||||
// Test the DOM interface
|
||||
var context = new OfflineAudioContext(1, 1, SR);
|
||||
var stereoPanner = context.createStereoPanner();
|
||||
var stereoPanner = new StereoPannerNode(context);
|
||||
ok(stereoPanner.pan, "The AudioParam member must exist");
|
||||
is(stereoPanner.pan.value, 0.0, "Correct initial value");
|
||||
is(stereoPanner.pan.defaultValue, 0.0, "Correct default value");
|
||||
@@ -70,8 +70,11 @@ function sine(t) {
|
||||
|
||||
// A couple mono and stereo buffers: the StereoPannerNode equation is different
|
||||
// if the input is mono or stereo
|
||||
var stereoBuffer = context.createBuffer(2, BUF_SIZE, context.sampleRate);
|
||||
var monoBuffer = context.createBuffer(1, BUF_SIZE, context.sampleRate);
|
||||
var stereoBuffer = new AudioBuffer(context, { numberOfChannels: 2,
|
||||
length: BUF_SIZE });
|
||||
var monoBuffer = new AudioBuffer(context, { numberOfChannels: 1,
|
||||
length: BUF_SIZE,
|
||||
sampleRate: context.sampleRate });
|
||||
for (var i = 0; i < BUF_SIZE; ++i) {
|
||||
monoBuffer.getChannelData(0)[i] =
|
||||
stereoBuffer.getChannelData(0)[i] =
|
||||
@@ -81,7 +84,9 @@ for (var i = 0; i < BUF_SIZE; ++i) {
|
||||
// Expected test vectors
|
||||
function expectedBufferNoop(gain) {
|
||||
gain = gain || 1.0;
|
||||
var expectedBuffer = context.createBuffer(2, BUF_SIZE, SR);
|
||||
var expectedBuffer = new AudioBuffer(context, { numberOfChannels: 2,
|
||||
length: BUF_SIZE,
|
||||
sampleRate: SR });
|
||||
for (var i = 0; i < BUF_SIZE; i++) {
|
||||
expectedBuffer.getChannelData(0)[i] = gain * sine(i);
|
||||
expectedBuffer.getChannelData(1)[i] = gain * sine(i);
|
||||
@@ -91,7 +96,9 @@ function expectedBufferNoop(gain) {
|
||||
|
||||
function expectedBufferForStereo(gain) {
|
||||
gain = gain || 1.0;
|
||||
var expectedBuffer = context.createBuffer(2, BUF_SIZE, SR);
|
||||
var expectedBuffer = new AudioBuffer(context, { numberOfChannels: 2,
|
||||
length: BUF_SIZE,
|
||||
sampleRate: SR });
|
||||
var gainPanning = gainForPanningStereoToStereo(PANNING);
|
||||
gainPanning[0] *= gain;
|
||||
gainPanning[1] *= gain;
|
||||
@@ -106,7 +113,9 @@ function expectedBufferForStereo(gain) {
|
||||
|
||||
function expectedBufferForMono(gain) {
|
||||
gain = gain || 1.0;
|
||||
var expectedBuffer = context.createBuffer(2, BUF_SIZE, SR);
|
||||
var expectedBuffer = new AudioBuffer(context, { numberOfChannels: 2,
|
||||
length: BUF_SIZE,
|
||||
sampleRate: SR });
|
||||
var gainPanning = gainForPanningMonoToStereo(PANNING);
|
||||
gainPanning[0] *= gain;
|
||||
gainPanning[1] *= gain;
|
||||
|
||||
@@ -17,7 +17,7 @@ var gTest = {
|
||||
var source = context.createBufferSource();
|
||||
source.buffer = this.buffer;
|
||||
|
||||
var shaper = context.createWaveShaper();
|
||||
var shaper = new WaveShaperNode(context);
|
||||
shaper.curve = this.curve;
|
||||
|
||||
source.connect(shaper);
|
||||
|
||||
@@ -78,6 +78,9 @@ if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']:
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' and CONFIG['CPU_ARCH'] == 'ppc':
|
||||
CXXFLAGS += ['-fpermissive']
|
||||
|
||||
if CONFIG['_MSC_VER']:
|
||||
CXXFLAGS += [
|
||||
'-wd4275', # non dll-interface class used as base for dll-interface class
|
||||
|
||||
@@ -1434,9 +1434,6 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
|
||||
if (mPluginIface->setwindow)
|
||||
(void) mPluginIface->setwindow(&mData, &mWindow);
|
||||
|
||||
#elif defined(MOZ_WIDGET_UIKIT)
|
||||
// Don't care
|
||||
#else
|
||||
# error Implement me for your OS
|
||||
#endif
|
||||
|
||||
@@ -1167,8 +1167,20 @@ public:
|
||||
};
|
||||
|
||||
void ScriptLoader::RunScriptWhenSafe(ScriptLoadRequest* aRequest) {
|
||||
auto runnable = new ScriptRequestProcessor(this, aRequest);
|
||||
nsContentUtils::AddScriptRunner(runnable);
|
||||
// Queue for processing through the normal script execution pipeline so that
|
||||
// dynamic imports are blocked during sync XHR just like async scripts.
|
||||
if (!aRequest->IsModuleRequest() ||
|
||||
!aRequest->AsModuleRequest()->IsDynamicImport()) {
|
||||
auto runnable = new ScriptRequestProcessor(this, aRequest);
|
||||
nsContentUtils::AddScriptRunner(runnable);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
MOZ_ASSERT(!aRequest->mInAsyncList);
|
||||
aRequest->mInAsyncList = true;
|
||||
mLoadedAsyncRequests.AppendElement(aRequest);
|
||||
ProcessPendingRequests();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2457,7 +2469,11 @@ ScriptLoader::ProcessPendingRequests()
|
||||
while (ReadyToExecuteScripts() && !mLoadedAsyncRequests.isEmpty()) {
|
||||
request = mLoadedAsyncRequests.StealFirst();
|
||||
if (request->IsModuleRequest()) {
|
||||
ProcessRequest(request);
|
||||
if (request->AsModuleRequest()->IsDynamicImport()) {
|
||||
ProcessDynamicImport(request->AsModuleRequest());
|
||||
} else {
|
||||
ProcessRequest(request);
|
||||
}
|
||||
} else {
|
||||
CompileOffThreadOrProcessRequest(request);
|
||||
}
|
||||
|
||||
@@ -333,78 +333,85 @@ nsMixedContentBlocker::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL) {
|
||||
nsAutoCString host;
|
||||
nsresult rv = aURL->GetHost(host);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1") ||
|
||||
host.EqualsLiteral("localhost");
|
||||
}
|
||||
|
||||
bool nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(nsIURI* aURI) {
|
||||
// The following implements:
|
||||
// https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
|
||||
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = aURI->GetScheme(scheme);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Blobs are expected to inherit their principal so we don't expect to have
|
||||
// a codebase principal with scheme 'blob' here. We can't assert that though
|
||||
// since someone could mess with a non-blob URI to give it that scheme.
|
||||
NS_WARNING_ASSERTION(!scheme.EqualsLiteral("blob"),
|
||||
"IsPotentiallyTrustworthyOrigin ignoring blob scheme");
|
||||
|
||||
// According to the specification, the user agent may choose to extend the
|
||||
// trust to other, vendor-specific URL schemes. We use this for "resource:",
|
||||
// which is technically a substituting protocol handler that is not limited to
|
||||
// local resource mapping, but in practice is never mapped remotely as this
|
||||
// would violate assumptions a lot of code makes.
|
||||
if (scheme.EqualsLiteral("https") ||
|
||||
scheme.EqualsLiteral("file") ||
|
||||
scheme.EqualsLiteral("resource") ||
|
||||
scheme.EqualsLiteral("app") ||
|
||||
scheme.EqualsLiteral("moz-extension") ||
|
||||
scheme.EqualsLiteral("wss")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsAutoCString host;
|
||||
rv = aURI->GetHost(host);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsPotentiallyTrustworthyLoopbackURL(aURI)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If a host is not considered secure according to the default algorithm, then
|
||||
// check to see if it has been whitelisted by the user. We only apply this
|
||||
// whitelist for network resources, i.e., those with scheme "http" or "ws".
|
||||
// The pref should contain a comma-separated list of hostnames.
|
||||
|
||||
if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("ws")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAdoptingCString whitelist = Preferences::GetCString("dom.securecontext.whitelist");
|
||||
if (whitelist) {
|
||||
nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsCSubstring& allowedHost = tokenizer.nextToken();
|
||||
if (host.Equals(allowedHost)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool
|
||||
nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(const nsACString& aAsciiHost) {
|
||||
return aAsciiHost.EqualsLiteral("127.0.0.1") ||
|
||||
aAsciiHost.EqualsLiteral("::1") ||
|
||||
aAsciiHost.EqualsLiteral("localhost");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool
|
||||
nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL) {
|
||||
nsAutoCString asciiHost;
|
||||
nsresult rv = aURL->GetAsciiHost(asciiHost);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
return IsPotentiallyTrustworthyLoopbackHost(asciiHost);
|
||||
}
|
||||
|
||||
bool
|
||||
nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(nsIURI* aURI) {
|
||||
// The following implements:
|
||||
// https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
|
||||
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = aURI->GetScheme(scheme);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Blobs are expected to inherit their principal so we don't expect to have
|
||||
// a codebase principal with scheme 'blob' here. We can't assert that though
|
||||
// since someone could mess with a non-blob URI to give it that scheme.
|
||||
NS_WARNING_ASSERTION(!scheme.EqualsLiteral("blob"),
|
||||
"IsPotentiallyTrustworthyOrigin ignoring blob scheme");
|
||||
|
||||
// According to the specification, the user agent may choose to extend the
|
||||
// trust to other, vendor-specific URL schemes. We use this for "resource:",
|
||||
// which is technically a substituting protocol handler that is not limited to
|
||||
// local resource mapping, but in practice is never mapped remotely as this
|
||||
// would violate assumptions a lot of code makes.
|
||||
if (scheme.EqualsLiteral("https") ||
|
||||
scheme.EqualsLiteral("file") ||
|
||||
scheme.EqualsLiteral("resource") ||
|
||||
scheme.EqualsLiteral("app") ||
|
||||
scheme.EqualsLiteral("moz-extension") ||
|
||||
scheme.EqualsLiteral("wss")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsAutoCString host;
|
||||
rv = aURI->GetHost(host);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsPotentiallyTrustworthyLoopbackURL(aURI)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If a host is not considered secure according to the default algorithm, then
|
||||
// check to see if it has been whitelisted by the user. We only apply this
|
||||
// whitelist for network resources, i.e., those with scheme "http" or "ws".
|
||||
// The pref should contain a comma-separated list of hostnames.
|
||||
|
||||
if (!scheme.EqualsLiteral("http") && !scheme.EqualsLiteral("ws")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAdoptingCString whitelist = Preferences::GetCString("dom.securecontext.whitelist");
|
||||
if (whitelist) {
|
||||
nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsCSubstring& allowedHost = tokenizer.nextToken();
|
||||
if (host.Equals(allowedHost)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This version of ShouldLoad() is non-static and called by the Content Policy
|
||||
* API and AsyncOnChannelRedirect(). See nsIContentPolicy::ShouldLoad()
|
||||
@@ -738,16 +745,16 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
||||
*aDecision = REJECT_REQUEST;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool isHttpScheme = false;
|
||||
rv = innerContentLocation->SchemeIs("http", &isHttpScheme);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Allow http requests for trusted origins (e.g. localhost or explicitly trusted contexts)
|
||||
if (isHttpScheme && IsPotentiallyTrustworthyOrigin(innerContentLocation)) {
|
||||
*aDecision = ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool isHttpScheme = false;
|
||||
rv = innerContentLocation->SchemeIs("http", &isHttpScheme);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Allow http requests for trusted origins (e.g. localhost or explicitly trusted contexts)
|
||||
if (isHttpScheme && IsPotentiallyTrustworthyOrigin(innerContentLocation)) {
|
||||
*aDecision = ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The page might have set the CSP directive 'upgrade-insecure-requests'. In such
|
||||
// a case allow the http: load to succeed with the promise that the channel will
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
|
||||
// See:
|
||||
// https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy
|
||||
static bool IsPotentiallyTrustworthyLoopbackHost(const nsACString& aAsciiHost);
|
||||
static bool IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL);
|
||||
static bool IsPotentiallyTrustworthyOrigin(nsIURI* aURI);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
||||
|
||||
if toolkit == 'windows':
|
||||
DIRS += ['windows']
|
||||
elif toolkit == 'cocoa' and CONFIG['CPU_ARCH'] != 'ppc':
|
||||
elif toolkit == 'cocoa' and [int(x) for x in CONFIG['MACOSX_DEPLOYMENT_TARGET'].split('.')] >= [10, 6]:
|
||||
DIRS += ['mac']
|
||||
elif toolkit in ('gtk2', 'gtk3'):
|
||||
DIRS += ['linux']
|
||||
|
||||
@@ -10,7 +10,15 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary AnalyserOptions : AudioNodeOptions {
|
||||
unsigned long fftSize = 2048;
|
||||
float maxDecibels = -30;
|
||||
float minDecibels = -100;
|
||||
float smoothingTimeConstant = 0.8;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional AnalyserOptions options)]
|
||||
interface AnalyserNode : AudioNode {
|
||||
|
||||
// Real-time frequency-domain data
|
||||
@@ -38,4 +46,3 @@ interface AnalyserNode : AudioNode {
|
||||
|
||||
// Mozilla extension
|
||||
AnalyserNode implements AudioNodePassThrough;
|
||||
|
||||
@@ -10,7 +10,14 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary AudioBufferOptions {
|
||||
unsigned long numberOfChannels = 1;
|
||||
required unsigned long length;
|
||||
float sampleRate;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, AudioBufferOptions options)]
|
||||
interface AudioBuffer {
|
||||
|
||||
readonly attribute float sampleRate;
|
||||
@@ -29,4 +36,3 @@ interface AudioBuffer {
|
||||
[Throws]
|
||||
void copyToChannel(Float32Array source, long channelNumber, optional unsigned long startInChannel = 0);
|
||||
};
|
||||
|
||||
@@ -10,7 +10,17 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary AudioBufferSourceOptions {
|
||||
AudioBuffer? buffer;
|
||||
float detune = 0;
|
||||
boolean loop = false;
|
||||
double loopEnd = 0;
|
||||
double loopStart = 0;
|
||||
float playbackRate = 1;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional AudioBufferSourceOptions options)]
|
||||
interface AudioBufferSourceNode : AudioNode {
|
||||
|
||||
attribute AudioBuffer? buffer;
|
||||
|
||||
@@ -21,6 +21,12 @@ enum ChannelInterpretation {
|
||||
"discrete"
|
||||
};
|
||||
|
||||
dictionary AudioNodeOptions {
|
||||
unsigned long channelCount;
|
||||
ChannelCountMode channelCountMode;
|
||||
ChannelInterpretation channelInterpretation;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
interface AudioNode : EventTarget {
|
||||
|
||||
|
||||
@@ -21,7 +21,16 @@ enum BiquadFilterType {
|
||||
"allpass"
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary BiquadFilterOptions : AudioNodeOptions {
|
||||
BiquadFilterType type = "lowpass";
|
||||
float Q = 1;
|
||||
float detune = 0;
|
||||
float frequency = 350;
|
||||
float gain = 0;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional BiquadFilterOptions options)]
|
||||
interface BiquadFilterNode : AudioNode {
|
||||
|
||||
attribute BiquadFilterType type;
|
||||
|
||||
@@ -10,8 +10,11 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
interface ChannelMergerNode : AudioNode {
|
||||
|
||||
dictionary ChannelMergerOptions : AudioNodeOptions {
|
||||
unsigned long numberOfInputs = 6;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional ChannelMergerOptions options)]
|
||||
interface ChannelMergerNode : AudioNode {
|
||||
};
|
||||
@@ -10,7 +10,12 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary ChannelSplitterOptions : AudioNodeOptions {
|
||||
unsigned long numberOfOutputs = 6;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional ChannelSplitterOptions options)]
|
||||
interface ChannelSplitterNode : AudioNode {
|
||||
|
||||
};
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary ConvolverOptions : AudioNodeOptions {
|
||||
AudioBuffer? buffer;
|
||||
boolean disableNormalization = false;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional ConvolverOptions options)]
|
||||
interface ConvolverNode : AudioNode {
|
||||
|
||||
[SetterThrows]
|
||||
|
||||
@@ -10,7 +10,13 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary DelayOptions : AudioNodeOptions {
|
||||
double maxDelayTime = 1;
|
||||
double delayTime = 0;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional DelayOptions options)]
|
||||
interface DelayNode : AudioNode {
|
||||
|
||||
readonly attribute AudioParam delayTime;
|
||||
|
||||
@@ -10,7 +10,16 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary DynamicsCompressorOptions : AudioNodeOptions {
|
||||
float attack = 0.003;
|
||||
float knee = 30;
|
||||
float ratio = 12;
|
||||
float release = 0.25;
|
||||
float threshold = -24;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional DynamicsCompressorOptions options)]
|
||||
interface DynamicsCompressorNode : AudioNode {
|
||||
|
||||
readonly attribute AudioParam threshold; // in Decibels
|
||||
|
||||
@@ -10,7 +10,12 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary GainOptions : AudioNodeOptions {
|
||||
float gain = 1.0;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, optional GainOptions options)]
|
||||
interface GainNode : AudioNode {
|
||||
|
||||
readonly attribute AudioParam gain;
|
||||
|
||||
@@ -43,6 +43,8 @@ interface HTMLFormElement : HTMLElement {
|
||||
|
||||
[Throws]
|
||||
void submit();
|
||||
[Pref="dom.forms.requestsubmit.enabled", Throws]
|
||||
void requestSubmit(optional HTMLElement? submitter = null);
|
||||
[CEReactions]
|
||||
void reset();
|
||||
boolean checkValidity();
|
||||
|
||||
@@ -9,7 +9,13 @@
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.webaudio.enabled"]
|
||||
dictionary IIRFilterOptions : AudioNodeOptions {
|
||||
required sequence<double> feedforward;
|
||||
required sequence<double> feedback;
|
||||
};
|
||||
|
||||
[Pref="dom.webaudio.enabled",
|
||||
Constructor(AudioContext context, IIRFilterOptions options)]
|
||||
interface IIRFilterNode : AudioNode {
|
||||
void getFrequencyResponse(Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse);
|
||||
};
|
||||
|
||||
Loaded 100 of 1782 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user