Skip to content

Commit

Permalink
Allow non-static sources
Browse files Browse the repository at this point in the history
  • Loading branch information
a1phyr committed Mar 25, 2024
1 parent 7e73f35 commit 316dbb8
Show file tree
Hide file tree
Showing 22 changed files with 148 additions and 133 deletions.
20 changes: 10 additions & 10 deletions symphonia-bundle-flac/src/demuxer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ const FLAC_FORMAT_INFO: FormatInfo = FormatInfo {
};

/// Free Lossless Audio Codec (FLAC) native frame reader.
pub struct FlacReader {
reader: MediaSourceStream,
pub struct FlacReader<'s> {
reader: MediaSourceStream<'s>,
metadata: MetadataLog,
tracks: Vec<Track>,
cues: Vec<Cue>,
Expand All @@ -45,9 +45,9 @@ pub struct FlacReader {
parser: PacketParser,
}

impl FlacReader {
impl<'s> FlacReader<'s> {
/// Reads all the metadata blocks, returning a fully populated `FlacReader`.
fn init_with_metadata(source: MediaSourceStream, options: FormatOptions) -> Result<Self> {
fn init_with_metadata(source: MediaSourceStream<'s>, options: FormatOptions) -> Result<Self> {
let mut metadata_builder = MetadataBuilder::new();

let mut reader = source;
Expand Down Expand Up @@ -140,18 +140,18 @@ impl FlacReader {
}
}

impl Probeable for FlacReader {
impl Probeable for FlacReader<'_> {
fn probe_descriptor() -> &'static [ProbeDescriptor] {
&[support_format!(FLAC_FORMAT_INFO, &["flac"], &["audio/flac"], &[b"fLaC"])]
&[support_format!(FlacReader<'_>, FLAC_FORMAT_INFO, &["flac"], &["audio/flac"], &[b"fLaC"])]
}

fn score(_src: ScopedStream<&mut MediaSourceStream>) -> Result<Score> {
fn score(_src: ScopedStream<&mut MediaSourceStream<'_>>) -> Result<Score> {
Ok(Score::Supported(255))
}
}

impl FormatReader for FlacReader {
fn try_new(mut source: MediaSourceStream, options: FormatOptions) -> Result<Self> {
impl<'s> FormatReader<'s> for FlacReader<'s> {
fn try_new(mut source: MediaSourceStream<'s>, options: FormatOptions) -> Result<Self> {
// Read the first 4 bytes of the stream. Ideally this will be the FLAC stream marker.
let marker = source.read_quad_bytes()?;

Expand Down Expand Up @@ -337,7 +337,7 @@ impl FormatReader for FlacReader {
Ok(SeekedTo { track_id: 0, actual_ts: packet.ts, required_ts: ts })
}

fn into_inner(self: Box<Self>) -> MediaSourceStream {
fn into_inner(self: Box<Self>) -> MediaSourceStream<'s> {
self.reader
}
}
Expand Down
25 changes: 14 additions & 11 deletions symphonia-bundle-mp3/src/demuxer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const MP3_FORMAT_INFO: FormatInfo = FormatInfo {
/// MPEG1 and MPEG2 audio elementary stream reader.
///
/// `MpaReader` implements a demuxer for the MPEG1 and MPEG2 audio elementary stream.
pub struct MpaReader {
reader: MediaSourceStream,
pub struct MpaReader<'s> {
reader: MediaSourceStream<'s>,
tracks: Vec<Track>,
cues: Vec<Cue>,
metadata: MetadataLog,
Expand All @@ -53,11 +53,12 @@ pub struct MpaReader {
next_packet_ts: u64,
}

impl Probeable for MpaReader {
impl Probeable for MpaReader<'_> {
fn probe_descriptor() -> &'static [ProbeDescriptor] {
&[
// Layer 1
support_format!(
MpaReader<'_>,
MP1_FORMAT_INFO,
&["mp1"],
&["audio/mpeg", "audio/mp1"],
Expand All @@ -72,6 +73,7 @@ impl Probeable for MpaReader {
),
// Layer 2
support_format!(
MpaReader<'_>,
MP2_FORMAT_INFO,
&["mp2"],
&["audio/mpeg", "audio/mp2"],
Expand All @@ -86,6 +88,7 @@ impl Probeable for MpaReader {
),
// Layer 3
support_format!(
MpaReader<'_>,
MP3_FORMAT_INFO,
&["mp3"],
&["audio/mpeg", "audio/mp3"],
Expand All @@ -101,7 +104,7 @@ impl Probeable for MpaReader {
]
}

fn score(mut src: ScopedStream<&mut MediaSourceStream>) -> Result<Score> {
fn score(mut src: ScopedStream<&mut MediaSourceStream<'_>>) -> Result<Score> {
// Read the sync word for the first (assumed) MPEG frame and try to parse it into a header.
let sync1 = header::read_frame_header_word_no_sync(&mut src)?;
let hdr1 = header::parse_frame_header(sync1)?;
Expand Down Expand Up @@ -132,8 +135,8 @@ impl Probeable for MpaReader {
}
}

impl FormatReader for MpaReader {
fn try_new(mut source: MediaSourceStream, options: FormatOptions) -> Result<Self> {
impl<'s> FormatReader<'s> for MpaReader<'s> {
fn try_new(mut source: MediaSourceStream<'s>, options: FormatOptions) -> Result<Self> {
// Try to read the first MPEG frame.
let (header, packet) = read_mpeg_frame_strict(&mut source)?;

Expand Down Expand Up @@ -467,12 +470,12 @@ impl FormatReader for MpaReader {
Ok(SeekedTo { track_id: 0, required_ts: required_ts - delay, actual_ts })
}

fn into_inner(self: Box<Self>) -> MediaSourceStream {
fn into_inner(self: Box<Self>) -> MediaSourceStream<'s> {
self.reader
}
}

impl MpaReader {
impl MpaReader<'_> {
/// Seeks the media source stream to a byte position roughly where the packet with the required
/// timestamp should be located.
fn preseek_coarse(&mut self, required_ts: u64, duration: Option<u64>) -> Result<()> {
Expand Down Expand Up @@ -542,7 +545,7 @@ impl MpaReader {
}

/// Reads a MPEG frame and returns the header and buffer.
fn read_mpeg_frame(reader: &mut MediaSourceStream) -> Result<(FrameHeader, Vec<u8>)> {
fn read_mpeg_frame(reader: &mut MediaSourceStream<'_>) -> Result<(FrameHeader, Vec<u8>)> {
let (header, header_word) = loop {
// Sync to the next frame header.
let sync = header::sync_frame(reader)?;
Expand All @@ -567,7 +570,7 @@ fn read_mpeg_frame(reader: &mut MediaSourceStream) -> Result<(FrameHeader, Vec<u
}

/// Reads a MPEG frame and checks if the next frame begins after the packet.
fn read_mpeg_frame_strict(reader: &mut MediaSourceStream) -> Result<(FrameHeader, Vec<u8>)> {
fn read_mpeg_frame_strict(reader: &mut MediaSourceStream<'_>) -> Result<(FrameHeader, Vec<u8>)> {
loop {
// Read the next MPEG frame.
let (header, packet) = read_mpeg_frame(reader)?;
Expand Down Expand Up @@ -640,7 +643,7 @@ fn read_main_data_begin<B: ReadBytes>(reader: &mut B, header: &FrameHeader) -> R
}

/// Estimates the total number of MPEG frames in the media source stream.
fn estimate_num_mpeg_frames(reader: &mut MediaSourceStream) -> Option<u64> {
fn estimate_num_mpeg_frames(reader: &mut MediaSourceStream<'_>) -> Option<u64> {
const MAX_FRAMES: u32 = 16;
const MAX_LEN: usize = 16 * 1024;

Expand Down
2 changes: 1 addition & 1 deletion symphonia-bundle-mp3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ pub use demuxer::MpaReader;
pub type Mp3Decoder = MpaDecoder;

#[deprecated = "use `symphonia_bundle_mp3::MpaReader` instead"]
pub type Mp3Reader = MpaReader;
pub type Mp3Reader<'s> = MpaReader<'s>;
7 changes: 5 additions & 2 deletions symphonia-check/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,16 @@ struct FlushStats {
}

struct DecoderInstance {
format: Box<dyn FormatReader>,
format: Box<dyn FormatReader<'static>>,
decoder: Box<dyn Decoder>,
track_id: u32,
}

impl DecoderInstance {
fn try_open(mss: MediaSourceStream, fmt_opts: FormatOptions) -> Result<DecoderInstance> {
fn try_open(
mss: MediaSourceStream<'static>,
fmt_opts: FormatOptions,
) -> Result<DecoderInstance> {
// Use the default options for metadata and format readers, and the decoder.
let meta_opts: MetadataOptions = Default::default();
let dec_opts: DecoderOptions = Default::default();
Expand Down
17 changes: 9 additions & 8 deletions symphonia-codec-aac/src/adts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,19 @@ const ADTS_FORMAT_INFO: FormatInfo = FormatInfo {
/// Audio Data Transport Stream (ADTS) format reader.
///
/// `AdtsReader` implements a demuxer for ADTS (AAC native frames).
pub struct AdtsReader {
reader: MediaSourceStream,
pub struct AdtsReader<'s> {
reader: MediaSourceStream<'s>,
tracks: Vec<Track>,
cues: Vec<Cue>,
metadata: MetadataLog,
first_frame_pos: u64,
next_packet_ts: u64,
}

impl Probeable for AdtsReader {
impl Probeable for AdtsReader<'_> {
fn probe_descriptor() -> &'static [ProbeDescriptor] {
&[support_format!(
AdtsReader<'_>,
ADTS_FORMAT_INFO,
&["aac"],
&["audio/aac"],
Expand All @@ -57,7 +58,7 @@ impl Probeable for AdtsReader {
)]
}

fn score(mut src: ScopedStream<&mut MediaSourceStream>) -> Result<Score> {
fn score(mut src: ScopedStream<&mut MediaSourceStream<'_>>) -> Result<Score> {
// Read the first (assumed) ADTS header.
let hdr1 = AdtsHeader::read_no_resync(&mut src)?;

Expand Down Expand Up @@ -211,8 +212,8 @@ impl AdtsHeader {
}
}

impl FormatReader for AdtsReader {
fn try_new(mut source: MediaSourceStream, options: FormatOptions) -> Result<Self> {
impl<'s> FormatReader<'s> for AdtsReader<'s> {
fn try_new(mut source: MediaSourceStream<'s>, options: FormatOptions) -> Result<Self> {
let header = AdtsHeader::read(&mut source)?;

// Rewind back to the start of the frame.
Expand Down Expand Up @@ -369,12 +370,12 @@ impl FormatReader for AdtsReader {
Ok(SeekedTo { track_id: 0, required_ts, actual_ts: self.next_packet_ts })
}

fn into_inner(self: Box<Self>) -> MediaSourceStream {
fn into_inner(self: Box<Self>) -> MediaSourceStream<'s> {
self.reader
}
}

fn approximate_frame_count(mut source: &mut MediaSourceStream) -> Result<Option<u64>> {
fn approximate_frame_count(mut source: &mut MediaSourceStream<'_>) -> Result<Option<u64>> {
let original_pos = source.pos();
let total_len = match source.byte_len() {
Some(len) => len - original_pos,
Expand Down
6 changes: 3 additions & 3 deletions symphonia-core/src/formats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,11 @@ impl Track {
/// `FormatReader` provides an Iterator-like interface over packets for easy consumption and
/// filtering. Seeking will invalidate the state of any `Decoder` processing packets from the
/// `FormatReader` and should be reset after a successful seek operation.
pub trait FormatReader: Send + Sync {
pub trait FormatReader<'s>: Send + Sync {
/// Attempt to instantiate a `FormatReader` using the provided `FormatOptions` and
/// `MediaSourceStream`. The reader will probe the container to verify format support, determine
/// the number of tracks, and read any initial metadata.
fn try_new(source: MediaSourceStream, options: FormatOptions) -> Result<Self>
fn try_new(source: MediaSourceStream<'s>, options: FormatOptions) -> Result<Self>
where
Self: Sized;

Expand Down Expand Up @@ -280,7 +280,7 @@ pub trait FormatReader: Send + Sync {
fn next_packet(&mut self) -> Result<Option<Packet>>;

/// Destroys the `FormatReader` and returns the underlying media source stream
fn into_inner(self: Box<Self>) -> MediaSourceStream;
fn into_inner(self: Box<Self>) -> MediaSourceStream<'s>;
}

/// A `Packet` contains a discrete amount of encoded data for a single codec bitstream. The exact
Expand Down
18 changes: 9 additions & 9 deletions symphonia-core/src/io/media_source_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ impl Default for MediaSourceStreamOptions {
/// length buffer cache. By default, the buffer caches allows backtracking by up-to the minimum of
/// either `buffer_len - 32kB` or the total number of bytes read since instantiation or the last
/// buffer cache invalidation. Note that regular a `seek()` will invalidate the buffer cache.
pub struct MediaSourceStream {
pub struct MediaSourceStream<'s> {
/// The source reader.
inner: Box<dyn MediaSource>,
inner: Box<dyn MediaSource + 's>,
/// The ring buffer.
ring: Box<[u8]>,
/// The ring buffer's wrap-around mask.
Expand All @@ -69,11 +69,11 @@ pub struct MediaSourceStream {
rel_pos: u64,
}

impl MediaSourceStream {
impl<'s> MediaSourceStream<'s> {
const MIN_BLOCK_LEN: usize = 1 * 1024;
const MAX_BLOCK_LEN: usize = 32 * 1024;

pub fn new(source: Box<dyn MediaSource>, options: MediaSourceStreamOptions) -> Self {
pub fn new(source: Box<dyn MediaSource + 's>, options: MediaSourceStreamOptions) -> Self {
// The buffer length must be a power of 2, and > the maximum read block length.
assert!(options.buffer_len.count_ones() == 1);
assert!(options.buffer_len > Self::MAX_BLOCK_LEN);
Expand Down Expand Up @@ -174,7 +174,7 @@ impl MediaSourceStream {
}
}

impl MediaSource for MediaSourceStream {
impl MediaSource for MediaSourceStream<'_> {
#[inline]
fn is_seekable(&self) -> bool {
self.inner.is_seekable()
Expand All @@ -186,7 +186,7 @@ impl MediaSource for MediaSourceStream {
}
}

impl io::Read for MediaSourceStream {
impl io::Read for MediaSourceStream<'_> {
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
let read_len = buf.len();

Expand All @@ -213,7 +213,7 @@ impl io::Read for MediaSourceStream {
}
}

impl io::Seek for MediaSourceStream {
impl io::Seek for MediaSourceStream<'_> {
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
// The current position of the underlying reader is ahead of the current position of the
// MediaSourceStream by how ever many bytes have not been read from the read-ahead buffer
Expand All @@ -234,7 +234,7 @@ impl io::Seek for MediaSourceStream {
}
}

impl ReadBytes for MediaSourceStream {
impl ReadBytes for MediaSourceStream<'_> {
#[inline(always)]
fn read_byte(&mut self) -> io::Result<u8> {
// This function, read_byte, is inlined for performance. To reduce code bloat, place the
Expand Down Expand Up @@ -375,7 +375,7 @@ impl ReadBytes for MediaSourceStream {
}
}

impl SeekBuffered for MediaSourceStream {
impl SeekBuffered for MediaSourceStream<'_> {
fn ensure_seekback_buffer(&mut self, len: usize) {
let ring_len = self.ring.len();

Expand Down
Loading

0 comments on commit 316dbb8

Please sign in to comment.