mirror of
https://github.com/librespot-org/librespot.git
synced 2025-02-06 17:47:10 +00:00
Simplify time calculations in SymphoniaDecoder
Time impl's from f64 (as secs) so there's no need to manually calculate it beyond converting ms to sec. If we grab the TimeBase in new we don't need to continually call decoder.codec_params().time_base everytime we want to convert ts to ms.
This commit is contained in:
parent
0bdfa726ca
commit
5e02b6643d
1 changed files with 12 additions and 15 deletions
|
@ -8,7 +8,7 @@ use symphonia::{
|
||||||
formats::{FormatOptions, FormatReader, SeekMode, SeekTo},
|
formats::{FormatOptions, FormatReader, SeekMode, SeekTo},
|
||||||
io::{MediaSource, MediaSourceStream, MediaSourceStreamOptions},
|
io::{MediaSource, MediaSourceStream, MediaSourceStreamOptions},
|
||||||
meta::{StandardTagKey, Value},
|
meta::{StandardTagKey, Value},
|
||||||
units::Time,
|
units::TimeBase,
|
||||||
},
|
},
|
||||||
default::{
|
default::{
|
||||||
codecs::{MpaDecoder, VorbisDecoder},
|
codecs::{MpaDecoder, VorbisDecoder},
|
||||||
|
@ -27,6 +27,7 @@ use crate::{
|
||||||
pub struct SymphoniaDecoder {
|
pub struct SymphoniaDecoder {
|
||||||
format: Box<dyn FormatReader>,
|
format: Box<dyn FormatReader>,
|
||||||
decoder: Box<dyn Decoder>,
|
decoder: Box<dyn Decoder>,
|
||||||
|
time_base: Option<TimeBase>,
|
||||||
sample_buffer: Option<SampleBuffer<f64>>,
|
sample_buffer: Option<SampleBuffer<f64>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,9 +89,12 @@ impl SymphoniaDecoder {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let time_base = decoder.codec_params().time_base;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
format,
|
format,
|
||||||
decoder,
|
decoder,
|
||||||
|
time_base,
|
||||||
|
|
||||||
// We set the sample buffer when decoding the first full packet,
|
// We set the sample buffer when decoding the first full packet,
|
||||||
// whose duration is also the ideal sample buffer size.
|
// whose duration is also the ideal sample buffer size.
|
||||||
|
@ -133,30 +137,23 @@ impl SymphoniaDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ts_to_ms(&self, ts: u64) -> u32 {
|
fn ts_to_ms(&self, ts: u64) -> u32 {
|
||||||
let time_base = self.decoder.codec_params().time_base;
|
// Falls back in the unexpected case that the format has no base time set.
|
||||||
let seeked_to_ms = match time_base {
|
self.time_base
|
||||||
Some(time_base) => {
|
.map(|time_base| {
|
||||||
let time = time_base.calc_time(ts);
|
let time = time_base.calc_time(ts);
|
||||||
(time.seconds as f64 + time.frac) * 1000.
|
((time.seconds as f64 + time.frac) * 1000.) as u32
|
||||||
}
|
})
|
||||||
// Fallback in the unexpected case that the format has no base time set.
|
.unwrap_or((ts as f64 * PAGES_PER_MS) as u32)
|
||||||
None => ts as f64 * PAGES_PER_MS,
|
|
||||||
};
|
|
||||||
seeked_to_ms as u32
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AudioDecoder for SymphoniaDecoder {
|
impl AudioDecoder for SymphoniaDecoder {
|
||||||
fn seek(&mut self, position_ms: u32) -> Result<u32, DecoderError> {
|
fn seek(&mut self, position_ms: u32) -> Result<u32, DecoderError> {
|
||||||
let seconds = position_ms as u64 / 1000;
|
|
||||||
let frac = (position_ms as f64 % 1000.) / 1000.;
|
|
||||||
let time = Time::new(seconds, frac);
|
|
||||||
|
|
||||||
// `track_id: None` implies the default track ID (of the container, not of Spotify).
|
// `track_id: None` implies the default track ID (of the container, not of Spotify).
|
||||||
let seeked_to_ts = self.format.seek(
|
let seeked_to_ts = self.format.seek(
|
||||||
SeekMode::Accurate,
|
SeekMode::Accurate,
|
||||||
SeekTo::Time {
|
SeekTo::Time {
|
||||||
time,
|
time: (position_ms as f64 / 1000.).into(),
|
||||||
track_id: None,
|
track_id: None,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
Loading…
Reference in a new issue