Closed
Bug 1391482
Opened 7 years ago
Closed 7 years ago
delay conversion of output of decodeAudioData() from int16_t to float until necessary
Categories
(Core :: Web Audio, enhancement, P1)
Tracking
()
RESOLVED
FIXED
mozilla57
Tracking | Status | |
---|---|---|
firefox57 | --- | fixed |
People
(Reporter: karlt, Assigned: karlt)
References
Details
Attachments
(15 files)
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
59 bytes,
text/x-review-board-request
|
padenot
:
review+
|
Details |
Some web audio game client authors have observed significantly increased memory requirements of AudioBuffers storing Float32 data compared with native games typically using signed 16-bit. This issue is particularly problematic on mobile devices, where typically less memory is available. Initially raised at https://lists.w3.org/Archives/Public/public-audio/2013OctDec/0294.html Gecko defines MOZ_SAMPLE_TYPE_S16 on mobile platforms, in which case decode and resampling for decodeAudioData() is already performed in 16-bit arithmetic. Instead of converting to float for storage, this conversion can be performed on demand. In AudioBufferSourceNode usage (the typical case), only one block need be converted at a time. Any buffer generated by decodeAudioData() will be stored in 16-bit format until and unless JS requests it in Float32 ArrayBuffer format via getChannelData(). Other platforms decode and resample in float format. I do not intend to convert back to signed 16-bit for those platforms.
Assignee | ||
Comment 1•7 years ago
|
||
Most of the changes here are about passing a more generic type than ThreadSharedFloatArrayBufferList, one that can contain either float or 16-bit data. AudioChunk already exists for that and has the nice advantage that it keeps the length together in the same struct.
Assignee | ||
Comment 2•7 years ago
|
||
This approach was suggested in https://github.com/WebAudio/web-audio-api/issues/283#issuecomment-108012641 and previously.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Comment 18•7 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=5571cadc5dca0f17a7b0b9dffb2441d4984b7cf3 https://treeherder.mozilla.org/#/jobs?repo=try&revision=23964d26968e2b70276271ebc4e4b16881660e84
Updated•7 years ago
|
Rank: 15
Priority: -- → P1
Comment 19•7 years ago
|
||
mozreview-review |
Comment on attachment 8898567 [details] bug 1391482 use AudioChunk to generalize AudioBuffer shared channel storage https://reviewboard.mozilla.org/r/169932/#review178034
Attachment #8898567 -
Flags: review?(padenot) → review+
Comment 20•7 years ago
|
||
mozreview-review |
Comment on attachment 8898568 [details] bug 1391482 add a mechanism to pass an AudioChunk from node to engine https://reviewboard.mozilla.org/r/169934/#review178036
Attachment #8898568 -
Flags: review?(padenot) → review+
Comment 21•7 years ago
|
||
mozreview-review |
Comment on attachment 8898569 [details] bug 1391482 generalize shared channel data from AudioBuffer as AudioChunk https://reviewboard.mozilla.org/r/169936/#review178038
Attachment #8898569 -
Flags: review?(padenot) → review+
Comment 22•7 years ago
|
||
mozreview-review |
Comment on attachment 8898570 [details] bug 1391482 add a fallible SharedBuffer::Create() https://reviewboard.mozilla.org/r/169938/#review178010 ::: dom/media/SharedBuffer.h:67 (Diff revision 1) > + return InternalCreate(&malloc, aSize); > + } > + > static already_AddRefed<SharedBuffer> Create(size_t aSize) > { > + // Use moz_x_malloc() to include its diagnostic message indicating the s/moz_x_malloc/moz_xmalloc/ ::: dom/media/SharedBuffer.h:86 (Diff revision 1) > CheckedInt<size_t> size = sizeof(SharedBuffer); > size += aSize; > if (!size.isValid()) { > MOZ_CRASH(); > } > - void* m = moz_xmalloc(size.value()); > + void* m = (*aMalloc)(size.value()); I thought we had a style guide entry stating that `new` should be preferred in new code. I can't find it though. Here it does not matter too much because we're allocating bytes and not elements of a bigger size, so we can't forget the multiplication.
Attachment #8898570 -
Flags: review?(padenot) → review+
Comment 23•7 years ago
|
||
mozreview-review |
Comment on attachment 8898571 [details] bug 1391482 keep custom oscillator data buffer on graph thread only long enough to initialize the PeriodicWave https://reviewboard.mozilla.org/r/169940/#review178040
Attachment #8898571 -
Flags: review?(padenot) → review+
Comment 24•7 years ago
|
||
mozreview-review |
Comment on attachment 8898572 [details] bug 1391482 use AudioChunk to store and pass PeriodicWave data to engine https://reviewboard.mozilla.org/r/169942/#review178022 ::: commit-message-9d9c4:1 (Diff revision 1) > +bug 1391482 use AudioChunk to store and pass PeriodicWave data to engine r?padenot A bit weird to have an `AudioChunk` containing Fourier coefficients, but it makes the code cleaner indeed.
Attachment #8898572 -
Flags: review?(padenot) → review+
Comment 25•7 years ago
|
||
mozreview-review |
Comment on attachment 8898573 [details] bug 1391482 remove now-unused ThreadSharedFloatArrayBufferList SetBuffer() variant https://reviewboard.mozilla.org/r/169944/#review178042
Attachment #8898573 -
Flags: review?(padenot) → review+
Comment 26•7 years ago
|
||
mozreview-review |
Comment on attachment 8898574 [details] bug 1391482 accept int16_t sample buffers in AudioBufferSourceNode https://reviewboard.mozilla.org/r/169946/#review178030 ::: dom/media/webaudio/AudioBufferSourceNode.cpp:308 (Diff revision 1) > aOutput->ChannelFloatsForWrite(i) + *aOffsetWithinBlock; > > + if (mBuffer.mBufferFormat == AUDIO_FORMAT_FLOAT32) { > + const float* inputData = > + mBuffer.ChannelData<float>()[i] + mBufferPosition; > - WebAudioUtils::SpeexResamplerProcess(resampler, i, > + WebAudioUtils::SpeexResamplerProcess(resampler, i, This will allocate if the resampling rate is less than 0.25 and the platform uses int16 for audio output, and the buffer is originally in float32. One one hand, this whole patch set would be amazing on desktop (and we don't have to change the spec to implement it), and this would mean we allocate a bit more in some case. On the other hand, solving the memory problem can also be done with explicit in-memory compression, and would be better. This is likely to require a spec change. The allocation can also be removed by compiling two copies of the resampler, one for int, one for float.
Attachment #8898574 -
Flags: review?(padenot) → review+
Comment 27•7 years ago
|
||
mozreview-review |
Comment on attachment 8898575 [details] bug 1391482 accept int16_t sample buffers in ConvolverNode https://reviewboard.mozilla.org/r/169948/#review178044
Attachment #8898575 -
Flags: review?(padenot) → review+
Comment 28•7 years ago
|
||
mozreview-review |
Comment on attachment 8898576 [details] bug 1391482 move AudioBuffer parameter checking to constructor https://reviewboard.mozilla.org/r/169950/#review178046
Attachment #8898576 -
Flags: review?(padenot) → review+
Comment 29•7 years ago
|
||
mozreview-review |
Comment on attachment 8898577 [details] bug 1391482 add a method to create an AudioBuffer from AudioChunk data https://reviewboard.mozilla.org/r/169952/#review178048
Attachment #8898577 -
Flags: review?(padenot) → review+
Comment 30•7 years ago
|
||
mozreview-review |
Comment on attachment 8898578 [details] bug 1391482 accept int16_t-sample initialization of AudioBuffer https://reviewboard.mozilla.org/r/169954/#review178052
Attachment #8898578 -
Flags: review?(padenot) → review+
Comment 31•7 years ago
|
||
mozreview-review |
Comment on attachment 8898579 [details] bug 1391482 permit AudioChunk channel data initialization when mBuffer is not shared https://reviewboard.mozilla.org/r/169956/#review178054
Attachment #8898579 -
Flags: review?(padenot) → review+
Comment 32•7 years ago
|
||
mozreview-review |
Comment on attachment 8898580 [details] bug 1391482 generalize WebAudioDecodeJob buffer as AudioChunk https://reviewboard.mozilla.org/r/169958/#review178056
Attachment #8898580 -
Flags: review?(padenot) → review+
Comment 33•7 years ago
|
||
mozreview-review |
Comment on attachment 8898581 [details] bug 1391482 delay conversion of output of decodeAudioData() from int16_t to float until necessary https://reviewboard.mozilla.org/r/169960/#review178058
Attachment #8898581 -
Flags: review?(padenot) → review+
Assignee | ||
Comment 34•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8898570 [details] bug 1391482 add a fallible SharedBuffer::Create() https://reviewboard.mozilla.org/r/169938/#review178010 > I thought we had a style guide entry stating that `new` should be preferred in new code. I can't find it though. > > Here it does not matter too much because we're allocating bytes and not elements of a bigger size, so we can't forget the multiplication. I filed bug 1394341 on the existing mismatch between moz_xmalloc and delete. Using vector new char[] here would still mismatch with scalar delete SharedBuffer*. I'd prefer ::operator new() and ::operator delete() over new char[] and delete[] char*, because it is bytes not chars being allocated and I'd like to avoids reinterpret_cast from char*. However, I think it is easier to share code with malloc/moz_x_malloc than ::operator new(size_t) and ::operator new(size_t, const mozilla::fallible_t). malloc and free are also better understood by everybody. I'll drop this issue and follow up in bug 1394341.
Assignee | ||
Comment 35•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8898572 [details] bug 1391482 use AudioChunk to store and pass PeriodicWave data to engine https://reviewboard.mozilla.org/r/169942/#review178022 > A bit weird to have an `AudioChunk` containing Fourier coefficients, but it makes the code cleaner indeed. Yes, I guess there is the possibility of wanting to pass non-audio data buffers through this mechanism, which would be a bit odd. I don't feel so bad about Fourier coefficients because they are frequency-domain audio with the same units and types as time domain audio. (AudioChunk has neither a fundamental frequency, nor a sample rate member.) I'll drop this issue because I don't think you expecting this to be addressed, and I don't have an better ideas.
Assignee | ||
Comment 36•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8898574 [details] bug 1391482 accept int16_t sample buffers in AudioBufferSourceNode https://reviewboard.mozilla.org/r/169946/#review178030 > This will allocate if the resampling rate is less than 0.25 and the platform uses int16 for audio output, and the buffer is originally in float32. > > One one hand, this whole patch set would be amazing on desktop (and we don't have to change the spec to implement it), and this would mean we allocate a bit more in some case. > > On the other hand, solving the memory problem can also be done with explicit in-memory compression, and would be better. This is likely to require a spec change. > > The allocation can also be removed by compiling two copies of the resampler, one for int, one for float. Perhaps I'm missing your point here. Yes, there can be an allocation when the resampler works in int16. On such platforms, having an int16 source buffer removes that allocation. When the buffer is in float on int16 platforms, this allocation could be avoided by clamping inputLimit to WEBAUDIO_BLOCK_SIZE*4. I'll leave that to a separate bug, as that is no worse with these changes. If something similar were to be done on desktop, then that allocation could also happen on desktop, and so that should first be addressed. On desktop, int16 buffers should probably only be generated from encodings that are intended for int16 output, such as int16 wav. I'll drop this issue, because I don't think you are requesting anything in this bug, but please speak up if I misunderstand. Thanks for the reviews!
Comment 37•7 years ago
|
||
Yes, to be clear, everything here is r+ and can land, I was merely thinking out loud.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 50•7 years ago
|
||
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/ca07d3a43b11 use AudioChunk to generalize AudioBuffer shared channel storage r=padenot https://hg.mozilla.org/integration/autoland/rev/fea3e5cd3590 add a mechanism to pass an AudioChunk from node to engine r=padenot https://hg.mozilla.org/integration/autoland/rev/a9c7abf92455 generalize shared channel data from AudioBuffer as AudioChunk r=padenot https://hg.mozilla.org/integration/autoland/rev/527ea972cdf3 add a fallible SharedBuffer::Create() r=padenot https://hg.mozilla.org/integration/autoland/rev/fc35c12c815f keep custom oscillator data buffer on graph thread only long enough to initialize the PeriodicWave r=padenot https://hg.mozilla.org/integration/autoland/rev/7ffc044e742a use AudioChunk to store and pass PeriodicWave data to engine r=padenot https://hg.mozilla.org/integration/autoland/rev/0e12a1bdb2fa remove now-unused ThreadSharedFloatArrayBufferList SetBuffer() variant r=padenot https://hg.mozilla.org/integration/autoland/rev/ee13302be6c8 accept int16_t sample buffers in AudioBufferSourceNode r=padenot https://hg.mozilla.org/integration/autoland/rev/6feba222e86b accept int16_t sample buffers in ConvolverNode r=padenot https://hg.mozilla.org/integration/autoland/rev/b9a522cc88c9 move AudioBuffer parameter checking to constructor r=padenot https://hg.mozilla.org/integration/autoland/rev/cb6ac4267562 add a method to create an AudioBuffer from AudioChunk data r=padenot https://hg.mozilla.org/integration/autoland/rev/497e04031fc3 accept int16_t-sample initialization of AudioBuffer r=padenot https://hg.mozilla.org/integration/autoland/rev/7f096b0d1d0e permit AudioChunk channel data initialization when mBuffer is not shared r=padenot https://hg.mozilla.org/integration/autoland/rev/c02da061fc56 generalize WebAudioDecodeJob buffer as AudioChunk r=padenot https://hg.mozilla.org/integration/autoland/rev/4d4ed9b64bdb delay conversion of output of decodeAudioData() from int16_t to float until necessary r=padenot
Assignee | ||
Updated•7 years ago
|
Flags: in-testsuite-
Comment 51•7 years ago
|
||
Backed out in https://hg.mozilla.org/integration/autoland/rev/ca5dcf6d7ff1 for the rooting hazard in https://treeherder.mozilla.org/logviewer.html#?job_id=126577268&repo=autoland
Assignee | ||
Comment 52•7 years ago
|
||
The rooting analysis does not analyze the values of function pointers, and so flags a hazard because it doesn't know that it is not a hazard. I'll rearrange SharedBuffer::Create() to work around this: Function '_ZN7mozilla3dom12nsSpeechTask9SendAudioEN2JS6HandleINS2_5ValueEEES5_P9JSContext$uint32 mozilla::dom::nsSpeechTask::SendAudio(class JS::Handle<JS::Value>, class JS::Handle<JS::Value>, JSContext*)' has unrooted 'nogc' of type 'JS::AutoCheckCannotGC' live across GC call '_ZN7mozilla3domL11makeSamplesEPsj$nsSpeechTask.cpp:RefPtr<mozilla::SharedBuffer> mozilla::dom::makeSamples(int16_t*, uint32_t)' at dom/media/webspeech/synth/nsSpeechTask.cpp:303 nsSpeechTask.cpp:296: Call(59,60, nogc.AutoCheckCannotGC(0)) nsSpeechTask.cpp:298: Call(60,61, __temp_24 := tsrc.operator 111()) nsSpeechTask.cpp:298: Call(61,62, data := JS_GetInt16ArrayData(__temp_24**,isShared,nogc)) nsSpeechTask.cpp:299: Assume(62,69, isShared*, false) nsSpeechTask.cpp:303: Call(69,70, __temp_25 := makeSamples(data*,dataLen*)) [[GC call]] nsSpeechTask.cpp:303: Call(70,71, samples.operator=(__temp_25)) nsSpeechTask.cpp:303: Call(71,72, __temp_25.~SharedBuffer>()) nsSpeechTask.cpp:303: Call(72,73, nogc.~AutoCheckCannotGC()) GC Function: _ZN7mozilla3domL11makeSamplesEPsj$nsSpeechTask.cpp:RefPtr<mozilla::SharedBuffer> mozilla::dom::makeSamples(int16_t*, uint32_t) static already_AddRefed<mozilla::SharedBuffer> mozilla::SharedBuffer::Create(size_t) static already_AddRefed<mozilla::SharedBuffer> mozilla::SharedBuffer::InternalCreate(void* (*)(size_t), size_t) IndirectCall: aMalloc
Assignee | ||
Comment 53•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8898570 [details] bug 1391482 add a fallible SharedBuffer::Create() https://reviewboard.mozilla.org/r/169938/#review178010 > I filed bug 1394341 on the existing mismatch between moz_xmalloc and delete. > > Using vector new char[] here would still mismatch with scalar delete > SharedBuffer*. > > I'd prefer ::operator new() and ::operator delete() over new char[] and > delete[] char*, because it is bytes not chars being allocated and I'd like to > avoids reinterpret_cast from char*. > > However, I think it is easier to share code with malloc/moz_x_malloc than > ::operator new(size_t) and ::operator new(size_t, const mozilla::fallible_t). > > malloc and free are also better understood by everybody. > > I'll drop this issue and follow up in bug 1394341. The changes required to avoid the function pointer also make it easy to use different variants of operator new. Using the non-array operator new balances with the non-array operator delete called when the ref count drops to zero, making a class operator delete unnecessary. This is different enough that I'll request review again.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Comment 66•7 years ago
|
||
Comment on attachment 8898570 [details] bug 1391482 add a fallible SharedBuffer::Create() Sorry about the churn. https://treeherder.mozilla.org/#/jobs?repo=try&revision=5c137902a1fea43cd3aace67f4a2f6b8a9469b97
Attachment #8898570 -
Flags: review+ → review?(padenot)
Comment 67•7 years ago
|
||
mozreview-review |
Comment on attachment 8898570 [details] bug 1391482 add a fallible SharedBuffer::Create() https://reviewboard.mozilla.org/r/169938/#review178954 Thanks!
Attachment #8898570 -
Flags: review?(padenot) → review+
Comment 68•7 years ago
|
||
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/f8fc4ff76ed9 use AudioChunk to generalize AudioBuffer shared channel storage r=padenot https://hg.mozilla.org/integration/autoland/rev/043d871b9b81 add a mechanism to pass an AudioChunk from node to engine r=padenot https://hg.mozilla.org/integration/autoland/rev/4192bfee266c generalize shared channel data from AudioBuffer as AudioChunk r=padenot https://hg.mozilla.org/integration/autoland/rev/d5cc91a56399 add a fallible SharedBuffer::Create() r=padenot https://hg.mozilla.org/integration/autoland/rev/529abb028f5a keep custom oscillator data buffer on graph thread only long enough to initialize the PeriodicWave r=padenot https://hg.mozilla.org/integration/autoland/rev/1967d3942792 use AudioChunk to store and pass PeriodicWave data to engine r=padenot https://hg.mozilla.org/integration/autoland/rev/927b04969910 remove now-unused ThreadSharedFloatArrayBufferList SetBuffer() variant r=padenot https://hg.mozilla.org/integration/autoland/rev/bea3d472cab9 accept int16_t sample buffers in AudioBufferSourceNode r=padenot https://hg.mozilla.org/integration/autoland/rev/ffef0925fba1 accept int16_t sample buffers in ConvolverNode r=padenot https://hg.mozilla.org/integration/autoland/rev/8654ca00ee9f move AudioBuffer parameter checking to constructor r=padenot https://hg.mozilla.org/integration/autoland/rev/b643a1847ffd add a method to create an AudioBuffer from AudioChunk data r=padenot https://hg.mozilla.org/integration/autoland/rev/c949d19c37d0 accept int16_t-sample initialization of AudioBuffer r=padenot https://hg.mozilla.org/integration/autoland/rev/480d761a45ae permit AudioChunk channel data initialization when mBuffer is not shared r=padenot https://hg.mozilla.org/integration/autoland/rev/76419265414e generalize WebAudioDecodeJob buffer as AudioChunk r=padenot https://hg.mozilla.org/integration/autoland/rev/a3aa8b09341f delay conversion of output of decodeAudioData() from int16_t to float until necessary r=padenot
Comment 69•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/f8fc4ff76ed9 https://hg.mozilla.org/mozilla-central/rev/043d871b9b81 https://hg.mozilla.org/mozilla-central/rev/4192bfee266c https://hg.mozilla.org/mozilla-central/rev/d5cc91a56399 https://hg.mozilla.org/mozilla-central/rev/529abb028f5a https://hg.mozilla.org/mozilla-central/rev/1967d3942792 https://hg.mozilla.org/mozilla-central/rev/927b04969910 https://hg.mozilla.org/mozilla-central/rev/bea3d472cab9 https://hg.mozilla.org/mozilla-central/rev/ffef0925fba1 https://hg.mozilla.org/mozilla-central/rev/8654ca00ee9f https://hg.mozilla.org/mozilla-central/rev/b643a1847ffd https://hg.mozilla.org/mozilla-central/rev/c949d19c37d0 https://hg.mozilla.org/mozilla-central/rev/480d761a45ae https://hg.mozilla.org/mozilla-central/rev/76419265414e https://hg.mozilla.org/mozilla-central/rev/a3aa8b09341f
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla57
You need to log in
before you can comment on or make changes to this bug.
Description
•