Skip to content

Break infinite loop for corrupted radio stream#422

Closed
ljufa wants to merge 152 commits intopdeljanov:rel-0.5from
ljufa:break_infinite_loop
Closed

Break infinite loop for corrupted radio stream#422
ljufa wants to merge 152 commits intopdeljanov:rel-0.5from
ljufa:break_infinite_loop

Conversation

@ljufa
Copy link
Copy Markdown

@ljufa ljufa commented Dec 26, 2025

In my https://github.com/ljufa/rsplayer that I am using and testing daily, I've experienced infinite loop created by some online radio streams. (I can provide some examples if needed)

I guess this fix is not generic enough to solve corupted stream problems among all streams/codecs but in my case it helped. Open for ideas to solve it in more elegant way...

pdeljanov and others added 30 commits March 10, 2024 19:36
The symphonia-format-wav crate is superseded by symphonia-format-riff.
The next_packet call now returns Result<Option<Packet>> instead of
Result<Packet>. A return value of Ok(None) indicates when the media
ends. Whereas an UnexpectedEof error now always indicates an
unexpected end to the media.

Fixes pdeljanov#246, pdeljanov#134.
* Scoring

The score function is now provided a scoped stream instead of a buffer.

* Preference Tiers

Allow format and metadata readers registered in Probe to be registered
with a preference tier.

There are three preference tiers: preferred, standard, and fallback.

Symphonia will always register its first-party implementations of
readers in the standard tier. Users that prefer to use their own
implementations over Symphonia's may register them at the preferred
tier. Likewise, if a user would prefer a first-party Symphonia
implementation over their own implementation, they may register
their implementation in the fallback tier.

This capability is particularly important when different
implementations may only partially support a format.

* Probe Options

A probe may now be instantiated with a set of options.

The maximum number of bytes probe may scan from the source is now
configurable. The maximum number of bytes any particular reader may
consume while scoring may also be limited.
Instead, an initial set of metadata may be provided to a format
reader upon creation. The reader is expected to use this metadata
as the start of its own metadata log. This allows users to access
all metadata via. the reader instead of handling metadata found
through probing seperately.
Add an explicit lifetime to the `MediaSource` to support non-static
media sources.

Fixes pdeljanov#117, pdeljanov#171.
Since the fft module now supports SIMD via. RustFFT, MDCT no longer needs
a SIMD and non-SIMD implementation.
This crate is intended to contain Symphonia first-party codec and format 
support code shared by multiple format readers and decoders.
@ljufa
Copy link
Copy Markdown
Author

ljufa commented Jan 15, 2026

Atm, I could not find any stream that fails immediatelly and consistently, it happens randomly (might be after 1h).
Anyway, current implementation without breaker is not robust enough for network streams.
I can add logging to my app and check for patterns...

pdeljanov and others added 19 commits February 7, 2026 12:06
This is to prepare for adding decode timestamps (DTS) for video support.
Signed timestamps better support gapless playback of audio and are
required for video decode timestamps.

The following new standards are set out for format readers:

- The number of frames and duration of a Track always exclude delay and
  padding frames.
- The PTS, DTS, and duration of a Packet should be as written by the
  container. If the timing information must be synthesized by the reader,
  then negative PTS should be used for delay frames. The duration should
  exclude both delay and padding frames. Encoder delay and padding to be
  trimmed should be signalled via the trim_start and trim_end fields. The
  sum of duration and trim fields equal the duration decoded. For audio
  tracks, the DTS should equal the PTS.
- Seeking to delay or padding PTS should be supported.
- Decoders are responsible for trimming the output if gapless playback is
  enabled.

Timestamps and durations are now represented by newtype wrappers of i64
and u64, respectively. The wrappers do not implement arithmetic operations
that may panic or wrap. Rather, checked arithmetic operations are provided
instead. Since i64 is not capable of representing a full unsigned 64-bit
range (as supported by many media containers), these interfaces ensure
overflows are always considered by the developer.

The following guidelines are put forward for handling timestamp overflow:

- Timestamp overflow should be lazily handled only once that timestamp is
  reached during playback or requested in a seek.
- When timestamp overflow occurs, a warning should be logged.
- A FormatReader::next_packet implementation should return Ok(None) since
  the stream has effectively ended.
- A FormatReader::seek implementation should return an out-of-range seek
  error since the stream effectively ended before the overflow.
- A MetadataReader should ignore unrepresentable timestamps (e.g., ignore
  a chapter whose start time overflows).

The guiding principle for timestamp overflow is to support playing as much
of the media as possible before bailing out. Given the range of an i64,
this should never realistically happen in real-world media streams.
PacketBuilder uses the typestate builder pattern to enforce the correct
construction of a valid packet.
It is a common type shared between format readers and decoders so it
should be promoted out of the formats module.
This commit adds validation checks to the FLAC decoder to prevent potential
panics or invalid behavior when processing malformed streams.

