Skip to content

Stopped zero-length ISO packets stranding audio frame slots - #271

Merged
fdesbiens merged 2 commits into
eclipse-threadx:devfrom
Nictrla:fix/device-audio-skip-zero-length-iso-out-frames
Oct 1, 2026
Merged

fdesbiens merged 2 commits into
eclipse-threadx:devfrom
Nictrla:fix/device-audio-skip-zero-length-iso-out-frames

Conversation

@Nictrla

@Nictrla Nictrla commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

A zero-length isochronous OUT transfer (actual_length == 0) carries no audio data, but the read thread still recorded it as a frame: it wrote frame_length = 0 into the slot at transfer_pos, advanced transfer_pos and fired the frame_done callback.

Because the frame FIFO uses frame_length == 0 as the sentinel for an empty slot, this made the slot indistinguishable from a free one. The consumer then read at access_pos, saw frame_length == 0, reported it as an underflow (UX_BUFFER_OVERFLOW) and did not advance access_pos. As a result transfer_pos moved forward while access_pos stayed put, permanently desyncing the producer/consumer positions.

Skip zero-length packets entirely: leave transfer_pos in place, do not fire the callback, and re-issue the transfer at the same slot. This preserves the "frame_length == 0 means empty slot" invariant and keeps the transfer and access positions in sync.

@Nictrla
Nictrla force-pushed the fix/device-audio-skip-zero-length-iso-out-frames branch from 4d2519b to 8e2d74b Compare July 27, 2026 10:21
@fdesbiens
fdesbiens changed the base branch from master to dev July 28, 2026 15:04
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Nictrla.

Thank you for this contribution!

@rahmanih: Can you review, please?

@fdesbiens
fdesbiens requested review from fdesbiens and rahmanih July 28, 2026 15:05
@fdesbiens fdesbiens moved this to In review in ThreadX Roadmap Jul 28, 2026

@rahmanih rahmanih left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actual_length = transfer -> ux_slave_transfer_request_actual_length;

fix to be applied here too.

@Nictrla

Nictrla commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

actual_length = transfer -> ux_slave_transfer_request_actual_length;

fix to be applied here too.

What would be the appropriate way to fix it there?
return(UX_STATE_WAIT); in case actual_length is equal 0? Should this check done before stream -> ux_device_class_audio_stream_task_state and stream -> ux_device_class_audio_stream_task_status are set?

Nictrla and others added 2 commits September 30, 2026 15:32
A zero-length isochronous OUT transfer (actual_length == 0) carries no
audio data, but the read thread still recorded it as a frame: it wrote
frame_length = 0 into the slot at transfer_pos, advanced transfer_pos
and fired the frame_done callback.

Because the frame FIFO uses frame_length == 0 as the sentinel for an
empty slot, this made the slot indistinguishable from a free one.
The consumer then read at access_pos, saw frame_length == 0, reported
it as an underflow (UX_BUFFER_OVERFLOW) and did not advance access_pos.
As a result transfer_pos moved forward while access_pos stayed put,
permanently desyncing the producer/consumer positions.

Skip zero-length packets entirely: leave transfer_pos in place,
do not fire the callback, and re-issue the transfer at the same slot.
This preserves the "frame_length == 0 means empty slot" invariant
and keeps the transfer and access positions in sync.
House style puts the brace on its own line and comments the reason, and the
change arrived with neither, plus a line of trailing whitespace.

The comment records why the skip matters rather than what it does: a zero length
frame is what marks a slot free, so logging one leaves a slot the reader never
drains while the transfer position advances past it.

No behaviour change.

Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
@fdesbiens
fdesbiens force-pushed the fix/device-audio-skip-zero-length-iso-out-frames branch from 8e2d74b to 72b6b39 Compare September 30, 2026 19:33
@fdesbiens

Copy link
Copy Markdown
Contributor

Thanks — this is a real fix and I have kept it. I pushed a second commit to your branch rather than asking you to redo it, and rebased onto current dev.

What changed is presentation only, no behaviour: the brace moved to its own line, a line of trailing whitespace went, and the reason is now recorded in a comment. The reason is worth stating because it is not obvious from the code: a frame length of zero is exactly what marks a slot free, so logging a zero-length packet leaves a slot the reader never drains while the transfer position advances past it. That is the bug, rather than merely a wasted slot.

The rebase was needed for a reason unrelated to your change. The branch predated #274, which removed a byte order mark from ux_test.c, so building it produced 47 errors in a file you never touched. On current dev it builds clean and 430/430 pass.

Two things worth flagging, neither blocking.

The skip also bypasses the frame_done callback for zero-length packets. That looks right to me, since a zero-length packet is not a frame, but it is a visible change for an application that counted callbacks rather than bytes.

There is no regression test. The device audio read thread needs the simulated device stack to drive, so this is not a quick one to add, and I would rather say so than let the absence pass unremarked.

@fdesbiens fdesbiens changed the title fix: skip zero-length ISO OUT packets in audio read thread Stopped zero-length ISO packets stranding audio frame slots Oct 1, 2026
@fdesbiens
fdesbiens merged commit 419efa1 into eclipse-threadx:dev Oct 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants