mirror of
https://github.com/rustdesk/magnum-opus.git
synced 2025-07-04 00:36:12 +00:00
Add macros to simplify CTL implementations
Also fixes a bug where get_bandwidth CTLs were not returning the correct values.
This commit is contained in:
parent
2ae7540582
commit
c888c71feb
107
src/lib.rs
107
src/lib.rs
@ -137,9 +137,26 @@ 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! ctl {
|
||||||
|
($f:ident, $this:ident, $ctl:ident, $($rest:expr),*) => {
|
||||||
|
check(
|
||||||
|
concat!(stringify!($f), "(", stringify!($ctl), ")"),
|
||||||
|
unsafe {
|
||||||
|
ffi::$f($this.ptr, $ctl, $($rest),*)
|
||||||
|
}
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Encoder
|
// Encoder
|
||||||
|
|
||||||
|
macro_rules! enc_ctl {
|
||||||
|
($this:ident, $ctl:ident $(, $rest:expr)*) => {
|
||||||
|
ctl!(opus_encoder_ctl, $this, $ctl, $($rest),*)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An Opus encoder with associated state.
|
/// An Opus encoder with associated state.
|
||||||
pub struct Encoder {
|
pub struct Encoder {
|
||||||
ptr: *mut ffi::OpusEncoder,
|
ptr: *mut ffi::OpusEncoder,
|
||||||
@ -196,51 +213,55 @@ impl Encoder {
|
|||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------
|
||||||
|
// Generic CTLs
|
||||||
|
|
||||||
/// Reset the codec state to be equivalent to a freshly initialized state.
|
/// Reset the codec state to be equivalent to a freshly initialized state.
|
||||||
pub fn reset_state(&mut self) -> Result<()> {
|
pub fn reset_state(&mut self) -> Result<()> {
|
||||||
check("opus_encoder_ctl(OPUS_RESET_STATE)", unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_RESET_STATE) })
|
enc_ctl!(self, OPUS_RESET_STATE);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the final range of the codec's entropy coder.
|
/// Get the final range of the codec's entropy coder.
|
||||||
pub fn get_final_range(&mut self) -> Result<u32> {
|
pub fn get_final_range(&mut self) -> Result<u32> {
|
||||||
let mut value: u32 = 0;
|
let mut value: u32 = 0;
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_FINAL_RANGE, &mut value) };
|
enc_ctl!(self, OPUS_GET_FINAL_RANGE, &mut value);
|
||||||
try!(check("opus_encoder_ctl(OPUS_GET_FINAL_RANGE)", result));
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the encoder's configured bandpass.
|
/// Get the encoder's configured bandpass.
|
||||||
pub fn get_bandwidth(&mut self) -> Result<Bandwidth> {
|
pub fn get_bandwidth(&mut self) -> Result<Bandwidth> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_BANDWIDTH, &mut value) };
|
enc_ctl!(self, OPUS_GET_BANDWIDTH, &mut value);
|
||||||
try!(check("opus_encoder_ctl(OPUS_GET_BANDWIDTH)", result));
|
Bandwidth::from_int(value).ok_or_else(||
|
||||||
Bandwidth::from_int(result).ok_or_else(|| Error::from_code("opus_encoder_ctl(OPUS_GET_BANDWIDTH)", ffi::OPUS_BAD_ARG))
|
Error::from_code("opus_encoder_ctl(OPUS_GET_BANDWIDTH)", ffi::OPUS_BAD_ARG))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the samping rate the encoder was intialized with.
|
/// Get the samping rate the encoder was intialized with.
|
||||||
pub fn get_sample_rate(&mut self) -> Result<u32> {
|
pub fn get_sample_rate(&mut self) -> Result<u32> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_SAMPLE_RATE, &mut value) };
|
enc_ctl!(self, OPUS_GET_SAMPLE_RATE, &mut value);
|
||||||
try!(check("opus_encoder_ctl(OPUS_GET_SAMPLE_RATE)", result));
|
|
||||||
Ok(value as u32)
|
Ok(value as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------
|
||||||
|
// Encoder CTLs
|
||||||
|
|
||||||
/// Set the encoder's bitrate.
|
/// Set the encoder's bitrate.
|
||||||
pub fn set_bitrate(&mut self, value: Bitrate) -> Result<()> {
|
pub fn set_bitrate(&mut self, value: Bitrate) -> Result<()> {
|
||||||
let val: i32 = match value {
|
let value: i32 = match value {
|
||||||
Bitrate::Auto => OPUS_AUTO,
|
Bitrate::Auto => OPUS_AUTO,
|
||||||
Bitrate::Max => OPUS_BITRATE_MAX,
|
Bitrate::Max => OPUS_BITRATE_MAX,
|
||||||
Bitrate::Bits(b) => b,
|
Bitrate::Bits(b) => b,
|
||||||
};
|
};
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_SET_BITRATE, val) };
|
enc_ctl!(self, OPUS_SET_BITRATE, value);
|
||||||
check("opus_encoder_ctl(OPUS_SET_BITRATE)", result)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the encoder's bitrate.
|
/// Get the encoder's bitrate.
|
||||||
pub fn get_bitrate(&mut self) -> Result<Bitrate> {
|
pub fn get_bitrate(&mut self) -> Result<Bitrate> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_BITRATE, &mut value) };
|
enc_ctl!(self, OPUS_GET_BITRATE, &mut value);
|
||||||
try!(check("opus_encoder_ctl(OPUS_GET_BITRATE)", result));
|
|
||||||
Ok(match value {
|
Ok(match value {
|
||||||
OPUS_AUTO => Bitrate::Auto,
|
OPUS_AUTO => Bitrate::Auto,
|
||||||
OPUS_BITRATE_MAX => Bitrate::Max,
|
OPUS_BITRATE_MAX => Bitrate::Max,
|
||||||
@ -250,38 +271,35 @@ impl Encoder {
|
|||||||
|
|
||||||
/// Configures the encoder's use of inband forward error correction (FEC).
|
/// Configures the encoder's use of inband forward error correction (FEC).
|
||||||
pub fn set_inband_fec(&mut self, value: bool) -> Result<()> {
|
pub fn set_inband_fec(&mut self, value: bool) -> Result<()> {
|
||||||
let value = if value { 1 } else { 0 };
|
let value: i32 = if value { 1 } else { 0 };
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_SET_INBAND_FEC, value) };
|
enc_ctl!(self, OPUS_SET_INBAND_FEC, value);
|
||||||
check("opus_encoder_ctl(OPUS_SET_INBAND_FEC)", result)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets encoder's configured use of inband forward error correction.
|
/// Gets encoder's configured use of inband forward error correction.
|
||||||
pub fn get_inband_fec(&mut self) -> Result<bool> {
|
pub fn get_inband_fec(&mut self) -> Result<bool> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_INBAND_FEC, &mut value) };
|
enc_ctl!(self, OPUS_GET_INBAND_FEC, &mut value);
|
||||||
try!(check("opus_encoder_ctl(OPUS_GET_INBAND_FEC)", result));
|
|
||||||
Ok(value != 0)
|
Ok(value != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the encoder's expected packet loss percentage.
|
/// Sets the encoder's expected packet loss percentage.
|
||||||
pub fn set_packet_loss_perc(&mut self, value: i32) -> Result<()> {
|
pub fn set_packet_loss_perc(&mut self, value: i32) -> Result<()> {
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_SET_PACKET_LOSS_PERC, value) };
|
enc_ctl!(self, OPUS_SET_PACKET_LOSS_PERC, value);
|
||||||
check("opus_encoder_ctl(OPUS_SET_PACKET_LOSS_PERC)", result)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the encoder's expected packet loss percentage.
|
/// Gets the encoder's expected packet loss percentage.
|
||||||
pub fn get_packet_loss_perc(&mut self) -> Result<i32> {
|
pub fn get_packet_loss_perc(&mut self) -> Result<i32> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_PACKET_LOSS_PERC, &mut value) };
|
enc_ctl!(self, OPUS_GET_PACKET_LOSS_PERC, &mut value);
|
||||||
try!(check("opus_encoder_ctl(OPUS_GET_PACKET_LOSS_PERC)", result));
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the total samples of delay added by the entire codec.
|
/// Gets the total samples of delay added by the entire codec.
|
||||||
pub fn get_lookahead(&mut self) -> Result<i32> {
|
pub fn get_lookahead(&mut self) -> Result<i32> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let result = unsafe { ffi::opus_encoder_ctl(self.ptr, OPUS_GET_LOOKAHEAD, &mut value) };
|
enc_ctl!(self, OPUS_GET_LOOKAHEAD, &mut value);
|
||||||
try!(check("opus_encoder_ctl(OPUS_GET_LOOKAHEAD)", result));
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,29 +315,18 @@ impl Drop for Encoder {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Decoder
|
// Decoder
|
||||||
|
|
||||||
|
macro_rules! dec_ctl {
|
||||||
|
($this:ident, $ctl:ident $(, $rest:expr)*) => {
|
||||||
|
ctl!(opus_decoder_ctl, $this, $ctl, $($rest),*)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An Opus decoder with associated state.
|
/// An Opus decoder with associated state.
|
||||||
pub struct Decoder {
|
pub struct Decoder {
|
||||||
ptr: *mut ffi::OpusDecoder,
|
ptr: *mut ffi::OpusDecoder,
|
||||||
channels: Channels,
|
channels: Channels,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! ctl {
|
|
||||||
($f:ident, $this:ident, $ctl:ident, $($rest:expr),*) => {
|
|
||||||
check(
|
|
||||||
concat!(stringify!($f), "(", stringify!($ctl), ")"),
|
|
||||||
unsafe {
|
|
||||||
ffi::$f($this.ptr, $ctl, $($rest),*)
|
|
||||||
}
|
|
||||||
)?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! dec_ctl {
|
|
||||||
($this:ident, $ctl:ident, $($rest:expr),*) => {
|
|
||||||
ctl!(opus_decoder_ctl, $this, $ctl, $($rest),*)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decoder {
|
impl Decoder {
|
||||||
/// Create and initialize a decoder.
|
/// Create and initialize a decoder.
|
||||||
pub fn new(sample_rate: u32, channels: Channels) -> Result<Decoder> {
|
pub fn new(sample_rate: u32, channels: Channels) -> Result<Decoder> {
|
||||||
@ -363,32 +370,34 @@ impl Decoder {
|
|||||||
Ok(len as usize)
|
Ok(len as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------
|
||||||
|
// Generic CTLs
|
||||||
|
|
||||||
/// Reset the codec state to be equivalent to a freshly initialized state.
|
/// Reset the codec state to be equivalent to a freshly initialized state.
|
||||||
pub fn reset_state(&mut self) -> Result<()> {
|
pub fn reset_state(&mut self) -> Result<()> {
|
||||||
check("opus_decoder_ctl(OPUS_RESET_STATE)", unsafe { ffi::opus_decoder_ctl(self.ptr, OPUS_RESET_STATE) })
|
dec_ctl!(self, OPUS_RESET_STATE);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the final range of the codec's entropy coder.
|
/// Get the final range of the codec's entropy coder.
|
||||||
pub fn get_final_range(&mut self) -> Result<u32> {
|
pub fn get_final_range(&mut self) -> Result<u32> {
|
||||||
let mut value: u32 = 0;
|
let mut value: u32 = 0;
|
||||||
let result = unsafe { ffi::opus_decoder_ctl(self.ptr, OPUS_GET_FINAL_RANGE, &mut value) };
|
dec_ctl!(self, OPUS_GET_FINAL_RANGE, &mut value);
|
||||||
try!(check("opus_decoder_ctl(OPUS_GET_FINAL_RANGE)", result));
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the decoder's last bandpass.
|
/// Get the decoder's last bandpass.
|
||||||
pub fn get_bandwidth(&mut self) -> Result<Bandwidth> {
|
pub fn get_bandwidth(&mut self) -> Result<Bandwidth> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let result = unsafe { ffi::opus_decoder_ctl(self.ptr, OPUS_GET_BANDWIDTH, &mut value) };
|
dec_ctl!(self, OPUS_GET_BANDWIDTH, &mut value);
|
||||||
try!(check("opus_decoder_ctl(OPUS_GET_BANDWIDTH)", result));
|
Bandwidth::from_int(value).ok_or_else(||
|
||||||
Bandwidth::from_int(result).ok_or_else(|| Error::from_code("opus_decoder_ctl(OPUS_GET_BANDWIDTH)", ffi::OPUS_BAD_ARG))
|
Error::from_code("opus_decoder_ctl(OPUS_GET_BANDWIDTH)", ffi::OPUS_BAD_ARG))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the samping rate the decoder was intialized with.
|
/// Get the samping rate the decoder was intialized with.
|
||||||
pub fn get_sample_rate(&mut self) -> Result<u32> {
|
pub fn get_sample_rate(&mut self) -> Result<u32> {
|
||||||
let mut value: i32 = 0;
|
let mut value: i32 = 0;
|
||||||
let result = unsafe { ffi::opus_decoder_ctl(self.ptr, OPUS_GET_SAMPLE_RATE, &mut value) };
|
dec_ctl!(self, OPUS_GET_SAMPLE_RATE, &mut value);
|
||||||
try!(check("opus_decoder_ctl(OPUS_GET_SAMPLE_RATE)", result));
|
|
||||||
Ok(value as u32)
|
Ok(value as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user