use crate::{sys, mem, ErrorCode};
use core::marker;
use core::convert::TryInto;
pub fn pad_packet(input: &mut [u8], new_len: usize) -> Result<(), ErrorCode> {
let len = match input.len().try_into() {
Ok(data_len) => data_len,
Err(_) => return Err(ErrorCode::bad_arg()),
};
let new_len = match new_len.try_into() {
Ok(data_len) => data_len,
Err(_) => return Err(ErrorCode::bad_arg()),
};
let data = input.as_mut_ptr();
let result = unsafe {
sys::opus_packet_pad(data, len, new_len)
};
map_sys_error!(result => ())
}
pub fn unpad_packet(input: &mut [u8]) -> Result<usize, ErrorCode> {
let len = match input.len().try_into() {
Ok(data_len) => data_len,
Err(_) => return Err(ErrorCode::bad_arg()),
};
let data = input.as_mut_ptr();
let result = unsafe {
sys::opus_packet_unpad(data, len)
};
map_sys_error!(result => result as usize)
}
#[repr(transparent)]
pub struct Repacketizer {
inner: mem::Unique<sys::OpusRepacketizer>
}
impl Repacketizer {
pub fn new() -> Result<Self, ErrorCode> {
let size = unsafe {
sys::opus_repacketizer_get_size()
};
if size == 0 {
return Err(ErrorCode::Internal);
}
let mut this = match mem::Unique::new(size as _) {
Some(inner) => Self {
inner,
},
None => return Err(ErrorCode::AllocFail)
};
this.reset();
Ok(this)
}
#[inline(always)]
pub fn reset(&mut self) {
unsafe {
sys::opus_repacketizer_init(self.inner.as_mut());
}
}
#[inline(always)]
pub fn start<'a, 'buf>(&'a mut self) -> OngoingRepacketizer<'a, 'buf> {
OngoingRepacketizer {
inner: self,
_buf_lifetime: marker::PhantomData
}
}
pub fn combine_all(&mut self, bufs: &[&[u8]], out: &mut [mem::MaybeUninit<u8>]) -> Result<usize, ErrorCode> {
let mut state = self.start();
for buf in bufs {
state.add_packet(buf)?;
}
state.create_full_packet(out)
}
}
unsafe impl Send for Repacketizer {}
#[repr(transparent)]
pub struct OngoingRepacketizer<'a, 'buf> {
inner: &'a mut Repacketizer,
_buf_lifetime: marker::PhantomData<&'buf [u8]>
}
impl<'a, 'buf> OngoingRepacketizer<'a, 'buf> {
#[inline(always)]
fn as_state(&self) -> &mem::Unique<sys::OpusRepacketizer> {
&self.inner.inner
}
#[inline(always)]
fn as_state_mut(&mut self) -> &mut mem::Unique<sys::OpusRepacketizer> {
&mut self.inner.inner
}
#[inline(always)]
pub fn reset(&mut self) {
self.inner.reset();
}
#[inline(always)]
pub fn get_nb_frames(&self) -> u32 {
unsafe {
sys::opus_repacketizer_get_nb_frames(self.as_state().as_pseudo_mut()) as _
}
}
pub fn add_packet(&mut self, input: &'buf [u8]) -> Result<(), ErrorCode> {
let len = match input.len().try_into() {
Ok(data_len) => data_len,
Err(_) => return Err(ErrorCode::bad_arg()),
};
let data = input.as_ptr();
let result = unsafe {
sys::opus_repacketizer_cat(self.as_state_mut().as_mut(), data, len)
};
map_sys_error!(result => ())
}
#[inline(always)]
pub fn with_packet<'new_buf>(self, input: &'new_buf [u8]) -> Result<OngoingRepacketizer<'a, 'new_buf>, ErrorCode> where 'buf: 'new_buf {
let mut new = self;
new.add_packet(input)?;
Ok(new)
}
pub fn create_packet(&self, range: (u32, u32), out: &mut [mem::MaybeUninit<u8>]) -> Result<usize, ErrorCode> {
let begin = match range.0.try_into() {
Ok(begin) => begin,
Err(_) => return Err(ErrorCode::bad_arg()),
};
let end = match range.1.try_into() {
Ok(end) => end,
Err(_) => return Err(ErrorCode::bad_arg()),
};
let out_len = match out.len().try_into() {
Ok(out_len) => out_len,
Err(_) => return Err(ErrorCode::bad_arg()),
};
let result = unsafe {
sys::opus_repacketizer_out_range(self.as_state().as_pseudo_mut(), begin, end, out.as_mut_ptr() as _, out_len)
};
map_sys_error!(result => result as _)
}
#[inline(always)]
pub fn create_full_packet(&self, out: &mut [mem::MaybeUninit<u8>]) -> Result<usize, ErrorCode> {
let out_len = match out.len().try_into() {
Ok(out_len) => out_len,
Err(_) => return Err(ErrorCode::bad_arg()),
};
let result = unsafe {
sys::opus_repacketizer_out(self.as_state().as_pseudo_mut(), out.as_mut_ptr() as _, out_len)
};
map_sys_error!(result => result as _)
}
}
impl<'a, 'buf> Drop for OngoingRepacketizer<'a, 'buf> {
#[inline(always)]
fn drop(&mut self) {
self.inner.reset();
}
}