mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-10 13:30:05 -05:00
context: add some comments
This commit is contained in:
parent
2268d1838b
commit
b0dcfa886d
1 changed files with 35 additions and 1 deletions
|
|
@ -1084,6 +1084,24 @@ static bool rates_contains(uint32_t *rates, uint32_t n_rates, uint32_t rate)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* here we evaluate the complete state of the graph.
|
||||||
|
*
|
||||||
|
* It roughly operates in 3 stages:
|
||||||
|
*
|
||||||
|
* 1. go over all drivers and collect the nodes that need to be scheduled with the
|
||||||
|
* driver. This include all nodes that have an active link with the driver or
|
||||||
|
* with a node already scheduled with the driver.
|
||||||
|
*
|
||||||
|
* 2. go over all nodes that are not assigned to a driver. The ones that require
|
||||||
|
* a driver are moved to some random active driver found in step 1.
|
||||||
|
*
|
||||||
|
* 3. go over all drivers again, collect the quantum/rate of all followers, select
|
||||||
|
* the desired final value and activate the followers and then the driver.
|
||||||
|
*
|
||||||
|
* A complete graph evaluation is performed for each change that is made to the
|
||||||
|
* graph, such as making/destroting links, adding/removing nodes, property changes such
|
||||||
|
* as quantum/rate changes or metadata changes.
|
||||||
|
*/
|
||||||
int pw_context_recalc_graph(struct pw_context *context, const char *reason)
|
int pw_context_recalc_graph(struct pw_context *context, const char *reason)
|
||||||
{
|
{
|
||||||
struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
|
struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
|
||||||
|
|
@ -1253,9 +1271,14 @@ again:
|
||||||
if (lock_rate ||
|
if (lock_rate ||
|
||||||
(!force_rate &&
|
(!force_rate &&
|
||||||
(n->info.state > PW_NODE_STATE_IDLE)))
|
(n->info.state > PW_NODE_STATE_IDLE)))
|
||||||
|
/* when someone wants us to lock the rate of this driver or
|
||||||
|
* when the driver is busy and we don't need to force a rate,
|
||||||
|
* keep the current rate */
|
||||||
target_rate = current_rate;
|
target_rate = current_rate;
|
||||||
else {
|
else {
|
||||||
/* calculate desired rate */
|
/* Here we are allowed to change the rate of the driver.
|
||||||
|
* Start with the default rate. If the desired rate is
|
||||||
|
* allowed, switch to it */
|
||||||
target_rate = def_rate;
|
target_rate = def_rate;
|
||||||
if (rate.denom != 0 && rate.num == 1) {
|
if (rate.denom != 0 && rate.num == 1) {
|
||||||
if (rates_contains(rates, n_rates, rate.denom))
|
if (rates_contains(rates, n_rates, rate.denom))
|
||||||
|
|
@ -1264,6 +1287,7 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_rate != current_rate) {
|
if (target_rate != current_rate) {
|
||||||
|
/* we doing a rate switch */
|
||||||
pw_log_info("(%s-%u) state:%s new rate:%u->%u",
|
pw_log_info("(%s-%u) state:%s new rate:%u->%u",
|
||||||
n->name, n->info.id,
|
n->name, n->info.id,
|
||||||
pw_node_state_as_string(n->info.state),
|
pw_node_state_as_string(n->info.state),
|
||||||
|
|
@ -1277,6 +1301,8 @@ again:
|
||||||
if (n->info.state >= PW_NODE_STATE_IDLE)
|
if (n->info.state >= PW_NODE_STATE_IDLE)
|
||||||
suspend_driver(context, n);
|
suspend_driver(context, n);
|
||||||
}
|
}
|
||||||
|
/* we're setting the pending rate. This will become the new
|
||||||
|
* current rate in the next iteration of the graph. */
|
||||||
n->current_rate = SPA_FRACTION(1, target_rate);
|
n->current_rate = SPA_FRACTION(1, target_rate);
|
||||||
n->current_pending = true;
|
n->current_pending = true;
|
||||||
current_rate = target_rate;
|
current_rate = target_rate;
|
||||||
|
|
@ -1285,6 +1311,7 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rate_quantum != 0 && current_rate != rate_quantum) {
|
if (rate_quantum != 0 && current_rate != rate_quantum) {
|
||||||
|
/* the quantum values are scaled with the current rate */
|
||||||
def_quantum = def_quantum * current_rate / rate_quantum;
|
def_quantum = def_quantum * current_rate / rate_quantum;
|
||||||
min_quantum = min_quantum * current_rate / rate_quantum;
|
min_quantum = min_quantum * current_rate / rate_quantum;
|
||||||
max_quantum = max_quantum * current_rate / rate_quantum;
|
max_quantum = max_quantum * current_rate / rate_quantum;
|
||||||
|
|
@ -1311,11 +1338,16 @@ again:
|
||||||
n->name, n->info.id,
|
n->name, n->info.id,
|
||||||
n->current_quantum,
|
n->current_quantum,
|
||||||
quantum);
|
quantum);
|
||||||
|
/* this is the new pending quantum */
|
||||||
n->current_quantum = quantum;
|
n->current_quantum = quantum;
|
||||||
n->current_pending = true;
|
n->current_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n->info.state < PW_NODE_STATE_RUNNING && n->current_pending) {
|
if (n->info.state < PW_NODE_STATE_RUNNING && n->current_pending) {
|
||||||
|
/* the driver node is not actually running and we have a
|
||||||
|
* panding change. Apply the change to the position now so
|
||||||
|
* that we have the right values when we change the node
|
||||||
|
* states of the driver and followers to RUNNING below */
|
||||||
n->rt.position->clock.duration = n->current_quantum;
|
n->rt.position->clock.duration = n->current_quantum;
|
||||||
n->rt.position->clock.rate = n->current_rate;
|
n->rt.position->clock.rate = n->current_rate;
|
||||||
n->current_pending = false;
|
n->current_pending = false;
|
||||||
|
|
@ -1324,6 +1356,7 @@ again:
|
||||||
pw_log_debug("%p: driving %p running:%d passive:%d quantum:%u '%s'",
|
pw_log_debug("%p: driving %p running:%d passive:%d quantum:%u '%s'",
|
||||||
context, n, running, n->passive, quantum, n->name);
|
context, n, running, n->passive, quantum, n->name);
|
||||||
|
|
||||||
|
/* first change the node states of the followers to the new target */
|
||||||
spa_list_for_each(s, &n->follower_list, follower_link) {
|
spa_list_for_each(s, &n->follower_list, follower_link) {
|
||||||
if (s == n)
|
if (s == n)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1331,6 +1364,7 @@ again:
|
||||||
context, s, s->active, s->name);
|
context, s, s->active, s->name);
|
||||||
ensure_state(s, running);
|
ensure_state(s, running);
|
||||||
}
|
}
|
||||||
|
/* now that all the followers are ready, start the driver */
|
||||||
ensure_state(n, running);
|
ensure_state(n, running);
|
||||||
}
|
}
|
||||||
impl->recalc = false;
|
impl->recalc = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue