media_core/audio/
frame.rs

1use std::{
2    borrow::Cow,
3    num::{NonZeroU32, NonZeroU8},
4};
5
6use aligned_vec::avec;
7
8use super::audio::{AudioFrameDescriptor, SampleFormat};
9use crate::{
10    error::Error,
11    frame::{Data, Frame, FrameData, FrameSpec, MemoryData},
12    invalid_param_error, unsupported_error, FrameDescriptor, MediaType, Result, DEFAULT_ALIGNMENT,
13};
14
15pub type AudioFrame<'a> = Frame<'a, AudioFrameDescriptor>;
16
17pub struct AudioDataCreator;
18
19impl AudioDataCreator {
20    fn create(format: SampleFormat, channels: NonZeroU8, samples: NonZeroU32) -> Result<MemoryData<'static>> {
21        let (size, planes) = format.calc_data_size(channels.get(), samples.get(), DEFAULT_ALIGNMENT as u32);
22        let initial_value = if matches!(format, SampleFormat::U8 | SampleFormat::U8P) {
23            0x80
24        } else {
25            0
26        };
27
28        Ok(MemoryData {
29            data: Data::Owned(avec![[DEFAULT_ALIGNMENT]| initial_value; size]),
30            planes,
31        })
32    }
33
34    fn create_from_buffer<'a, T>(format: SampleFormat, channels: NonZeroU8, samples: NonZeroU32, buffer: T) -> Result<MemoryData<'a>>
35    where
36        T: Into<Cow<'a, [u8]>>,
37    {
38        let (size, planes) = format.calc_data_size(channels.get(), samples.get(), 1);
39        let buffer = buffer.into();
40
41        if buffer.len() != size {
42            return Err(Error::Invalid("buffer size".to_string()));
43        }
44
45        Ok(MemoryData {
46            data: buffer.into(),
47            planes,
48        })
49    }
50}
51
52pub struct AudioFrameCreator;
53
54impl AudioFrameCreator {
55    pub fn create(&self, format: SampleFormat, channels: u8, samples: u32, sample_rate: u32) -> Result<Frame<'static>> {
56        let desc = AudioFrameDescriptor::try_new(format, channels, samples, sample_rate)?;
57
58        self.create_with_descriptor(desc)
59    }
60
61    pub fn create_with_descriptor(&self, desc: AudioFrameDescriptor) -> Result<Frame<'static>> {
62        let data = AudioDataCreator::create(desc.format, desc.channels(), desc.samples)?;
63
64        Ok(Frame::from_data(FrameDescriptor::Audio(desc), FrameData::Memory(data)))
65    }
66
67    pub fn create_from_buffer<'a, T>(&self, format: SampleFormat, channels: u8, samples: u32, sample_rate: u32, buffer: T) -> Result<Frame<'a>>
68    where
69        T: Into<Cow<'a, [u8]>>,
70    {
71        let desc = AudioFrameDescriptor::try_new(format, channels, samples, sample_rate)?;
72
73        self.create_from_buffer_with_descriptor(desc, buffer)
74    }
75
76    pub fn create_from_buffer_with_descriptor<'a, T>(&self, desc: AudioFrameDescriptor, buffer: T) -> Result<Frame<'a>>
77    where
78        T: Into<Cow<'a, [u8]>>,
79    {
80        let data = AudioDataCreator::create_from_buffer(desc.format, desc.channels(), desc.samples, buffer)?;
81
82        Ok(Frame::from_data(FrameDescriptor::Audio(desc), FrameData::Memory(data)))
83    }
84
85    pub fn create_empty(&self, format: SampleFormat, channels: u8, samples: u32, sample_rate: u32) -> Result<Frame<'static>> {
86        let desc = AudioFrameDescriptor::try_new(format, channels, samples, sample_rate)?;
87
88        self.create_empty_with_descriptor(desc)
89    }
90
91    pub fn create_empty_with_descriptor(&self, desc: AudioFrameDescriptor) -> Result<Frame<'static>> {
92        let data = FrameData::Empty;
93
94        Ok(Frame::from_data(FrameDescriptor::Audio(desc), data))
95    }
96}
97
98impl Frame<'_> {
99    pub fn audio_creator() -> AudioFrameCreator {
100        AudioFrameCreator
101    }
102
103    pub fn audio_descriptor(&self) -> Option<&AudioFrameDescriptor> {
104        if let FrameDescriptor::Audio(desc) = &self.desc {
105            Some(desc)
106        } else {
107            None
108        }
109    }
110
111    pub fn is_audio(&self) -> bool {
112        self.desc.is_audio()
113    }
114
115    pub fn truncate(&mut self, samples: u32) -> Result<()> {
116        let FrameDescriptor::Audio(desc) = &mut self.desc else {
117            return Err(unsupported_error!(self.desc));
118        };
119
120        AudioFrame::truncate_internal(desc, &mut self.data, samples)
121    }
122}
123
124impl AudioFrame<'_> {
125    pub fn new(format: SampleFormat, channels: u8, samples: u32, sample_rate: u32) -> Result<Self> {
126        let desc = AudioFrameDescriptor::try_new(format, channels, samples, sample_rate)?;
127
128        Self::new_with_descriptor(desc)
129    }
130
131    pub fn new_with_descriptor(desc: AudioFrameDescriptor) -> Result<Self> {
132        let data = AudioDataCreator::create(desc.format, desc.channels(), desc.samples)?;
133
134        Ok(Frame::from_data_with_generic_descriptor(desc, FrameData::Memory(data)))
135    }
136
137    pub fn from_buffer<'a, T>(format: SampleFormat, channels: u8, samples: u32, sample_rate: u32, buffer: T) -> Result<AudioFrame<'a>>
138    where
139        T: Into<Cow<'a, [u8]>>,
140    {
141        let desc = AudioFrameDescriptor::try_new(format, channels, samples, sample_rate)?;
142
143        Self::from_buffer_with_descriptor(desc, buffer)
144    }
145
146    pub fn from_buffer_with_descriptor<'a, T>(desc: AudioFrameDescriptor, buffer: T) -> Result<AudioFrame<'a>>
147    where
148        T: Into<Cow<'a, [u8]>>,
149    {
150        let data = AudioDataCreator::create_from_buffer(desc.format, desc.channels(), desc.samples, buffer)?;
151
152        Ok(Frame::from_data_with_generic_descriptor(desc, FrameData::Memory(data)))
153    }
154
155    pub fn new_empty(format: SampleFormat, channels: u8, samples: u32, sample_rate: u32) -> Result<Self> {
156        let desc = AudioFrameDescriptor::try_new(format, channels, samples, sample_rate)?;
157
158        Self::new_empty_with_descriptor(desc)
159    }
160
161    pub fn new_empty_with_descriptor(desc: AudioFrameDescriptor) -> Result<Self> {
162        let data = FrameData::Empty;
163
164        Ok(Frame::from_data_with_generic_descriptor(desc, data))
165    }
166
167    fn truncate_internal(desc: &mut AudioFrameDescriptor, data: &mut FrameData, samples: u32) -> Result<()> {
168        if desc.samples.get() < samples || samples == 0 {
169            return Err(invalid_param_error!(samples));
170        }
171
172        let actual_bytes = desc.format.calc_plane_size(desc.channels().get(), samples);
173        data.truncate(actual_bytes)?;
174
175        desc.samples = NonZeroU32::new(samples).unwrap();
176
177        Ok(())
178    }
179
180    pub fn truncate(&mut self, samples: u32) -> Result<()> {
181        Self::truncate_internal(&mut self.desc, &mut self.data, samples)
182    }
183}
184
185impl<'a> From<AudioFrame<'a>> for Frame<'a> {
186    fn from(frame: AudioFrame<'a>) -> Self {
187        Frame {
188            desc: FrameDescriptor::Audio(frame.desc),
189            source: frame.source,
190            pts: frame.pts,
191            dts: frame.dts,
192            duration: frame.duration,
193            time_base: frame.time_base,
194            metadata: frame.metadata,
195            data: frame.data,
196        }
197    }
198}
199
200impl<'a> TryFrom<Frame<'a>> for AudioFrame<'a> {
201    type Error = Error;
202
203    fn try_from(frame: Frame<'a>) -> Result<Self> {
204        if let FrameDescriptor::Audio(desc) = frame.desc {
205            Ok(Frame {
206                desc,
207                source: frame.source,
208                pts: frame.pts,
209                dts: frame.dts,
210                duration: frame.duration,
211                time_base: frame.time_base,
212                metadata: frame.metadata,
213                data: frame.data,
214            })
215        } else {
216            Err(Error::Invalid("not audio frame".to_string()))
217        }
218    }
219}
220
221impl FrameSpec<AudioFrameDescriptor> for AudioFrame<'_> {
222    fn new_with_descriptor(desc: AudioFrameDescriptor) -> Result<Frame<'static, AudioFrameDescriptor>> {
223        AudioFrame::new_with_descriptor(desc)
224    }
225
226    fn media_type(&self) -> MediaType {
227        MediaType::Audio
228    }
229}