media_codec_opus/
decoder.rs1use std::{collections::VecDeque, os::raw::c_int, sync::Arc};
2
3use bytemuck;
4use ctor::ctor;
5use media_codec::{
6 codec::{Codec, CodecBuilder, CodecID},
7 decoder::{register_decoder, AudioDecoderConfiguration, AudioDecoderParameters, Decoder, DecoderBuilder},
8 packet::Packet,
9 CodecInfomation,
10};
11use media_core::{
12 audio::{AudioFrameDescriptor, SampleFormat},
13 error::Error,
14 frame::Frame,
15 invalid_param_error, unsupported_error,
16 variant::Variant,
17 Result,
18};
19
20use crate::{opus_error_string, opus_sys};
21
22struct OpusDecoder {
23 decoder: *mut opus_sys::OpusDecoder,
24 pending: VecDeque<Frame<'static>>,
25}
26
27unsafe impl Send for OpusDecoder {}
28unsafe impl Sync for OpusDecoder {}
29
30impl Codec<AudioDecoderConfiguration> for OpusDecoder {
31 fn configure(&mut self, _parameters: Option<&AudioDecoderParameters>, _options: Option<&Variant>) -> Result<()> {
32 Ok(())
33 }
34
35 fn set_option(&mut self, _key: &str, _value: &Variant) -> Result<()> {
36 Ok(())
37 }
38}
39
40impl Decoder<AudioDecoderConfiguration> for OpusDecoder {
41 fn send_packet(&mut self, config: &AudioDecoderConfiguration, packet: &Packet) -> Result<()> {
42 let audio_params = &config.audio;
43 let sample_rate = audio_params.sample_rate.ok_or(invalid_param_error!(config))?.get();
44 let sample_format = if audio_params.format.ok_or(invalid_param_error!(config))? == SampleFormat::F32 {
45 SampleFormat::F32
46 } else {
47 SampleFormat::S16
48 };
49 let channel_layout = audio_params.channel_layout.as_ref().ok_or(invalid_param_error!(config))?;
50 let max_samples = sample_rate * 120 / 1000;
52
53 let desc = AudioFrameDescriptor::try_from_channel_layout(sample_format, max_samples, sample_rate, channel_layout.clone())?;
54 let mut frame = Frame::audio_creator().create_with_descriptor(desc)?;
55
56 let ret = if let Ok(mut guard) = frame.map_mut() {
57 let mut planes = guard.planes_mut().unwrap();
58 let packet_data = packet.data();
59
60 if sample_format == SampleFormat::F32 {
61 let data = bytemuck::cast_slice_mut::<u8, f32>(planes.plane_data_mut(0).unwrap());
62 unsafe {
63 opus_sys::opus_decode_float(
64 self.decoder,
65 packet_data.as_ptr(),
66 packet_data.len() as i32,
67 data.as_mut_ptr(),
68 max_samples as i32,
69 false as i32,
70 )
71 }
72 } else {
73 let data = bytemuck::cast_slice_mut::<u8, i16>(planes.plane_data_mut(0).unwrap());
74 unsafe {
75 opus_sys::opus_decode(
76 self.decoder,
77 packet_data.as_ptr(),
78 packet_data.len() as i32,
79 data.as_mut_ptr(),
80 max_samples as i32,
81 false as i32,
82 )
83 }
84 }
85 } else {
86 return Err(Error::Invalid("not writable".to_string()));
87 };
88
89 let samples = if ret < 0 {
90 return Err(Error::Failed(opus_error_string(ret)));
91 } else {
92 ret as u32
93 };
94
95 frame.truncate(samples)?;
96
97 self.pending.push_back(frame);
98
99 Ok(())
100 }
101
102 fn receive_frame(&mut self, _config: &AudioDecoderConfiguration) -> Result<Frame<'static>> {
103 self.pending.pop_front().ok_or(Error::Again("no frame available".to_string()))
104 }
105
106 fn receive_frame_borrowed(&mut self, _config: &AudioDecoderConfiguration) -> Result<Frame<'_>> {
107 Err(Error::Unsupported("borrowed frame not supported".to_string()))
108 }
109
110 fn flush(&mut self, _config: &AudioDecoderConfiguration) -> Result<()> {
111 unsafe { opus_sys::opus_decoder_ctl(self.decoder, opus_sys::OPUS_RESET_STATE) };
112 Ok(())
113 }
114}
115
116impl Drop for OpusDecoder {
117 fn drop(&mut self) {
118 unsafe { opus_sys::opus_decoder_destroy(self.decoder) }
119 }
120}
121
122impl OpusDecoder {
123 pub fn new(codec_id: CodecID, parameters: &AudioDecoderParameters, _options: Option<&Variant>) -> Result<Self> {
124 if codec_id != CodecID::Opus {
125 return Err(unsupported_error!(codec_id));
126 }
127
128 let audio_params = ¶meters.audio;
129 let sample_rate = audio_params.sample_rate.ok_or(invalid_param_error!(parameters))?.get() as opus_sys::opus_int32;
130 let channels = audio_params.channel_layout.as_ref().ok_or(invalid_param_error!(parameters))?.channels.get() as c_int;
131
132 let mut ret = 0;
133 let decoder = unsafe { opus_sys::opus_decoder_create(sample_rate, channels, &mut ret) };
134 if decoder.is_null() || ret != opus_sys::OPUS_OK {
135 return Err(Error::CreationFailed(opus_error_string(ret)));
136 }
137
138 Ok(OpusDecoder {
139 decoder,
140 pending: VecDeque::new(),
141 })
142 }
143}
144
145const CODEC_NAME: &str = "opus-dec";
146
147pub struct OpusDecoderBuilder;
148
149impl DecoderBuilder<AudioDecoderConfiguration> for OpusDecoderBuilder {
150 fn new_decoder(
151 &self,
152 codec_id: CodecID,
153 parameters: &AudioDecoderParameters,
154 options: Option<&Variant>,
155 ) -> Result<Box<dyn Decoder<AudioDecoderConfiguration>>> {
156 Ok(Box::new(OpusDecoder::new(codec_id, parameters, options)?))
157 }
158}
159
160impl CodecBuilder<AudioDecoderConfiguration> for OpusDecoderBuilder {
161 fn id(&self) -> CodecID {
162 CodecID::Opus
163 }
164
165 fn name(&self) -> &'static str {
166 CODEC_NAME
167 }
168}
169
170impl CodecInfomation for OpusDecoder {
171 fn id(&self) -> CodecID {
172 CodecID::Opus
173 }
174
175 fn name(&self) -> &'static str {
176 CODEC_NAME
177 }
178}
179
180#[ctor]
181fn initialize() {
182 register_decoder(Arc::new(OpusDecoderBuilder), false);
183}