From b0dcfa886d7ce5465f8f5837b957a34f3016ba75 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 14 Apr 2022 10:16:20 +0200 Subject: [PATCH] context: add some comments --- src/pipewire/context.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 200c7f6b6..e8279b00e 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -1084,6 +1084,24 @@ static bool rates_contains(uint32_t *rates, uint32_t n_rates, uint32_t rate) 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) { struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this); @@ -1253,9 +1271,14 @@ again: if (lock_rate || (!force_rate && (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; 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; if (rate.denom != 0 && rate.num == 1) { if (rates_contains(rates, n_rates, rate.denom)) @@ -1264,6 +1287,7 @@ again: } if (target_rate != current_rate) { + /* we doing a rate switch */ pw_log_info("(%s-%u) state:%s new rate:%u->%u", n->name, n->info.id, pw_node_state_as_string(n->info.state), @@ -1277,6 +1301,8 @@ again: if (n->info.state >= PW_NODE_STATE_IDLE) 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_pending = true; current_rate = target_rate; @@ -1285,6 +1311,7 @@ again: } 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; min_quantum = min_quantum * current_rate / rate_quantum; max_quantum = max_quantum * current_rate / rate_quantum; @@ -1311,11 +1338,16 @@ again: n->name, n->info.id, n->current_quantum, quantum); + /* this is the new pending quantum */ n->current_quantum = quantum; n->current_pending = true; } 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.rate = n->current_rate; n->current_pending = false; @@ -1324,6 +1356,7 @@ again: pw_log_debug("%p: driving %p running:%d passive:%d quantum:%u '%s'", 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) { if (s == n) continue; @@ -1331,6 +1364,7 @@ again: context, s, s->active, s->name); ensure_state(s, running); } + /* now that all the followers are ready, start the driver */ ensure_state(n, running); } impl->recalc = false;