1use std::sync::Arc;
2
3#[cfg(feature = "audio")]
4use media_core::audio::AudioFrameDescriptor;
5#[cfg(feature = "video")]
6use media_core::video::VideoFrameDescriptor;
7use media_core::{
8 error::Error,
9 frame::{Frame, SharedFrame},
10 frame_pool::FramePool,
11 invalid_param_error,
12 variant::Variant,
13 MediaType, Result,
14};
15
16#[cfg(feature = "audio")]
17use crate::AudioParameters;
18#[cfg(feature = "video")]
19use crate::VideoParameters;
20use crate::{packet::Packet, Codec, CodecBuilder, CodecID, CodecParameters, CodecParametersType, CodecSpec, CodecType, MediaParametersType};
21
22#[derive(Clone, Debug)]
23pub enum ExtraData {
24 Raw(Vec<u8>),
25 #[cfg(feature = "audio")]
26 ASC {
27 object_type: u8,
28 channel_config: u8,
29 },
30 #[cfg(feature = "video")]
31 AVC {
32 sps: Vec<Vec<u8>>,
33 pps: Vec<Vec<u8>>,
34 nalu_length_size: u8,
35 },
36 #[cfg(feature = "video")]
37 HEVC {
38 vps: Option<Vec<Vec<u8>>>,
39 sps: Vec<Vec<u8>>,
40 pps: Vec<Vec<u8>>,
41 nalu_length_size: u8,
42 },
43}
44
45#[derive(Clone, Debug, Default)]
46pub struct DecoderParameters {
47 pub extra_data: Option<ExtraData>,
48 pub use_pool: Option<bool>,
49}
50
51impl DecoderParameters {
52 fn update(&mut self, other: &DecoderParameters) {
53 if let Some(ref extra_data) = other.extra_data {
54 self.extra_data = Some(extra_data.clone());
55 }
56 }
57
58 fn update_with_option(&mut self, key: &str, value: &Variant) {
59 #[allow(clippy::single_match)]
60 match key {
61 "extra_data" => self.extra_data = value.get_buffer().map(ExtraData::Raw),
62 "use_pool" => self.use_pool = value.get_bool(),
63 _ => {}
64 }
65 }
66}
67
68impl TryFrom<&CodecParametersType> for DecoderParameters {
69 type Error = Error;
70
71 fn try_from(params: &CodecParametersType) -> Result<Self> {
72 #[allow(unreachable_patterns)]
73 match params {
74 CodecParametersType::Decoder(params) => Ok(params.clone()),
75 _ => Err(invalid_param_error!(params)),
76 }
77 }
78}
79
80#[cfg(feature = "audio")]
81#[derive(Clone, Debug, Default)]
82pub struct AudioDecoderParameters {
83 pub audio: AudioParameters,
84 pub decoder: DecoderParameters,
85}
86
87#[cfg(feature = "audio")]
88#[allow(unreachable_patterns)]
89impl TryFrom<&CodecParameters> for AudioDecoderParameters {
90 type Error = Error;
91
92 fn try_from(params: &CodecParameters) -> Result<Self> {
93 Ok(Self {
94 audio: match ¶ms.media {
95 MediaParametersType::Audio(params) => params.clone(),
96 _ => return Err(invalid_param_error!(params)),
97 },
98 decoder: match ¶ms.codec {
99 CodecParametersType::Decoder(params) => params.clone(),
100 _ => return Err(invalid_param_error!(params)),
101 },
102 })
103 }
104}
105
106#[cfg(feature = "audio")]
107#[derive(Clone, Debug)]
108pub struct AudioDecoder {
109 pub audio: AudioParameters,
110 pub decoder: DecoderParameters,
111}
112
113#[cfg(feature = "audio")]
114impl CodecSpec for AudioDecoder {
115 type FrameDescriptor = AudioFrameDescriptor;
116
117 fn media_type() -> MediaType {
118 MediaType::Audio
119 }
120
121 fn codec_type() -> CodecType {
122 CodecType::Decoder
123 }
124
125 fn from_parameters(params: &CodecParameters) -> Result<Self> {
126 Ok(Self {
127 audio: (¶ms.media).try_into()?,
128 decoder: (¶ms.codec).try_into()?,
129 })
130 }
131
132 fn configure(&mut self, params: &CodecParameters) -> Result<()> {
133 let audio_params = (¶ms.media).try_into()?;
134 let decoder_params = (¶ms.codec).try_into()?;
135 self.audio.update(&audio_params);
136 self.decoder.update(&decoder_params);
137 Ok(())
138 }
139
140 fn configure_with_option(&mut self, key: &str, value: &Variant) -> Result<()> {
141 self.audio.update_with_option(key, value);
142 self.decoder.update_with_option(key, value);
143 Ok(())
144 }
145}
146
147#[cfg(feature = "video")]
148#[derive(Clone, Debug, Default)]
149pub struct VideoDecoderParameters {
150 pub video: VideoParameters,
151 pub decoder: DecoderParameters,
152}
153
154#[cfg(feature = "video")]
155#[allow(unreachable_patterns)]
156impl TryFrom<&CodecParameters> for VideoDecoderParameters {
157 type Error = Error;
158
159 fn try_from(params: &CodecParameters) -> Result<Self> {
160 Ok(Self {
161 video: match ¶ms.media {
162 MediaParametersType::Video(params) => params.clone(),
163 _ => return Err(invalid_param_error!(params)),
164 },
165 decoder: match ¶ms.codec {
166 CodecParametersType::Decoder(params) => params.clone(),
167 _ => return Err(invalid_param_error!(params)),
168 },
169 })
170 }
171}
172
173#[cfg(feature = "video")]
174#[derive(Clone, Debug)]
175pub struct VideoDecoder {
176 pub video: VideoParameters,
177 pub decoder: DecoderParameters,
178}
179
180#[cfg(feature = "video")]
181impl CodecSpec for VideoDecoder {
182 type FrameDescriptor = VideoFrameDescriptor;
183
184 fn media_type() -> MediaType {
185 MediaType::Video
186 }
187
188 fn codec_type() -> CodecType {
189 CodecType::Decoder
190 }
191
192 #[allow(unreachable_patterns)]
193 fn from_parameters(params: &CodecParameters) -> Result<Self> {
194 Ok(Self {
195 video: match ¶ms.media {
196 MediaParametersType::Video(params) => params.clone(),
197 _ => return Err(invalid_param_error!(params)),
198 },
199 decoder: match ¶ms.codec {
200 CodecParametersType::Decoder(params) => params.clone(),
201 _ => return Err(invalid_param_error!(params)),
202 },
203 })
204 }
205
206 #[allow(unreachable_patterns)]
207 fn configure(&mut self, params: &CodecParameters) -> Result<()> {
208 let video_params = (¶ms.media).try_into()?;
209 let decoder_params = (¶ms.codec).try_into()?;
210 self.video.update(&video_params);
211 self.decoder.update(&decoder_params);
212 Ok(())
213 }
214
215 fn configure_with_option(&mut self, key: &str, value: &Variant) -> Result<()> {
216 self.video.update_with_option(key, value);
217 self.decoder.update_with_option(key, value);
218 Ok(())
219 }
220}
221
222pub trait Decoder<T: CodecSpec>: Codec<T> + Send + Sync {
223 fn init(&mut self, _config: &T) -> Result<()> {
224 Ok(())
225 }
226 fn send_packet(&mut self, config: &T, pool: Option<&Arc<FramePool<Frame<'static, T::FrameDescriptor>>>>, packet: &Packet) -> Result<()>;
227 fn receive_frame(
228 &mut self,
229 config: &T,
230 pool: Option<&Arc<FramePool<Frame<'static, T::FrameDescriptor>>>>,
231 ) -> Result<SharedFrame<Frame<'static, T::FrameDescriptor>>>;
232 fn flush(&mut self, config: &T) -> Result<()>;
233}
234
235pub trait DecoderBuilder<T: CodecSpec>: CodecBuilder<T> {
236 fn new_decoder(&self, id: CodecID, params: &CodecParameters, options: Option<&Variant>) -> Result<Box<dyn Decoder<T>>>;
237}