зеркало из https://github.com/mozilla/gecko-dev.git
bug 1558123 call AudioWorkletProcessor.process() r=padenot,bzbarsky
https://heycam.github.io/webidl/#call-a-user-objects-operation may be a simpler option here, but there are some small optimizations possible with using JS::Call() directly: JS::ExposeObjectToActiveJS() is not necessary because parameters are PersistentRooted and so won't be gray. MaybeWrapObjectValue() is not necessary because parameters are already in the appropriate compartment. See also https://github.com/WebAudio/web-audio-api/issues/1967 and https://github.com/WebAudio/web-audio-api/issues/1933 Microtask support is tracked in https://bugzilla.mozilla.org/show_bug.cgi?id=1566312 Differential Revision: https://phabricator.services.mozilla.com/D34838 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
87d828f979
Коммит
35faeb0880
|
@ -63,6 +63,8 @@ class WorkletNodeEngine final : public AudioNodeEngine {
|
|||
|
||||
private:
|
||||
void SendProcessorError();
|
||||
bool CallProcess(JSContext* aCx, JS::Handle<JS::Value> aCallable,
|
||||
bool* aActiveRet);
|
||||
|
||||
void ReleaseJSResources() {
|
||||
mInputs.mPorts.clearAndFree();
|
||||
|
@ -70,6 +72,7 @@ class WorkletNodeEngine final : public AudioNodeEngine {
|
|||
mInputs.mJSArray.reset();
|
||||
mOutputs.mJSArray.reset();
|
||||
mGlobal = nullptr;
|
||||
// This is equivalent to setting [[callable process]] to false.
|
||||
mProcessor.reset();
|
||||
}
|
||||
|
||||
|
@ -231,6 +234,29 @@ static bool PrepareBufferArrays(JSContext* aCx, Span<const AudioBlock> aBlocks,
|
|||
return !(NS_WARN_IF(!PrepareArray(aCx, aPorts->mPorts, &aPorts->mJSArray)));
|
||||
}
|
||||
|
||||
// This runs JS script. MediaStreamGraph control messages, which would
|
||||
// potentially destroy the WorkletNodeEngine and its AudioNodeStream, cannot
|
||||
// be triggered by script. They are not run from an nsIThread event loop and
|
||||
// do not run until after ProcessBlocksOnPorts() has returned.
|
||||
bool WorkletNodeEngine::CallProcess(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aCallable,
|
||||
bool* aActiveRet) {
|
||||
JS::RootedVector<JS::Value> argv(aCx);
|
||||
if (NS_WARN_IF(!argv.resize(3))) {
|
||||
return false;
|
||||
}
|
||||
argv[0].setObject(*mInputs.mJSArray);
|
||||
argv[1].setObject(*mOutputs.mJSArray);
|
||||
// TODO: argv[2].setObject() for parameters.
|
||||
JS::Rooted<JS::Value> rval(aCx);
|
||||
if (!JS::Call(aCx, mProcessor, aCallable, argv, &rval)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*aActiveRet = JS::ToBoolean(rval);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ProduceSilence(Span<AudioBlock> aOutput) {
|
||||
for (AudioBlock& output : aOutput) {
|
||||
output.SetNull(WEBAUDIO_BLOCK_SIZE);
|
||||
|
@ -262,9 +288,12 @@ void WorkletNodeEngine::ProcessBlocksOnPorts(AudioNodeStream* aStream,
|
|||
AutoEntryScript aes(mGlobal, "Worklet Process");
|
||||
JSContext* cx = aes.cx();
|
||||
|
||||
if (!PrepareBufferArrays(cx, aInput, &mInputs, ArrayElementInit::None) ||
|
||||
JS::Rooted<JS::Value> process(cx);
|
||||
if (!JS_GetProperty(cx, mProcessor, "process", &process) ||
|
||||
!process.isObject() || !JS::IsCallable(&process.toObject()) ||
|
||||
!PrepareBufferArrays(cx, aInput, &mInputs, ArrayElementInit::None) ||
|
||||
!PrepareBufferArrays(cx, aOutput, &mOutputs, ArrayElementInit::Zero)) {
|
||||
// OOM. Give up.
|
||||
// process() not callable or OOM.
|
||||
SendProcessorError();
|
||||
ProduceSilence(aOutput);
|
||||
return;
|
||||
|
@ -291,7 +320,19 @@ void WorkletNodeEngine::ProcessBlocksOnPorts(AudioNodeStream* aStream,
|
|||
}
|
||||
}
|
||||
|
||||
// TODO call process() - bug 1558123
|
||||
bool active;
|
||||
if (!CallProcess(cx, process, &active)) {
|
||||
// An exception occurred.
|
||||
SendProcessorError();
|
||||
/**
|
||||
* https://webaudio.github.io/web-audio-api/#dom-audioworkletnode-onprocessorerror
|
||||
* Note that once an exception is thrown, the processor will output silence
|
||||
* throughout its lifetime.
|
||||
*/
|
||||
ProduceSilence(aOutput);
|
||||
return;
|
||||
}
|
||||
// TODO: Stay active even without inputs, if active is set.
|
||||
|
||||
// Copy output values from JS objects.
|
||||
for (size_t o = 0; o < aOutput.Length(); ++o) {
|
||||
|
|
|
@ -4,12 +4,9 @@
|
|||
[# AUDIT TASK RUNNER FINISHED: 1 out of 2 tasks were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[< [test\] 2 out of 2 assertions were failed.]
|
||||
[< [test\] 1 out of 2 assertions were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[X AudioWorklet output[128:\]: Expected 1 for all values but found 47872 unexpected values: \n\tIndex\tActual\n\t[0\]\t0\n\t[1\]\t0\n\t[2\]\t0\n\t[3\]\t0\n\t...and 47868 more errors.]
|
||||
expected: FAIL
|
||||
|
||||
[X AudioWorklet output[0:127\] does not equal [1,1.0575640201568604,1.11493718624115,1.171929121017456,1.2283508777618408,1.2840152978897095,1.3387378454208374,1.3923370838165283,1.4446351528167725,1.4954586029052734,1.5446388721466064,1.5920131206512451,1.6374238729476929,1.6807208061218262,1.7217600345611572,1.7604057788848877...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[0\]\t0.0000000000000000e+0\t1.0000000000000000e+0\t1.0000000000000000e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[1\]\t0.0000000000000000e+0\t1.0575640201568604e+0\t1.0575640201568604e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[2\]\t0.0000000000000000e+0\t1.1149371862411499e+0\t1.1149371862411499e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[3\]\t0.0000000000000000e+0\t1.1719291210174561e+0\t1.1719291210174561e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[4\]\t0.0000000000000000e+0\t1.2283508777618408e+0\t1.2283508777618408e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t...and 123 more errors.\n\tMax AbsError of 1.9998766183853149e+0 at index of 27.\n\t[27\]\t0.0000000000000000e+0\t1.9998766183853149e+0\t1.9998766183853149e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\tMax RelError of 1.0000000000000000e+0 at index of 0.\n]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче