From 197bab7931f36f7dd0743e6fd60a0e3d89d8d702 Mon Sep 17 00:00:00 2001 From: hackerman-kl Date: Sun, 26 Apr 2026 14:57:24 +0200 Subject: [PATCH] milan-avb: hook stream output to MSRP listener_observed + add max_transit_time_ns --- src/modules/module-avb/aecp-aem-state.h | 9 +++++++++ src/modules/module-avb/msrp.c | 23 +++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/modules/module-avb/aecp-aem-state.h b/src/modules/module-avb/aecp-aem-state.h index 4e7a4f235..64296beba 100644 --- a/src/modules/module-avb/aecp-aem-state.h +++ b/src/modules/module-avb/aecp-aem-state.h @@ -219,6 +219,15 @@ struct aecp_aem_stream_output_state { * MSRP_ACC_LAT_VALID flag. Range 0 .. 0x7FFFFFFF. */ uint32_t presentation_time_offset_ns; + /** IEEE 1722.1-2021 Section 7.4.39 max_transit_time, nanoseconds. The maximum + * time between an AVTP frame's transmission by this Talker and its + * consumption by any Listener. Read by stream_activate() to seed + * stream->mtt (the per-PDU presentation_time = txtime + mtt) and by + * GET_MAX_TRANSIT_TIME; updated by SET_MAX_TRANSIT_TIME. Default + * 2_000_000 (2 ms) — kept in sync with presentation_time_offset_ns + * until the two opcodes are wired up to set them independently. */ + uint64_t max_transit_time_ns; + bool stream_info_dirty; /* Milan Section 5.4.5 counter unsolicited rate-limit (see avb_interface_state). */ diff --git a/src/modules/module-avb/msrp.c b/src/modules/module-avb/msrp.c index 9941256ca..f03c99591 100644 --- a/src/modules/module-avb/msrp.c +++ b/src/modules/module-avb/msrp.c @@ -222,12 +222,27 @@ static void notify_listener(struct msrp *msrp, uint64_t now, struct attr *attr, else if (notify == AVB_MRP_NOTIFY_LEAVE) stream_out->listener_observed = false; - /* listener_observed flips flags_ex.REGISTERING in the - * GET_STREAM_INFO answer (Milan Table 5.12). Hint AECP to - * re-emit so controllers see the update. */ - if (prev != stream_out->listener_observed) + if (prev != stream_out->listener_observed) { + /* listener_observed flips flags_ex.REGISTERING in the + * GET_STREAM_INFO answer (Milan Table 5.12). Hint AECP + * to re-emit so controllers see the update. */ avb_aecp_aem_mark_stream_info_dirty(msrp->server, AVB_AEM_DESC_STREAM_OUTPUT, s->index); + + /* Milan Section 4.3.3.1: a foreign Listener registration is the + * "matching declaration" condition for starting AVTP TX. + * Activate the data plane on false→true; tear it down on + * true→false. The internal source/!source guards make the + * calls idempotent against the listener_observed bit, so a + * spurious flip won't double-start. */ + if (stream_out->listener_observed) { + if (s->source == NULL) + stream_activate(s, s->index, now); + } else { + if (s->source != NULL) + stream_deactivate(s, now); + } + } } }