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