mirror of
https://github.com/rustdesk/magnum-opus.git
synced 2026-07-12 18:04:18 +00:00
Replace check calls with ffi macro
The macro stringifies the function name automatically and ensures that the error check is not skipped.
This commit is contained in:
+45
-57
@@ -170,14 +170,24 @@ pub fn version() -> &'static str {
|
|||||||
unsafe { CStr::from_ptr(ffi::opus_get_version_string()) }.to_str().unwrap()
|
unsafe { CStr::from_ptr(ffi::opus_get_version_string()) }.to_str().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! ffi {
|
||||||
|
($f:ident $(, $rest:expr)*) => {
|
||||||
|
match unsafe { ffi::$f($($rest),*) } {
|
||||||
|
code if code < 0 => return Err(Error::from_code(stringify!($f), code)),
|
||||||
|
code => code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! ctl {
|
macro_rules! ctl {
|
||||||
($f:ident, $this:ident, $ctl:ident, $($rest:expr),*) => {
|
($f:ident, $this:ident, $ctl:ident, $($rest:expr),*) => {
|
||||||
check(
|
match unsafe { ffi::$f($this.ptr, $ctl, $($rest),*) } {
|
||||||
concat!(stringify!($f), "(", stringify!($ctl), ")"),
|
code if code < 0 => return Err(Error::from_code(
|
||||||
unsafe {
|
concat!(stringify!($f), "(", stringify!($ctl), ")"),
|
||||||
ffi::$f($this.ptr, $ctl, $($rest),*)
|
code,
|
||||||
}
|
)),
|
||||||
)?
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,19 +224,17 @@ impl Encoder {
|
|||||||
|
|
||||||
/// Encode an Opus frame.
|
/// Encode an Opus frame.
|
||||||
pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
|
pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
|
||||||
let len = unsafe { ffi::opus_encode(self.ptr,
|
let len = ffi!(opus_encode, self.ptr,
|
||||||
input.as_ptr(), input.len() as c_int / self.channels as c_int,
|
input.as_ptr(), input.len() as c_int / self.channels as c_int,
|
||||||
output.as_mut_ptr(), output.len() as c_int) };
|
output.as_mut_ptr(), output.len() as c_int);
|
||||||
try!(check("opus_encode", len));
|
|
||||||
Ok(len as usize)
|
Ok(len as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode an Opus frame from floating point input.
|
/// Encode an Opus frame from floating point input.
|
||||||
pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
|
pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
|
||||||
let len = unsafe { ffi::opus_encode_float(self.ptr,
|
let len = ffi!(opus_encode_float, self.ptr,
|
||||||
input.as_ptr(), input.len() as c_int / self.channels as c_int,
|
input.as_ptr(), input.len() as c_int / self.channels as c_int,
|
||||||
output.as_mut_ptr(), output.len() as c_int) };
|
output.as_mut_ptr(), output.len() as c_int);
|
||||||
try!(check("opus_encode_float", len));
|
|
||||||
Ok(len as usize)
|
Ok(len as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,29 +384,26 @@ impl Decoder {
|
|||||||
|
|
||||||
/// Decode an Opus packet.
|
/// Decode an Opus packet.
|
||||||
pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
|
pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
|
||||||
let len = unsafe { ffi::opus_decode(self.ptr,
|
let len = ffi!(opus_decode, self.ptr,
|
||||||
input.as_ptr(), input.len() as c_int,
|
input.as_ptr(), input.len() as c_int,
|
||||||
output.as_mut_ptr(), output.len() as c_int / self.channels as c_int,
|
output.as_mut_ptr(), output.len() as c_int / self.channels as c_int,
|
||||||
fec as c_int) };
|
fec as c_int);
|
||||||
try!(check("opus_decode", len));
|
|
||||||
Ok(len as usize)
|
Ok(len as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode an Opus packet with floating point output.
|
/// Decode an Opus packet with floating point output.
|
||||||
pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
|
pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
|
||||||
let len = unsafe { ffi::opus_decode_float(self.ptr,
|
let len = ffi!(opus_decode_float, self.ptr,
|
||||||
input.as_ptr(), input.len() as c_int,
|
input.as_ptr(), input.len() as c_int,
|
||||||
output.as_mut_ptr(), output.len() as c_int / self.channels as c_int,
|
output.as_mut_ptr(), output.len() as c_int / self.channels as c_int,
|
||||||
fec as c_int) };
|
fec as c_int);
|
||||||
try!(check("opus_decode_float", len));
|
|
||||||
Ok(len as usize)
|
Ok(len as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of samples of an Opus packet.
|
/// Get the number of samples of an Opus packet.
|
||||||
pub fn get_nb_samples(&self, packet: &[u8]) -> Result<usize> {
|
pub fn get_nb_samples(&self, packet: &[u8]) -> Result<usize> {
|
||||||
let len = unsafe { ffi::opus_decoder_get_nb_samples(self.ptr,
|
let len = ffi!(opus_decoder_get_nb_samples, self.ptr,
|
||||||
packet.as_ptr(), packet.len() as i32) };
|
packet.as_ptr(), packet.len() as i32);
|
||||||
try!(check("opus_decoder_get_nb_samples", len));
|
|
||||||
Ok(len as usize)
|
Ok(len as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,7 +493,7 @@ impl Drop for Decoder {
|
|||||||
/// Analyze raw Opus packets.
|
/// Analyze raw Opus packets.
|
||||||
pub mod packet {
|
pub mod packet {
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::{ffi, check};
|
use super::ffi;
|
||||||
use std::{ptr, slice};
|
use std::{ptr, slice};
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
|
|
||||||
@@ -497,8 +502,7 @@ pub mod packet {
|
|||||||
if packet.len() < 1 {
|
if packet.len() < 1 {
|
||||||
return Err(Error::bad_arg("opus_packet_get_bandwidth"));
|
return Err(Error::bad_arg("opus_packet_get_bandwidth"));
|
||||||
}
|
}
|
||||||
let bandwidth = unsafe { ffi::opus_packet_get_bandwidth(packet.as_ptr()) };
|
let bandwidth = ffi!(opus_packet_get_bandwidth, packet.as_ptr());
|
||||||
try!(check("opus_packet_get_bandwidth", bandwidth));
|
|
||||||
Bandwidth::decode(bandwidth, "opus_packet_get_bandwidth")
|
Bandwidth::decode(bandwidth, "opus_packet_get_bandwidth")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,8 +511,7 @@ pub mod packet {
|
|||||||
if packet.len() < 1 {
|
if packet.len() < 1 {
|
||||||
return Err(Error::bad_arg("opus_packet_get_nb_channels"));
|
return Err(Error::bad_arg("opus_packet_get_nb_channels"));
|
||||||
}
|
}
|
||||||
let channels = unsafe { ffi::opus_packet_get_nb_channels(packet.as_ptr()) };
|
let channels = ffi!(opus_packet_get_nb_channels, packet.as_ptr());
|
||||||
try!(check("opus_packet_get_nb_channels", channels));
|
|
||||||
match channels {
|
match channels {
|
||||||
1 => Ok(Channels::Mono),
|
1 => Ok(Channels::Mono),
|
||||||
2 => Ok(Channels::Stereo),
|
2 => Ok(Channels::Stereo),
|
||||||
@@ -518,17 +521,15 @@ pub mod packet {
|
|||||||
|
|
||||||
/// Get the number of frames in an Opus packet.
|
/// Get the number of frames in an Opus packet.
|
||||||
pub fn get_nb_frames(packet: &[u8]) -> Result<usize> {
|
pub fn get_nb_frames(packet: &[u8]) -> Result<usize> {
|
||||||
let frames = unsafe { ffi::opus_packet_get_nb_frames(packet.as_ptr(), packet.len() as c_int) };
|
let frames = ffi!(opus_packet_get_nb_frames, packet.as_ptr(), packet.len() as c_int);
|
||||||
try!(check("opus_packet_get_nb_frames", frames));
|
|
||||||
Ok(frames as usize)
|
Ok(frames as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of samples of an Opus packet.
|
/// Get the number of samples of an Opus packet.
|
||||||
pub fn get_nb_samples(packet: &[u8], sample_rate: u32) -> Result<usize> {
|
pub fn get_nb_samples(packet: &[u8], sample_rate: u32) -> Result<usize> {
|
||||||
let frames = unsafe { ffi::opus_packet_get_nb_samples(
|
let frames = ffi!(opus_packet_get_nb_samples,
|
||||||
packet.as_ptr(), packet.len() as c_int,
|
packet.as_ptr(), packet.len() as c_int,
|
||||||
sample_rate as c_int) };
|
sample_rate as c_int);
|
||||||
try!(check("opus_packet_get_nb_samples", frames));
|
|
||||||
Ok(frames as usize)
|
Ok(frames as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -537,8 +538,8 @@ pub mod packet {
|
|||||||
if packet.len() < 1 {
|
if packet.len() < 1 {
|
||||||
return Err(Error::bad_arg("opus_packet_get_samples_per_frame"))
|
return Err(Error::bad_arg("opus_packet_get_samples_per_frame"))
|
||||||
}
|
}
|
||||||
let samples = unsafe { ffi::opus_packet_get_samples_per_frame(packet.as_ptr(), sample_rate as c_int) };
|
let samples = ffi!(opus_packet_get_samples_per_frame,
|
||||||
try!(check("opus_packet_get_samples_per_frame", samples));
|
packet.as_ptr(), sample_rate as c_int);
|
||||||
Ok(samples as usize)
|
Ok(samples as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,11 +549,10 @@ pub mod packet {
|
|||||||
let mut frames = [ptr::null(); 48];
|
let mut frames = [ptr::null(); 48];
|
||||||
let mut sizes = [0i16; 48];
|
let mut sizes = [0i16; 48];
|
||||||
let mut payload_offset: i32 = 0;
|
let mut payload_offset: i32 = 0;
|
||||||
let num_frames = unsafe { ffi::opus_packet_parse(
|
let num_frames = ffi!(opus_packet_parse,
|
||||||
packet.as_ptr(), packet.len() as c_int,
|
packet.as_ptr(), packet.len() as c_int,
|
||||||
&mut toc, frames.as_mut_ptr(),
|
&mut toc, frames.as_mut_ptr(),
|
||||||
sizes.as_mut_ptr(), &mut payload_offset) };
|
sizes.as_mut_ptr(), &mut payload_offset);
|
||||||
try!(check("opus_packet_parse", num_frames));
|
|
||||||
|
|
||||||
let mut frames_vec = Vec::with_capacity(num_frames as usize);
|
let mut frames_vec = Vec::with_capacity(num_frames as usize);
|
||||||
for i in 0..num_frames as usize {
|
for i in 0..num_frames as usize {
|
||||||
@@ -581,16 +581,14 @@ pub mod packet {
|
|||||||
/// The packet will be extended from the first `prev_len` bytes of the
|
/// The packet will be extended from the first `prev_len` bytes of the
|
||||||
/// buffer into the rest of the available space.
|
/// buffer into the rest of the available space.
|
||||||
pub fn pad(packet: &mut [u8], prev_len: usize) -> Result<usize> {
|
pub fn pad(packet: &mut [u8], prev_len: usize) -> Result<usize> {
|
||||||
let result = unsafe { ffi::opus_packet_pad(packet.as_mut_ptr(), prev_len as c_int, packet.len() as c_int) };
|
let result = ffi!(opus_packet_pad, packet.as_mut_ptr(), prev_len as c_int, packet.len() as c_int);
|
||||||
try!(check("opus_packet_pad", result));
|
|
||||||
Ok(result as usize)
|
Ok(result as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove all padding from a given Opus packet and rewrite the TOC sequence
|
/// Remove all padding from a given Opus packet and rewrite the TOC sequence
|
||||||
/// to minimize space usage.
|
/// to minimize space usage.
|
||||||
pub fn unpad(packet: &mut [u8]) -> Result<usize> {
|
pub fn unpad(packet: &mut [u8]) -> Result<usize> {
|
||||||
let result = unsafe { ffi::opus_packet_unpad(packet.as_mut_ptr(), packet.len() as c_int) };
|
let result = ffi!(opus_packet_unpad, packet.as_mut_ptr(), packet.len() as c_int);
|
||||||
try!(check("opus_packet_unpad", result));
|
|
||||||
Ok(result as usize)
|
Ok(result as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -676,9 +674,9 @@ pub struct RepacketizerState<'rp, 'buf> {
|
|||||||
impl<'rp, 'buf> RepacketizerState<'rp, 'buf> {
|
impl<'rp, 'buf> RepacketizerState<'rp, 'buf> {
|
||||||
/// Add a packet to the current repacketizer state.
|
/// Add a packet to the current repacketizer state.
|
||||||
pub fn cat(&mut self, packet: &'buf [u8]) -> Result<()> {
|
pub fn cat(&mut self, packet: &'buf [u8]) -> Result<()> {
|
||||||
let result = unsafe { ffi::opus_repacketizer_cat(self.rp.ptr,
|
ffi!(opus_repacketizer_cat, self.rp.ptr,
|
||||||
packet.as_ptr(), packet.len() as c_int) };
|
packet.as_ptr(), packet.len() as c_int);
|
||||||
check("opus_repacketizer_cat", result)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a packet to the current repacketizer state, moving it.
|
/// Add a packet to the current repacketizer state, moving it.
|
||||||
@@ -699,9 +697,8 @@ impl<'rp, 'buf> RepacketizerState<'rp, 'buf> {
|
|||||||
///
|
///
|
||||||
/// All previously submitted frames are used.
|
/// All previously submitted frames are used.
|
||||||
pub fn out(&mut self, buffer: &mut [u8]) -> Result<usize> {
|
pub fn out(&mut self, buffer: &mut [u8]) -> Result<usize> {
|
||||||
let result = unsafe { ffi::opus_repacketizer_out(self.rp.ptr,
|
let result = ffi!(opus_repacketizer_out, self.rp.ptr,
|
||||||
buffer.as_mut_ptr(), buffer.len() as c_int) };
|
buffer.as_mut_ptr(), buffer.len() as c_int);
|
||||||
try!(check("opus_repacketizer_out", result));
|
|
||||||
Ok(result as usize)
|
Ok(result as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -710,10 +707,9 @@ impl<'rp, 'buf> RepacketizerState<'rp, 'buf> {
|
|||||||
///
|
///
|
||||||
/// The `end` index should not exceed the value of `get_nb_frames()`.
|
/// The `end` index should not exceed the value of `get_nb_frames()`.
|
||||||
pub fn out_range(&mut self, begin: usize, end: usize, buffer: &mut [u8]) -> Result<usize> {
|
pub fn out_range(&mut self, begin: usize, end: usize, buffer: &mut [u8]) -> Result<usize> {
|
||||||
let result = unsafe { ffi::opus_repacketizer_out_range(self.rp.ptr,
|
let result = ffi!(opus_repacketizer_out_range, self.rp.ptr,
|
||||||
begin as c_int, end as c_int,
|
begin as c_int, end as c_int,
|
||||||
buffer.as_mut_ptr(), buffer.len() as c_int) };
|
buffer.as_mut_ptr(), buffer.len() as c_int);
|
||||||
try!(check("opus_repacketizer_out_range", result));
|
|
||||||
Ok(result as usize)
|
Ok(result as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -767,11 +763,3 @@ impl std::error::Error for Error {
|
|||||||
self.code.description()
|
self.code.description()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check(what: &'static str, code: c_int) -> Result<()> {
|
|
||||||
if code < 0 {
|
|
||||||
Err(Error::from_code(what, code))
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user