Skip to main content

media_codec_types/
encoder.rs

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    buffer::BufferPool,
9    error::Error,
10    frame::{Frame, SharedFrame},
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, Default)]
23pub struct EncoderParameters {
24    pub bit_rate: Option<u64>,
25    pub profile: Option<i32>,
26    pub level: Option<i32>,
27    pub use_pool: Option<bool>,
28}
29
30impl EncoderParameters {
31    fn update(&mut self, other: &EncoderParameters) {
32        if other.bit_rate.is_some() {
33            self.bit_rate = other.bit_rate;
34        }
35        if other.profile.is_some() {
36            self.profile = other.profile;
37        }
38        if other.level.is_some() {
39            self.level = other.level;
40        }
41    }
42
43    fn update_with_option(&mut self, key: &str, value: &Variant) {
44        match key {
45            "bit_rate" => self.bit_rate = value.get_uint64(),
46            "profile" => self.profile = value.get_int32(),
47            "level" => self.level = value.get_int32(),
48            _ => {}
49        }
50    }
51}
52
53impl TryFrom<&CodecParametersType> for EncoderParameters {
54    type Error = Error;
55
56    fn try_from(params: &CodecParametersType) -> Result<Self> {
57        #[allow(unreachable_patterns)]
58        match params {
59            CodecParametersType::Encoder(params) => Ok(params.clone()),
60            _ => Err(invalid_param_error!(params)),
61        }
62    }
63}
64
65#[cfg(feature = "audio")]
66#[derive(Clone, Debug, Default)]
67pub struct AudioEncoderParameters {
68    pub audio: AudioParameters,
69    pub encoder: EncoderParameters,
70}
71
72#[cfg(feature = "audio")]
73#[allow(unreachable_patterns)]
74impl TryFrom<&CodecParameters> for AudioEncoderParameters {
75    type Error = Error;
76
77    fn try_from(params: &CodecParameters) -> Result<Self> {
78        Ok(Self {
79            audio: match &params.media {
80                MediaParametersType::Audio(params) => params.clone(),
81                _ => return Err(invalid_param_error!(params)),
82            },
83            encoder: match &params.codec {
84                CodecParametersType::Encoder(params) => params.clone(),
85                _ => return Err(invalid_param_error!(params)),
86            },
87        })
88    }
89}
90
91#[cfg(feature = "audio")]
92#[derive(Clone, Debug)]
93pub struct AudioEncoder {
94    pub audio: AudioParameters,
95    pub encoder: EncoderParameters,
96    // audio encoder specific configuration
97    pub frame_size: Option<u32>,
98    pub delay: Option<u32>,
99}
100
101#[cfg(feature = "audio")]
102impl CodecSpec for AudioEncoder {
103    type FrameDescriptor = AudioFrameDescriptor;
104
105    fn media_type() -> MediaType {
106        MediaType::Audio
107    }
108
109    fn codec_type() -> CodecType {
110        CodecType::Encoder
111    }
112
113    fn from_parameters(params: &CodecParameters) -> Result<Self> {
114        Ok(Self {
115            audio: (&params.media).try_into()?,
116            encoder: (&params.codec).try_into()?,
117            frame_size: None,
118            delay: None,
119        })
120    }
121
122    fn configure(&mut self, params: &CodecParameters) -> Result<()> {
123        let audio_params = (&params.media).try_into()?;
124        let encoder_params = (&params.codec).try_into()?;
125        self.audio.update(&audio_params);
126        self.encoder.update(&encoder_params);
127        Ok(())
128    }
129
130    fn configure_with_option(&mut self, key: &str, value: &Variant) -> Result<()> {
131        self.audio.update_with_option(key, value);
132        self.encoder.update_with_option(key, value);
133
134        match key {
135            "frame_size" => self.frame_size = value.get_uint32(),
136            "delay" => self.delay = value.get_uint32(),
137            _ => {}
138        }
139
140        Ok(())
141    }
142}
143
144#[cfg(feature = "video")]
145#[derive(Clone, Debug, Default)]
146pub struct VideoEncoderParameters {
147    pub video: VideoParameters,
148    pub encoder: EncoderParameters,
149}
150
151#[cfg(feature = "video")]
152#[allow(unreachable_patterns)]
153impl TryFrom<&CodecParameters> for VideoEncoderParameters {
154    type Error = Error;
155
156    #[allow(unreachable_patterns)]
157    fn try_from(params: &CodecParameters) -> Result<Self> {
158        Ok(Self {
159            video: match &params.media {
160                MediaParametersType::Video(params) => params.clone(),
161                _ => return Err(invalid_param_error!(params)),
162            },
163            encoder: match &params.codec {
164                CodecParametersType::Encoder(params) => params.clone(),
165                _ => return Err(invalid_param_error!(params)),
166            },
167        })
168    }
169}
170
171#[cfg(feature = "video")]
172#[derive(Clone, Debug)]
173pub struct VideoEncoder {
174    pub video: VideoParameters,
175    pub encoder: EncoderParameters,
176}
177
178#[cfg(feature = "video")]
179impl CodecSpec for VideoEncoder {
180    type FrameDescriptor = VideoFrameDescriptor;
181
182    fn media_type() -> MediaType {
183        MediaType::Video
184    }
185
186    fn codec_type() -> CodecType {
187        CodecType::Encoder
188    }
189
190    #[allow(unreachable_patterns)]
191    fn from_parameters(params: &CodecParameters) -> Result<Self> {
192        Ok(Self {
193            video: match &params.media {
194                MediaParametersType::Video(params) => params.clone(),
195                _ => return Err(invalid_param_error!(params)),
196            },
197            encoder: match &params.codec {
198                CodecParametersType::Encoder(params) => params.clone(),
199                _ => return Err(invalid_param_error!(params)),
200            },
201        })
202    }
203
204    #[allow(unreachable_patterns)]
205    fn configure(&mut self, params: &CodecParameters) -> Result<()> {
206        let video_params = (&params.media).try_into()?;
207        let encoder_params = (&params.codec).try_into()?;
208        self.video.update(&video_params);
209        self.encoder.update(&encoder_params);
210        Ok(())
211    }
212
213    fn configure_with_option(&mut self, key: &str, value: &Variant) -> Result<()> {
214        self.video.update_with_option(key, value);
215        self.encoder.update_with_option(key, value);
216        Ok(())
217    }
218}
219
220pub trait Encoder<T: CodecSpec>: Codec<T> + Send + Sync {
221    fn init(&mut self, _config: &T) -> Result<()> {
222        Ok(())
223    }
224    fn send_frame(&mut self, config: &T, pool: Option<&Arc<BufferPool>>, frame: SharedFrame<Frame<'static, T::FrameDescriptor>>) -> Result<()>;
225    fn receive_packet(&mut self, config: &T, pool: Option<&Arc<BufferPool>>) -> Result<Packet<'static>>;
226    fn flush(&mut self, config: &T) -> Result<()>;
227}
228
229pub trait EncoderBuilder<T: CodecSpec>: CodecBuilder<T> {
230    fn new_encoder(&self, id: CodecID, params: &CodecParameters, options: Option<&Variant>) -> Result<Box<dyn Encoder<T>>>;
231}