selene_core/media_container/
stream.rs1use serde::{Deserialize, Serialize};
2use symphonia::core::codecs::CodecParameters;
3
4use crate::{
5 errors::ContainerError,
6 media_container::{channel_layout::ChannelLayout, codec::Codec, sample_format::SampleFormat},
7};
8
9#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Copy)]
10pub struct Stream {
11 pub(crate) codec: Codec,
12 pub(crate) sample_rate: u32,
13 pub(crate) time_base: Option<(u32, u32)>,
14 pub(crate) n_frames: Option<u64>,
15 pub(crate) start_ts: u64,
16 pub(crate) sample_format: Option<SampleFormat>,
17 pub(crate) bits_per_sample: Option<u32>,
18 pub(crate) bits_per_coded_sample: Option<u32>,
19 pub(crate) channels: usize,
20 pub(crate) channel_layout: Option<ChannelLayout>,
21 pub(crate) delay: Option<u32>,
22 pub(crate) padding: Option<u32>,
23 pub(crate) max_frames_per_packet: Option<u64>,
24 pub(crate) packet_data_integrity: bool,
25 pub(crate) frames_per_block: Option<u64>,
26}
27
28impl Stream {
29 #[must_use]
30 pub fn sample_rate(&self) -> u32 {
31 self.sample_rate
32 }
33
34 #[must_use]
35 pub fn duration(&self) -> Option<f64> {
36 let frames = self.n_frames? as f64;
37 let rate = f64::from(self.sample_rate);
38 Some(frames / rate)
39 }
40
41 #[must_use]
42 pub fn channel_count(&self) -> usize {
43 self.channels
44 }
45
46 #[must_use]
47 pub fn channel_layout(&self) -> Option<&ChannelLayout> {
48 self.channel_layout.as_ref()
49 }
50}
51
52impl TryFrom<CodecParameters> for Stream {
53 type Error = ContainerError;
54
55 fn try_from(value: CodecParameters) -> Result<Self, Self::Error> {
56 Ok(Self {
57 codec: Codec::try_from(value.codec)?,
58 sample_rate: value.sample_rate.ok_or(ContainerError::NoSampleRate)?,
59 time_base: value.time_base.map(|b| (b.numer, b.denom)),
60 n_frames: value.n_frames,
61 start_ts: value.start_ts,
62 sample_format: value.sample_format.map(SampleFormat::from),
63 bits_per_sample: value.bits_per_sample,
64 bits_per_coded_sample: value.bits_per_coded_sample,
65 channels: value
66 .channels
67 .ok_or(ContainerError::NoChannelCount)?
68 .count(),
69 channel_layout: value.channel_layout.map(ChannelLayout::from),
70 delay: value.delay,
71 padding: value.padding,
72 max_frames_per_packet: value.max_frames_per_packet,
73 packet_data_integrity: value.packet_data_integrity,
74 frames_per_block: value.frames_per_block,
75 })
76 }
77}