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 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(&parameters.audio);
82        self.decoder.update(&parameters.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(&parameters.video);
135        self.decoder.update(&parameters.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}