Skip to content

Commit ccafed9

Browse files
committed
refactor: make demo decode able to initialize without malloc (use Box instead)
1 parent 1a57ef0 commit ccafed9

File tree

4 files changed

+125
-78
lines changed

4 files changed

+125
-78
lines changed

src/src/opus_decoder.rs

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,45 @@ pub struct OpusDecoder {
6363
pub(crate) softclip_mem: [opus_val16; 2],
6464
pub(crate) rangeFinal: u32,
6565
}
66+
impl OpusDecoder {
67+
pub unsafe fn new(Fs: i32, channels: usize) -> Result<OpusDecoder, i32> {
68+
if Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000
69+
|| channels != 1 && channels != 2
70+
{
71+
return Err(OPUS_BAD_ARG);
72+
}
73+
74+
let mut st = OpusDecoder {
75+
celt_dec: celt_decoder_init(Fs, channels),
76+
silk_dec: silk_InitDecoder(),
77+
channels: channels as i32,
78+
Fs,
79+
DecControl: silk_DecControlStruct {
80+
nChannelsAPI: channels as i32,
81+
nChannelsInternal: 0,
82+
API_sampleRate: Fs,
83+
internalSampleRate: 0,
84+
payloadSize_ms: 0,
85+
prevPitchLag: 0,
86+
},
87+
decode_gain: 0,
88+
stream_channels: channels as i32,
89+
bandwidth: 0,
90+
mode: 0,
91+
prev_mode: 0,
92+
frame_size: Fs / 400,
93+
prev_redundancy: 0,
94+
last_packet_duration: 0,
95+
softclip_mem: [0.0; 2],
96+
rangeFinal: 0,
97+
};
98+
99+
opus_custom_decoder_ctl!(&mut st.celt_dec, CELT_SET_SIGNALLING_REQUEST, 0);
100+
101+
Ok(st)
102+
}
103+
}
104+
66105
unsafe fn validate_opus_decoder(st: &OpusDecoder) {
67106
assert!((*st).channels == 1 || (*st).channels == 2);
68107
assert!(
@@ -94,34 +133,27 @@ unsafe fn validate_opus_decoder(st: &OpusDecoder) {
94133
);
95134
assert!((*st).stream_channels == 1 || (*st).stream_channels == 2);
96135
}
97-
pub fn opus_decoder_get_size(_channels: i32) -> usize {
98-
align(core::mem::size_of::<OpusDecoder>() as _) as usize
136+
#[deprecated]
137+
pub fn opus_decoder_get_size(channels: i32) -> i32 {
138+
if channels < 1 || channels > 2 {
139+
return 0;
140+
}
141+
align(core::mem::size_of::<OpusDecoder>() as _)
99142
}
143+
#[deprecated]
100144
pub unsafe fn opus_decoder_init(st: *mut OpusDecoder, Fs: i32, channels: i32) -> i32 {
101-
if Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000
102-
|| channels != 1 && channels != 2
103-
{
104-
return OPUS_BAD_ARG;
145+
match OpusDecoder::new(Fs, channels as usize) {
146+
Ok(dec) => {
147+
*st = dec;
148+
return OPUS_OK;
149+
}
150+
Err(err) => {
151+
return err;
152+
}
105153
}
106-
memset(
107-
st as *mut i8 as *mut core::ffi::c_void,
108-
0,
109-
(opus_decoder_get_size(channels) as u64).wrapping_mul(::core::mem::size_of::<i8>() as u64),
110-
);
111-
(*st).channels = channels;
112-
(*st).stream_channels = (*st).channels;
113-
(*st).Fs = Fs;
114-
(*st).DecControl.API_sampleRate = (*st).Fs;
115-
(*st).DecControl.nChannelsAPI = (*st).channels;
116-
(*st).silk_dec = silk_InitDecoder();
117-
(*st).celt_dec = celt_decoder_init(Fs, channels as usize);
118-
opus_custom_decoder_ctl!(&mut (*st).celt_dec, CELT_SET_SIGNALLING_REQUEST, 0);
119-
(*st).prev_mode = 0;
120-
(*st).frame_size = Fs / 400;
121-
return OPUS_OK;
122154
}
155+
#[deprecated]
123156
pub unsafe fn opus_decoder_create(Fs: i32, channels: i32, error: *mut i32) -> *mut OpusDecoder {
124-
let mut ret: i32 = 0;
125157
let mut st: *mut OpusDecoder = 0 as *mut OpusDecoder;
126158
if Fs != 48000 && Fs != 24000 && Fs != 16000 && Fs != 12000 && Fs != 8000
127159
|| channels != 1 && channels != 2
@@ -138,7 +170,7 @@ pub unsafe fn opus_decoder_create(Fs: i32, channels: i32, error: *mut i32) -> *m
138170
}
139171
return NULL as *mut OpusDecoder;
140172
}
141-
ret = opus_decoder_init(st, Fs, channels);
173+
let ret = opus_decoder_init(st, Fs, channels);
142174
if !error.is_null() {
143175
*error = ret;
144176
}
@@ -999,6 +1031,7 @@ macro_rules! opus_decoder_ctl {
9991031
opus_decoder_ctl!($st, $request,)
10001032
};
10011033
}
1034+
#[deprecated]
10021035
pub unsafe fn opus_decoder_destroy(st: *mut OpusDecoder) {
10031036
free(st as *mut core::ffi::c_void);
10041037
}

src/src/opus_multistream_decoder.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use crate::src::opus_multistream::{
4343
use crate::src::opus_private::align;
4444
use crate::varargs::VarArgs;
4545
use crate::{
46-
opus_decoder_ctl, opus_decoder_get_size, opus_decoder_init, opus_multistream_decoder_ctl,
46+
opus_decoder_ctl, opus_decoder_get_size, opus_multistream_decoder_ctl,
4747
opus_packet_get_nb_samples, OpusDecoder,
4848
};
4949

@@ -71,7 +71,6 @@ pub unsafe fn opus_multistream_decoder_init(
7171
mapping: *const u8,
7272
) -> i32 {
7373
let mut i: i32 = 0;
74-
let mut ret: i32 = 0;
7574
let mut ptr: *mut i8 = 0 as *mut i8;
7675
if channels > 255
7776
|| channels < 1
@@ -99,18 +98,28 @@ pub unsafe fn opus_multistream_decoder_init(
9998
let mono_size = opus_decoder_get_size(1);
10099
i = 0;
101100
while i < (*st).layout.nb_coupled_streams {
102-
ret = opus_decoder_init(ptr as *mut OpusDecoder, Fs, 2);
103-
if ret != OPUS_OK {
104-
return ret;
101+
match OpusDecoder::new(Fs, 2) {
102+
Err(e) => {
103+
return e;
104+
}
105+
Ok(dec) => {
106+
*(ptr as *mut OpusDecoder) = dec;
107+
}
105108
}
109+
106110
ptr = ptr.offset(align(coupled_size as _) as isize);
107111
i += 1;
108112
}
109113
while i < (*st).layout.nb_streams {
110-
ret = opus_decoder_init(ptr as *mut OpusDecoder, Fs, 1);
111-
if ret != OPUS_OK {
112-
return ret;
114+
match OpusDecoder::new(Fs, 2) {
115+
Err(e) => {
116+
return e;
117+
}
118+
Ok(dec) => {
119+
*(ptr as *mut OpusDecoder) = dec;
120+
}
113121
}
122+
114123
ptr = ptr.offset(align(mono_size as _) as isize);
115124
i += 1;
116125
}

unsafe-libopus-tools/src/demo/backend.rs

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ pub(crate) trait OpusBackendTrait {
1212
Fs: i32,
1313
channels: i32,
1414
application: i32,
15-
error: *mut i32,
16-
) -> Self::Encoder;
15+
) -> Result<Self::Encoder, i32>;
1716
unsafe fn opus_encoder_ctl_impl(st: &mut Self::Encoder, request: i32, args: VarArgs) -> i32;
1817
unsafe fn opus_encode(
1918
st: &mut Self::Encoder,
@@ -24,7 +23,7 @@ pub(crate) trait OpusBackendTrait {
2423
) -> i32;
2524
unsafe fn opus_encoder_destroy(st: Self::Encoder);
2625

27-
unsafe fn opus_decoder_create(Fs: i32, channels: i32, error: *mut i32) -> Self::Decoder;
26+
unsafe fn opus_decoder_create(Fs: i32, channels: i32) -> Result<Self::Decoder, i32>;
2827
unsafe fn opus_decode(
2928
st: &mut Self::Decoder,
3029
data: *const u8,
@@ -38,26 +37,30 @@ pub(crate) trait OpusBackendTrait {
3837
}
3938

4039
mod unsafe_libopus {
41-
use ::unsafe_libopus::varargs::VarArgs;
42-
use ::unsafe_libopus::{
43-
opus_decode, opus_decoder_create, opus_decoder_ctl_impl, opus_decoder_destroy, opus_encode,
44-
opus_encoder_create, opus_encoder_ctl_impl, opus_encoder_destroy,
40+
use unsafe_libopus::{
41+
opus_decode, opus_decoder_ctl_impl, opus_encode, opus_encoder_create,
42+
opus_encoder_ctl_impl, opus_encoder_destroy, varargs::VarArgs, OpusDecoder, OpusEncoder,
4543
};
46-
use unsafe_libopus::{OpusDecoder, OpusEncoder};
4744

4845
pub struct RustLibopusBackend;
4946

5047
impl super::OpusBackendTrait for RustLibopusBackend {
5148
type Encoder = *mut OpusEncoder;
52-
type Decoder = *mut OpusDecoder;
49+
type Decoder = Box<OpusDecoder>;
5350

5451
unsafe fn opus_encoder_create(
5552
Fs: i32,
5653
channels: i32,
5754
application: i32,
58-
error: *mut i32,
59-
) -> *mut OpusEncoder {
60-
opus_encoder_create(Fs, channels, application, error)
55+
) -> Result<*mut OpusEncoder, i32> {
56+
let mut error = 0;
57+
58+
let res = opus_encoder_create(Fs, channels, application, &mut error);
59+
if res.is_null() {
60+
Err(error)
61+
} else {
62+
Ok(res)
63+
}
6164
}
6265

6366
unsafe fn opus_encoder_ctl_impl(
@@ -82,31 +85,31 @@ mod unsafe_libopus {
8285
opus_encoder_destroy(st)
8386
}
8487

85-
unsafe fn opus_decoder_create(Fs: i32, channels: i32, error: *mut i32) -> *mut OpusDecoder {
86-
opus_decoder_create(Fs, channels, error)
88+
unsafe fn opus_decoder_create(Fs: i32, channels: i32) -> Result<Box<OpusDecoder>, i32> {
89+
OpusDecoder::new(Fs, channels as usize).map(Box::new)
8790
}
8891

8992
unsafe fn opus_decode(
90-
&mut st: &mut *mut OpusDecoder,
93+
st: &mut Box<OpusDecoder>,
9194
data: *const u8,
9295
len: i32,
9396
pcm: *mut i16,
9497
frame_size: i32,
9598
decode_fec: i32,
9699
) -> i32 {
97-
opus_decode(st, data, len, pcm, frame_size, decode_fec)
100+
opus_decode(st.as_mut(), data, len, pcm, frame_size, decode_fec)
98101
}
99102

100103
unsafe fn opus_decoder_ctl_impl(
101-
&mut st: &mut *mut OpusDecoder,
104+
st: &mut Box<OpusDecoder>,
102105
request: i32,
103106
args: VarArgs,
104107
) -> i32 {
105-
opus_decoder_ctl_impl(st, request, args)
108+
opus_decoder_ctl_impl(st.as_mut(), request, args)
106109
}
107110

108-
unsafe fn opus_decoder_destroy(st: *mut OpusDecoder) {
109-
opus_decoder_destroy(st)
111+
unsafe fn opus_decoder_destroy(st: Box<OpusDecoder>) {
112+
drop(st)
110113
}
111114
}
112115
}
@@ -130,9 +133,15 @@ mod libopus {
130133
Fs: i32,
131134
channels: i32,
132135
application: i32,
133-
error: *mut i32,
134-
) -> *mut OpusEncoder {
135-
opus_encoder_create(Fs, channels, application, error)
136+
) -> Result<*mut OpusEncoder, i32> {
137+
let mut error = 0;
138+
139+
let res = opus_encoder_create(Fs, channels, application, &mut error);
140+
if res.is_null() {
141+
Err(error)
142+
} else {
143+
Ok(res)
144+
}
136145
}
137146

138147
unsafe fn opus_encoder_ctl_impl(
@@ -163,8 +172,14 @@ mod libopus {
163172
opus_encoder_destroy(st)
164173
}
165174

166-
unsafe fn opus_decoder_create(Fs: i32, channels: i32, error: *mut i32) -> *mut OpusDecoder {
167-
opus_decoder_create(Fs, channels, error)
175+
unsafe fn opus_decoder_create(Fs: i32, channels: i32) -> Result<*mut OpusDecoder, i32> {
176+
let mut error = 0;
177+
let res = opus_decoder_create(Fs, channels, &mut error);
178+
if res.is_null() {
179+
Err(error)
180+
} else {
181+
Ok(res)
182+
}
168183
}
169184

170185
unsafe fn opus_decode(

unsafe-libopus-tools/src/demo/mod.rs

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,14 @@ fn opus_demo_encode_impl<B: OpusBackendTrait>(
103103
samples.push(i16::from_le_bytes(data.try_into().unwrap()));
104104
}
105105

106-
let mut enc = {
107-
let mut err: i32 = 0;
108-
let enc = unsafe {
109-
B::opus_encoder_create(
110-
usize::from(sampling_rate) as i32,
111-
channels as i32,
112-
application.into_opus(),
113-
&mut err,
114-
)
115-
};
116-
handle_opus_error(err, "opus_encoder_create");
117-
enc
118-
};
106+
let mut enc = unsafe {
107+
B::opus_encoder_create(
108+
usize::from(sampling_rate) as i32,
109+
channels as i32,
110+
application.into_opus(),
111+
)
112+
}
113+
.expect("opus_encoder_create failed");
119114

120115
let mut skip: i32 = 0;
121116

@@ -244,14 +239,9 @@ fn opus_demo_decode_impl<B: OpusBackendTrait>(
244239

245240
let channels: usize = channels.into();
246241

247-
let mut dec = {
248-
let mut err: i32 = 0;
249-
let dec = unsafe {
250-
B::opus_decoder_create(usize::from(sample_rate) as i32, channels as i32, &mut err)
251-
};
252-
handle_opus_error(err, "opus_decoder_create()");
253-
dec
254-
};
242+
let mut dec =
243+
unsafe { B::opus_decoder_create(usize::from(sample_rate) as i32, channels as i32) }
244+
.expect("opus_decoder_create failed");
255245

256246
if options.inbandfec {
257247
panic!("inbandfec not supported")

0 commit comments

Comments
 (0)