1use std::{
2 any::TypeId,
3 collections::HashMap,
4 mem,
5 sync::{Arc, LazyLock, RwLock},
6};
7
8use media_core::{error::Error, frame::Frame, variant::Variant, MediaType, Result};
9
10#[cfg(feature = "audio")]
11use crate::AudioParameters;
12#[cfg(feature = "video")]
13use crate::VideoParameters;
14use crate::{
15 find_codec, find_codec_by_name, packet::Packet, register_codec, Codec, CodecBuilder, CodecConfiguration, CodecID, CodecList, CodecParameters,
16 CodecType, LazyCodecList,
17};
18
19#[derive(Clone, Debug, Default)]
20pub struct DecoderParameters {
21 pub extra_data: Option<Vec<u8>>,
22}
23
24impl DecoderParameters {
25 fn update(&mut self, other: &DecoderParameters) {
26 if let Some(ref extra_data) = other.extra_data {
27 self.extra_data = Some(extra_data.clone());
28 }
29 }
30
31 fn update_with_option(&mut self, key: &str, value: &Variant) {
32 #[allow(clippy::single_match)]
33 match key {
34 "extra_data" => self.extra_data = value.get_buffer(),
35 _ => {}
36 }
37 }
38}
39
40#[cfg(feature = "audio")]
41#[derive(Clone, Debug, Default)]
42pub struct AudioDecoderParameters {
43 pub audio: AudioParameters,
44 pub decoder: DecoderParameters,
45}
46
47#[cfg(feature = "audio")]
48impl CodecParameters for AudioDecoderParameters {
49 fn media_type() -> MediaType {
50 MediaType::Audio
51 }
52
53 fn codec_type() -> CodecType {
54 CodecType::Decoder
55 }
56}
57
58#[cfg(feature = "audio")]
59#[derive(Clone, Debug)]
60pub struct AudioDecoder {
61 pub audio: AudioParameters,
62 pub decoder: DecoderParameters,
63}
64
65#[cfg(feature = "audio")]
66#[deprecated = "Use 'AudioDecoder' instead"]
67pub type AudioDecoderConfiguration = AudioDecoder;
68
69#[cfg(feature = "audio")]
70impl CodecConfiguration for AudioDecoder {
71 type Parameters = AudioDecoderParameters;
72
73 fn from_parameters(parameters: &Self::Parameters) -> Result<Self> {
74 Ok(Self {
75 audio: parameters.audio.clone(),
76 decoder: parameters.decoder.clone(),
77 })
78 }
79
80 fn configure(&mut self, parameters: &Self::Parameters) -> Result<()> {
81 self.audio.update(¶meters.audio);
82 self.decoder.update(¶meters.decoder);
83 Ok(())
84 }
85
86 fn configure_with_option(&mut self, key: &str, value: &Variant) -> Result<()> {
87 self.audio.update_with_option(key, value);
88 self.decoder.update_with_option(key, value);
89 Ok(())
90 }
91}
92
93#[cfg(feature = "video")]
94#[derive(Clone, Debug, Default)]
95pub struct VideoDecoderParameters {
96 pub video: VideoParameters,
97 pub decoder: DecoderParameters,
98}
99
100#[cfg(feature = "video")]
101impl CodecParameters for VideoDecoderParameters {
102 fn media_type() -> MediaType {
103 MediaType::Video
104 }
105
106 fn codec_type() -> CodecType {
107 CodecType::Decoder
108 }
109}
110
111#[cfg(feature = "video")]
112#[derive(Clone, Debug)]
113pub struct VideoDecoder {
114 pub video: VideoParameters,
115 pub decoder: DecoderParameters,
116}
117
118#[cfg(feature = "video")]
119#[deprecated = "Use 'VideoDecoder' instead"]
120pub type VideoDecoderConfiguration = VideoDecoder;
121
122#[cfg(feature = "video")]
123impl CodecConfiguration for VideoDecoder {
124 type Parameters = VideoDecoderParameters;
125
126 fn from_parameters(parameters: &Self::Parameters) -> Result<Self> {
127 Ok(Self {
128 video: parameters.video.clone(),
129 decoder: parameters.decoder.clone(),
130 })
131 }
132
133 fn configure(&mut self, parameters: &Self::Parameters) -> Result<()> {
134 self.video.update(¶meters.video);
135 self.decoder.update(¶meters.decoder);
136 Ok(())
137 }
138
139 fn configure_with_option(&mut self, key: &str, value: &Variant) -> Result<()> {
140 self.video.update_with_option(key, value);
141 self.decoder.update_with_option(key, value);
142 Ok(())
143 }
144}
145
146pub trait Decoder<T: CodecConfiguration>: Codec<T> + Send + Sync {
147 fn send_packet(&mut self, config: &T, packet: &Packet) -> Result<()>;
148 fn receive_frame(&mut self, config: &T) -> Result<Frame<'static>> {
149 self.receive_frame_borrowed(config).map(|frame| frame.into_owned())
150 }
151 fn receive_frame_borrowed(&mut self, config: &T) -> Result<Frame<'_>>;
152 fn flush(&mut self, config: &T) -> Result<()>;
153}
154
155pub trait DecoderBuilder<T: CodecConfiguration>: CodecBuilder<T> {
156 fn new_decoder(&self, id: CodecID, parameters: &T::Parameters, options: Option<&Variant>) -> Result<Box<dyn Decoder<T>>>;
157}
158
159pub struct DecoderContext<T: CodecConfiguration> {
160 pub configurations: T,
161 decoder: Box<dyn Decoder<T>>,
162}
163
164#[cfg(feature = "audio")]
165static AUDIO_DECODER_LIST: LazyCodecList<AudioDecoder> = LazyLock::new(|| {
166 RwLock::new(CodecList::<AudioDecoder> {
167 codecs: HashMap::new(),
168 })
169});
170
171#[cfg(feature = "video")]
172static VIDEO_DECODER_LIST: LazyCodecList<VideoDecoder> = LazyLock::new(|| {
173 RwLock::new(CodecList::<VideoDecoder> {
174 codecs: HashMap::new(),
175 })
176});
177
178pub fn register_decoder<T: CodecConfiguration>(builder: Arc<dyn DecoderBuilder<T>>, default: bool) -> Result<()> {
179 match TypeId::of::<T>() {
180 #[cfg(feature = "audio")]
181 id if id == TypeId::of::<AudioDecoder>() => {
182 let builder = unsafe { mem::transmute::<Arc<dyn DecoderBuilder<T>>, Arc<dyn CodecBuilder<AudioDecoder>>>(builder) };
183 register_codec(&AUDIO_DECODER_LIST, builder, default)
184 }
185 #[cfg(feature = "video")]
186 id if id == TypeId::of::<VideoDecoder>() => {
187 let builder = unsafe { mem::transmute::<Arc<dyn DecoderBuilder<T>>, Arc<dyn CodecBuilder<VideoDecoder>>>(builder) };
188 register_codec(&VIDEO_DECODER_LIST, builder, default)
189 }
190 _ => Err(Error::Unsupported("codec parameters type".to_string())),
191 }
192}
193
194pub(crate) fn find_decoder<T: CodecConfiguration>(id: CodecID) -> Result<Arc<dyn DecoderBuilder<T>>> {
195 match TypeId::of::<T>() {
196 #[cfg(feature = "audio")]
197 type_id if type_id == TypeId::of::<AudioDecoder>() => {
198 let builder = find_codec(&AUDIO_DECODER_LIST, id)?;
199 unsafe { Ok(mem::transmute::<Arc<dyn CodecBuilder<AudioDecoder>>, Arc<dyn DecoderBuilder<T>>>(builder)) }
200 }
201 #[cfg(feature = "video")]
202 type_id if type_id == TypeId::of::<VideoDecoder>() => {
203 let builder = find_codec(&VIDEO_DECODER_LIST, id)?;
204 unsafe { Ok(mem::transmute::<Arc<dyn CodecBuilder<VideoDecoder>>, Arc<dyn DecoderBuilder<T>>>(builder)) }
205 }
206 _ => Err(Error::Unsupported("codec parameters type".to_string())),
207 }
208}
209
210pub(crate) fn find_decoder_by_name<T: CodecConfiguration>(name: &str) -> Result<Arc<dyn DecoderBuilder<T>>> {
211 match TypeId::of::<T>() {
212 #[cfg(feature = "audio")]
213 id if id == TypeId::of::<AudioDecoder>() => {
214 let builder = find_codec_by_name(&AUDIO_DECODER_LIST, name)?;
215 unsafe { Ok(mem::transmute::<Arc<dyn CodecBuilder<AudioDecoder>>, Arc<dyn DecoderBuilder<T>>>(builder)) }
216 }
217 #[cfg(feature = "video")]
218 id if id == TypeId::of::<VideoDecoder>() => {
219 let builder = find_codec_by_name(&VIDEO_DECODER_LIST, name)?;
220 unsafe { Ok(mem::transmute::<Arc<dyn CodecBuilder<VideoDecoder>>, Arc<dyn DecoderBuilder<T>>>(builder)) }
221 }
222 _ => Err(Error::Unsupported("codec parameters type".to_string())),
223 }
224}
225
226impl<T: CodecConfiguration> DecoderContext<T> {
227 pub fn from_codec_id(id: CodecID, parameters: &T::Parameters, options: Option<&Variant>) -> Result<Self> {
228 let builder = find_decoder(id)?;
229 let decoder = builder.new_decoder(id, parameters, options)?;
230 let config = T::from_parameters(parameters)?;
231
232 Ok(Self {
233 configurations: config,
234 decoder,
235 })
236 }
237
238 pub fn from_codec_name(name: &str, parameters: &T::Parameters, options: Option<&Variant>) -> Result<Self> {
239 let builder = find_decoder_by_name(name)?;
240 let decoder = builder.new_decoder(builder.id(), parameters, options)?;
241 let config = T::from_parameters(parameters)?;
242
243 Ok(Self {
244 configurations: config,
245 decoder,
246 })
247 }
248
249 pub fn codec_id(&self) -> CodecID {
250 self.decoder.id()
251 }
252
253 pub fn codec_name(&self) -> &'static str {
254 self.decoder.name()
255 }
256
257 pub fn configure(&mut self, parameters: Option<&T::Parameters>, options: Option<&Variant>) -> Result<()> {
258 if let Some(params) = parameters {
259 self.configurations.configure(params)?;
260 }
261 self.decoder.configure(parameters, options)
262 }
263
264 pub fn set_option(&mut self, key: &str, value: &Variant) -> Result<()> {
265 self.decoder.set_option(key, value)
266 }
267
268 pub fn send_packet(&mut self, packet: &Packet) -> Result<()> {
269 self.decoder.send_packet(&self.configurations, packet)
270 }
271
272 pub fn receive_frame(&mut self) -> Result<Frame<'static>> {
273 self.decoder.receive_frame(&self.configurations)
274 }
275
276 pub fn receive_frame_borrowed(&mut self) -> Result<Frame<'_>> {
277 self.decoder.receive_frame_borrowed(&self.configurations)
278 }
279}