media_codec/
decoder.rs

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 AudioDecoderConfiguration {
61    pub audio: AudioParameters,
62    pub decoder: DecoderParameters,
63}
64
65#[cfg(feature = "audio")]
66impl CodecConfiguration for AudioDecoderConfiguration {
67    type Parameters = AudioDecoderParameters;
68
69    fn from_parameters(parameters: &Self::Parameters) -> Result<Self> {
70        Ok(Self {
71            audio: parameters.audio.clone(),
72            decoder: parameters.decoder.clone(),
73        })
74    }
75
76    fn configure(&mut self, parameters: &Self::Parameters) -> Result<()> {
77        self.audio.update(&parameters.audio);
78        self.decoder.update(&parameters.decoder);
79        Ok(())
80    }
81
82    fn configure_with_option(&mut self, key: &str, value: &Variant) -> Result<()> {
83        self.audio.update_with_option(key, value);
84        self.decoder.update_with_option(key, value);
85        Ok(())
86    }
87}
88
89#[cfg(feature = "video")]
90#[derive(Clone, Debug, Default)]
91pub struct VideoDecoderParameters {
92    pub video: VideoParameters,
93    pub decoder: DecoderParameters,
94}
95
96#[cfg(feature = "video")]
97impl CodecParameters for VideoDecoderParameters {
98    fn media_type() -> MediaType {
99        MediaType::Video
100    }
101
102    fn codec_type() -> CodecType {
103        CodecType::Decoder
104    }
105}
106
107#[cfg(feature = "video")]
108#[derive(Clone, Debug)]
109pub struct VideoDecoderConfiguration {
110    pub video: VideoParameters,
111    pub decoder: DecoderParameters,
112}
113
114#[cfg(feature = "video")]
115impl CodecConfiguration for VideoDecoderConfiguration {
116    type Parameters = VideoDecoderParameters;
117
118    fn from_parameters(parameters: &Self::Parameters) -> Result<Self> {
119        Ok(Self {
120            video: parameters.video.clone(),
121            decoder: parameters.decoder.clone(),
122        })
123    }
124
125    fn configure(&mut self, parameters: &Self::Parameters) -> Result<()> {
126        self.video.update(&parameters.video);
127        self.decoder.update(&parameters.decoder);
128        Ok(())
129    }
130
131    fn configure_with_option(&mut self, key: &str, value: &Variant) -> Result<()> {
132        self.video.update_with_option(key, value);
133        self.decoder.update_with_option(key, value);
134        Ok(())
135    }
136}
137
138pub trait Decoder<T: CodecConfiguration>: Codec<T> + Send + Sync {
139    fn send_packet(&mut self, config: &T, packet: &Packet) -> Result<()>;
140    fn receive_frame(&mut self, config: &T) -> Result<Frame<'static>> {
141        self.receive_frame_borrowed(config).map(|frame| frame.into_owned())
142    }
143    fn receive_frame_borrowed(&mut self, config: &T) -> Result<Frame<'_>>;
144    fn flush(&mut self, config: &T) -> Result<()>;
145}
146
147pub trait DecoderBuilder<T: CodecConfiguration>: CodecBuilder<T> {
148    fn new_decoder(&self, id: CodecID, parameters: &T::Parameters, options: Option<&Variant>) -> Result<Box<dyn Decoder<T>>>;
149}
150
151pub struct DecoderContext<T: CodecConfiguration> {
152    pub configurations: T,
153    decoder: Box<dyn Decoder<T>>,
154}
155
156#[cfg(feature = "audio")]
157static AUDIO_DECODER_LIST: LazyCodecList<AudioDecoderConfiguration> = LazyLock::new(|| {
158    RwLock::new(CodecList::<AudioDecoderConfiguration> {
159        codecs: HashMap::new(),
160    })
161});
162
163#[cfg(feature = "video")]
164static VIDEO_DECODER_LIST: LazyCodecList<VideoDecoderConfiguration> = LazyLock::new(|| {
165    RwLock::new(CodecList::<VideoDecoderConfiguration> {
166        codecs: HashMap::new(),
167    })
168});
169
170pub fn register_decoder<T: CodecConfiguration>(builder: Arc<dyn DecoderBuilder<T>>, default: bool) -> Result<()> {
171    match TypeId::of::<T>() {
172        #[cfg(feature = "audio")]
173        id if id == TypeId::of::<AudioDecoderConfiguration>() => {
174            let builder = unsafe { mem::transmute::<Arc<dyn DecoderBuilder<T>>, Arc<dyn CodecBuilder<AudioDecoderConfiguration>>>(builder) };
175            register_codec(&AUDIO_DECODER_LIST, builder, default)
176        }
177        #[cfg(feature = "video")]
178        id if id == TypeId::of::<VideoDecoderConfiguration>() => {
179            let builder = unsafe { mem::transmute::<Arc<dyn DecoderBuilder<T>>, Arc<dyn CodecBuilder<VideoDecoderConfiguration>>>(builder) };
180            register_codec(&VIDEO_DECODER_LIST, builder, default)
181        }
182        _ => Err(Error::Unsupported("codec parameters type".to_string())),
183    }
184}
185
186pub(crate) fn find_decoder<T: CodecConfiguration>(id: CodecID) -> Result<Arc<dyn DecoderBuilder<T>>> {
187    match TypeId::of::<T>() {
188        #[cfg(feature = "audio")]
189        type_id if type_id == TypeId::of::<AudioDecoderConfiguration>() => {
190            let builder = find_codec(&AUDIO_DECODER_LIST, id)?;
191            unsafe { Ok(mem::transmute::<Arc<dyn CodecBuilder<AudioDecoderConfiguration>>, Arc<dyn DecoderBuilder<T>>>(builder)) }
192        }
193        #[cfg(feature = "video")]
194        type_id if type_id == TypeId::of::<VideoDecoderConfiguration>() => {
195            let builder = find_codec(&VIDEO_DECODER_LIST, id)?;
196            unsafe { Ok(mem::transmute::<Arc<dyn CodecBuilder<VideoDecoderConfiguration>>, Arc<dyn DecoderBuilder<T>>>(builder)) }
197        }
198        _ => Err(Error::Unsupported("codec parameters type".to_string())),
199    }
200}
201
202pub(crate) fn find_decoder_by_name<T: CodecConfiguration>(name: &str) -> Result<Arc<dyn DecoderBuilder<T>>> {
203    match TypeId::of::<T>() {
204        #[cfg(feature = "audio")]
205        id if id == TypeId::of::<AudioDecoderConfiguration>() => {
206            let builder = find_codec_by_name(&AUDIO_DECODER_LIST, name)?;
207            unsafe { Ok(mem::transmute::<Arc<dyn CodecBuilder<AudioDecoderConfiguration>>, Arc<dyn DecoderBuilder<T>>>(builder)) }
208        }
209        #[cfg(feature = "video")]
210        id if id == TypeId::of::<VideoDecoderConfiguration>() => {
211            let builder = find_codec_by_name(&VIDEO_DECODER_LIST, name)?;
212            unsafe { Ok(mem::transmute::<Arc<dyn CodecBuilder<VideoDecoderConfiguration>>, Arc<dyn DecoderBuilder<T>>>(builder)) }
213        }
214        _ => Err(Error::Unsupported("codec parameters type".to_string())),
215    }
216}
217
218impl<T: CodecConfiguration> DecoderContext<T> {
219    pub fn from_codec_id(id: CodecID, parameters: &T::Parameters, options: Option<&Variant>) -> Result<Self> {
220        let builder = find_decoder(id)?;
221        let decoder = builder.new_decoder(id, parameters, options)?;
222        let config = T::from_parameters(parameters)?;
223
224        Ok(Self {
225            configurations: config,
226            decoder,
227        })
228    }
229
230    pub fn from_codec_name(name: &str, parameters: &T::Parameters, options: Option<&Variant>) -> Result<Self> {
231        let builder = find_decoder_by_name(name)?;
232        let decoder = builder.new_decoder(builder.id(), parameters, options)?;
233        let config = T::from_parameters(parameters)?;
234
235        Ok(Self {
236            configurations: config,
237            decoder,
238        })
239    }
240
241    pub fn codec_id(&self) -> CodecID {
242        self.decoder.id()
243    }
244
245    pub fn codec_name(&self) -> &'static str {
246        self.decoder.name()
247    }
248
249    pub fn configure(&mut self, parameters: Option<&T::Parameters>, options: Option<&Variant>) -> Result<()> {
250        if let Some(params) = parameters {
251            self.configurations.configure(params)?;
252        }
253        self.decoder.configure(parameters, options)
254    }
255
256    pub fn set_option(&mut self, key: &str, value: &Variant) -> Result<()> {
257        self.decoder.set_option(key, value)
258    }
259
260    pub fn send_packet(&mut self, packet: &Packet) -> Result<()> {
261        self.decoder.send_packet(&self.configurations, packet)
262    }
263
264    pub fn receive_frame(&mut self) -> Result<Frame<'static>> {
265        self.decoder.receive_frame(&self.configurations)
266    }
267
268    pub fn receive_frame_borrowed(&mut self) -> Result<Frame<'_>> {
269        self.decoder.receive_frame_borrowed(&self.configurations)
270    }
271}