- Verify frame channel count matches the stream information.
- Ensure dropped bits per sample does not exceed frame bits per sample.
- Validate that the predictor order does not exceed the block size.
…eljanov#442)

Expands the fuzzing infrastructure of Symphonia and include fixes for critical bugs
found in the FLAC and ALAC decoders during initial fuzzing.

Fuzzer Changes:
* Added component-level fuzzers for AAC, ADPCM, ALAC, FLAC, MPA, PCM, and Vorbis decoders.
* Added a helper script to easily run all fuzzers.

ALAC Fixes:
* Limit the ALAC magic cookie maximum frame length to 65,536 frames to prevent malicious
  headers from causing excessive memory allocation (OOM).
* Add validation to ensure partial frames does not exceed the maximum buffer size.
* Add bounds checks to handle empty or short output buffers gracefully, preventing index out
  of bounds panics.

FLAC fixes:
* Disallow bits per sample > 32 from codec parameters as that is not supported by FLAC.
* Disallow FLAC frames with a block size > the output buffer's length.

Fixes pdeljanov#149.
Check the fuzzers as part of the CI workflow to ensure they remain buildable.

Improvement on pdeljanov#149.
This PR expands the fuzzing infrastructure for Symphonia to include
new fuzzing target for each type of supported demuxer.

Continued work on pdeljanov#149
Add a simple builder to each to make construction easier.
@ljufa
Copy link
Copy Markdown
Author

ljufa commented Mar 21, 2026

I found one url that fails and can be used to reproduce this issue http://fr2.1mix.co.uk:9000/aach

pdeljanov and others added 8 commits March 22, 2026 18:05
Reduce the binary size between about 60kB (with opt-simd) to 600kB (
without opt-simd) by boxing some lookup tables generated at runtime
with lazy_static. Despite their runtime initialization, their
uninitialized state does not appear to be located in the bss section
of the binary. Instead, their uninitialized states are present in the
data section, bloating the binary.

This change caused a minor performance regression with the built-in
(no SIMD) FFT implementation. Switched to a breadth-first FFT in an
attempt to amortize the FFT twiddle factor lookup to as few times as
possible. Ended up having a much greater performance uplift overall.

Addresses pdeljanov#456.

Co-authored-by: Jordan Bayles <jophba@chromium.org>
…deljanov#463)

Xiph lacing is sometimes used by WebM and Matroska containers to pack 
Vorbis extradata in the CodecPrivate data.

Fixes pdeljanov#460.
# Conflicts:
#	.github/workflows/ci.yml
#	symphonia-bundle-flac/Cargo.toml
#	symphonia-bundle-flac/src/demuxer.rs
#	symphonia-bundle-mp3/Cargo.toml
#	symphonia-bundle-mp3/src/demuxer.rs
#	symphonia-check/Cargo.toml
#	symphonia-codec-aac/Cargo.toml
#	symphonia-codec-aac/src/aac/mod.rs
#	symphonia-codec-aac/src/adts.rs
#	symphonia-codec-adpcm/Cargo.toml
#	symphonia-codec-alac/Cargo.toml
#	symphonia-codec-opus/Cargo.toml
#	symphonia-codec-pcm/Cargo.toml
#	symphonia-codec-vorbis/Cargo.toml
#	symphonia-codec-vorbis/src/codebook.rs
#	symphonia-codec-wavpack/Cargo.toml
#	symphonia-common/LICENSE
#	symphonia-core/Cargo.toml
#	symphonia-core/src/audio.rs
#	symphonia-core/src/codecs.rs
#	symphonia-core/src/formats.rs
#	symphonia-core/src/probe.rs
#	symphonia-format-caf/Cargo.toml
#	symphonia-format-isomp4/Cargo.toml
#	symphonia-format-isomp4/src/atoms/esds.rs
#	symphonia-format-isomp4/src/atoms/flac.rs
#	symphonia-format-isomp4/src/atoms/ilst.rs
#	symphonia-format-isomp4/src/atoms/mod.rs
#	symphonia-format-isomp4/src/atoms/opus.rs
#	symphonia-format-isomp4/src/atoms/stsd.rs
#	symphonia-format-isomp4/src/demuxer.rs
#	symphonia-format-mkv/Cargo.toml
#	symphonia-format-mkv/src/demuxer.rs
#	symphonia-format-mkv/src/ebml.rs
#	symphonia-format-ogg/Cargo.toml
#	symphonia-format-ogg/src/logical.rs
#	symphonia-format-riff/Cargo.toml
#	symphonia-format-riff/src/aiff/chunks.rs
#	symphonia-format-wav/Cargo.toml
#	symphonia-metadata/Cargo.toml
#	symphonia-play/Cargo.toml
#	symphonia-utils-xiph/Cargo.toml
#	symphonia/Cargo.toml
#	symphonia/src/lib.rs
@ljufa ljufa closed this Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants