-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Specify start()
and stop()
in AudioRenderCapacity
#2558
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2852,6 +2852,20 @@ Dictionary {{AudioTimestamp}} Members</h5> | |
{{AudioContext}}. In order to calculate them, the renderer collects a | ||
<a>load value</a> per <a>system-level audio callback</a>. | ||
|
||
This interface has two internal slots: | ||
|
||
<dl dfn-type=attribute dfn-for="AudioRenderCapacity"> | ||
: <dfn>[[is running]]</dfn> | ||
:: | ||
A boolean flag indicating whether the metric reporting loop is | ||
running. The initial value is <code>false</code>. | ||
|
||
: <dfn>[[update interval]]</dfn> | ||
:: | ||
A double number that represents the interval of the metric | ||
reporting loop in seconds. The initial value is 1. | ||
</dl> | ||
|
||
<h5 id="AudioRenderCapacity-attributes"> | ||
Attributes</h5> | ||
|
||
|
@@ -2874,13 +2888,47 @@ Dictionary {{AudioTimestamp}} Members</h5> | |
{{AudioRenderCapacity/update}} at {{AudioRenderCapacity}}, using | ||
{{AudioRenderCapacityEvent}}, with the given update interval in | ||
{{AudioRenderCapacityOptions}}. | ||
|
||
<div algorithm="audiorendercapacity-start"> | ||
When invoked, perform the following steps: | ||
|
||
1. Set {{[[update interval]]}} to the value of | ||
<code>options.{{AudioRenderCapacityOptions/updateInterval}} | ||
</code>. | ||
1. Set {{[[is running]]}} to <code>true</code>. | ||
1. <a href="https://html.spec.whatwg.org/multipage/media.html#queue-a-media-element-task"> | ||
Queue a media element task</a> to run the metric | ||
reporting loop. | ||
</div> | ||
|
||
: <dfn>stop()</dfn> | ||
:: | ||
Stops metric collection and analysis. It also stops dispatching | ||
{{AudioRenderCapacity/update}} events. | ||
|
||
<div algorithm="audiorendercapacity-stop"> | ||
When invoked, perform the following steps: | ||
|
||
1. Set {{[[is running]]}} to <code>false<code>. | ||
</div> | ||
</dl> | ||
|
||
<h6 id="AudioRenderCapacity-metric-reporting-loop"> | ||
Metric Reporting Loop</h6> | ||
|
||
This algorithm can be invoked by {{AudioRenderCapacity/start}} method | ||
to report the performance metric repreatedly. | ||
|
||
1. If {{[[is running]]}} is <code>false</code>, abort this algorithm. | ||
2. Create |E|, which is a new instance of {{AudioRenderCapacityEvent}}, | ||
with computed performance metrics. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might need to have something that stores the load values on the context as a private slot (e.g. a list) and perform the average/peak/underrun calculation, resets the list, fire the event, etc. so it's clear what's going on. Besides, do we want this to be clocked off of the rendering clock or the main thread? I can see things going both ways:
I'd lean towards the second solution, not firing the event when suspended. I think it's more useful: even if underrunning horribly, authors can know. But what happens if the graph is so big that not a single rendering quantum was completed in the interval? That easy to simulate, and we should make it so that it reports 100% of load or something like that (some software report > 100%, that's also well-defined what it means). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you proposal is to expand "computed performance metrics" with more detailed steps? Right? +1 on the second option. For your last question, the API doesn't really specify how the renderer can recover from such problem. So we might see different behavior depending on the implementation. Some will drop subsequent system audio callbacks until the renderer becomes responsive while others will continue to process subsequent callbacks and accumulate more buffer underruns. All that aside, 1.0 (100%) is practical. I am not sure what users can do with a number beyond 1.0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, generally I was asking for more details on the specifics of the computation, so it's clear what one should implement. I don't know what we should do for the case "above 100%", so maybe explicitly capping to 100% and saying that at 100% it means it's over capacity (regardless of the actual rendering time), like you say. In Firefox, we keep plowing through as fast as we can, there are audio glitches, but otherwise it proceeds normally, |
||
3. <a spec="dom" lt="fire an event">Fire an event</a> named | ||
{{AudioRenderCapacity/update}} using |E|. | ||
4. <a href="https://html.spec.whatwg.org/multipage/media.html#queue-a-media-element-task"> | ||
Queue a media element task</a> to run the metric reporting loop | ||
with the delay of {{[[update interval]]}}. | ||
|
||
|
||
<h4 dictionary lt="audiorenderCapacityoptions" id="AudioRenderCapacityOptions"> | ||
{{AudioRenderCapacityOptions}}</h4> | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if
is running
is only checked here it could result in multiple Metric Reporting Loops running in parallel.I think the following could cause two parallel loops.
Since
stop()
only sets theis running
flag tofalse
but doesn't stop the loop both loops started by callingstart()
could be kept alive. It seems to be possible that by the time the first loop checksis running
it's true again as a result of callingstart()
for the second time.