Skip to content

Centralize DAX RX stream ownership/refcounting in PanadapterStream (multi-slice DAX/TCI hardening) #3305

Description

@jensenpat

Problem

The radio-side dax_rx stream map lives in a single PanadapterStream (one per radio), but three independent consumers each hand-roll their own ownership bookkeeping on top of it and coordinate by peeking at each other's state:

Consumer Hand-rolled state
DAX virtual-audio bridge (MainWindow) m_daxSliceLastCh (sliceId→channel), per-slice daxChannelChanged wiring
TCI (TciServer) m_tciDaxStreamIds (channel→id), m_tciDaxBorrowedChannels, m_tciDaxSlices
RADE (MainWindow) m_radeDaxStreamId

PanadapterStream itself only exposes registerDaxStream() / unregisterDaxStream() / daxStreamIdForChannel() — no notion of who holds a channel or how many holders there are. So each consumer reimplements "is anyone else using this channel?" by reaching into the others:

This works but is fragile and O(consumers²): every new consumer has to learn about every existing one, and any missed cross-check silently tears out a stream another consumer needs (the #3270 failure mode, which #2895/#3282 patched from two directions).

Proposed direction

Replace the per-consumer ownership maps with centralized refcounting in PanadapterStream:

// rough shape
quint32 acquireDaxChannel(int channel, DaxConsumer who);  // creates stream if refcount 0→1, else reuses
void    releaseDaxChannel(int channel, DaxConsumer who);  // sends `stream remove` only when refcount 1→0
  • PanadapterStream owns the channel→(streamId, refcount, holders) table and is the single place that emits stream create / stream remove.
  • Consumers call acquire/release and stop tracking stream IDs and each other entirely.
  • Removal happens only when the last holder releases — no consumer can stomp another.
  • Keeps the slice set <id> dax=<ch> client-registration re-assert (Broken TCI audio tested on Win11 #1439) as a separate concern.

Context / predecessors (contained fixes already landed/in-flight)

These are the contained, per-path predecessors; this issue tracks the structural consolidation we deferred to a later release.

Notes

  • Architecture change (new ownership model + signal/ownership routing) → maintainer design call before implementation.
  • Should preserve: slice 0 RX flow, the Broken TCI audio tested on Win11 #1439 re-assert, borrowed-stream semantics (no double stream create → double-speed audio), and clean teardown on disconnect/stopDax/releaseDaxForTci.

Metadata

Metadata

Assignees

No one assigned

    Labels

    VITA-49VITA-49 UDP streaming: FFT, waterfall, audio, metersaudioAudio engine and streamingenhancementImprovement to existing featuremaintainer-reviewRequires maintainer review before any action is takenpriority: lowLow priorityprotocolSmartSDR protocolrefactorCode cleanup, restructuring, or consolidation — no user-visible behavior change

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions