opus_codec/
repacketizer.rs1use crate::bindings::{
4 OpusRepacketizer, opus_repacketizer_cat, opus_repacketizer_create, opus_repacketizer_destroy,
5 opus_repacketizer_get_nb_frames, opus_repacketizer_get_size, opus_repacketizer_init,
6 opus_repacketizer_out, opus_repacketizer_out_range,
7};
8use crate::error::{Error, Result};
9use crate::{AlignedBuffer, Ownership, RawHandle};
10use std::marker::PhantomData;
11use std::ops::{Deref, DerefMut};
12use std::ptr::NonNull;
13
14pub struct Repacketizer {
16 rp: RawHandle<OpusRepacketizer>,
17 packets: Vec<Vec<u8>>,
18}
19
20unsafe impl Send for Repacketizer {}
21unsafe impl Sync for Repacketizer {}
22
23pub struct RepacketizerRef<'a> {
25 inner: Repacketizer,
26 _marker: PhantomData<&'a mut OpusRepacketizer>,
27}
28
29unsafe impl Send for RepacketizerRef<'_> {}
30unsafe impl Sync for RepacketizerRef<'_> {}
31
32impl Repacketizer {
33 fn from_raw(ptr: NonNull<OpusRepacketizer>, ownership: Ownership) -> Self {
34 Self {
35 rp: RawHandle::new(ptr, ownership, opus_repacketizer_destroy),
36 packets: Vec::new(),
37 }
38 }
39
40 pub fn new() -> Result<Self> {
45 let rp = unsafe { opus_repacketizer_create() };
46 let rp = NonNull::new(rp).ok_or(Error::AllocFail)?;
47 Ok(Self::from_raw(rp, Ownership::Owned))
48 }
49
50 pub fn reset(&mut self) {
52 unsafe { opus_repacketizer_init(self.rp.as_ptr()) };
53 self.packets.clear();
54 }
55
56 pub fn push(&mut self, packet: &[u8]) -> Result<()> {
63 if packet.is_empty() {
64 return Err(Error::BadArg);
65 }
66 let len_i32 = i32::try_from(packet.len()).map_err(|_| Error::BadArg)?;
67 self.packets.push(packet.to_vec());
68 let idx = self.packets.len() - 1;
69 let r =
70 unsafe { opus_repacketizer_cat(self.rp.as_ptr(), self.packets[idx].as_ptr(), len_i32) };
71 if r != 0 {
72 self.packets.pop();
73 return Err(Error::from_code(r));
74 }
75 Ok(())
77 }
78
79 #[must_use]
81 pub fn frame_count(&self) -> i32 {
82 unsafe { opus_repacketizer_get_nb_frames(self.rp.as_ptr()) }
83 }
84
85 #[must_use]
87 pub fn len(&self) -> usize {
88 let frames = self.frame_count();
89 debug_assert!(
90 frames >= 0,
91 "repacketizer frame count should be non-negative"
92 );
93 usize::try_from(frames).unwrap_or(0)
94 }
95
96 #[must_use]
98 pub fn is_empty(&self) -> bool {
99 self.len() == 0
100 }
101
102 pub fn emit_range(&mut self, begin: i32, end: i32, out: &mut [u8]) -> Result<usize> {
107 if out.is_empty() {
108 return Err(Error::BadArg);
109 }
110 if begin < 0 || end <= begin {
111 return Err(Error::BadArg);
112 }
113 let out_len_i32 = i32::try_from(out.len()).map_err(|_| Error::BadArg)?;
114 let n = unsafe {
115 opus_repacketizer_out_range(self.rp.as_ptr(), begin, end, out.as_mut_ptr(), out_len_i32)
116 };
117 if n < 0 {
118 return Err(Error::from_code(n));
119 }
120 usize::try_from(n).map_err(|_| Error::InternalError)
121 }
122
123 pub fn emit(&mut self, out: &mut [u8]) -> Result<usize> {
128 if out.is_empty() {
129 return Err(Error::BadArg);
130 }
131 let out_len_i32 = i32::try_from(out.len()).map_err(|_| Error::BadArg)?;
132 let n = unsafe { opus_repacketizer_out(self.rp.as_ptr(), out.as_mut_ptr(), out_len_i32) };
133 if n < 0 {
134 return Err(Error::from_code(n));
135 }
136 usize::try_from(n).map_err(|_| Error::InternalError)
137 }
138
139 pub fn size() -> Result<usize> {
144 let raw = unsafe { opus_repacketizer_get_size() };
145 if raw <= 0 {
146 return Err(Error::InternalError);
147 }
148 usize::try_from(raw).map_err(|_| Error::InternalError)
149 }
150
151 pub unsafe fn init_in_place(ptr: *mut OpusRepacketizer) -> Result<()> {
160 if ptr.is_null() {
161 return Err(Error::BadArg);
162 }
163 if !crate::opus_ptr_is_aligned(ptr.cast()) {
164 return Err(Error::BadArg);
165 }
166 unsafe { opus_repacketizer_init(ptr) };
167 Ok(())
168 }
169}
170
171impl<'a> RepacketizerRef<'a> {
172 #[must_use]
182 pub unsafe fn from_raw(ptr: *mut OpusRepacketizer) -> Self {
183 debug_assert!(!ptr.is_null(), "from_raw called with null ptr");
184 debug_assert!(crate::opus_ptr_is_aligned(ptr.cast()));
185 let repacketizer =
186 Repacketizer::from_raw(unsafe { NonNull::new_unchecked(ptr) }, Ownership::Borrowed);
187 Self {
188 inner: repacketizer,
189 _marker: PhantomData,
190 }
191 }
192
193 pub fn init_in(buf: &'a mut AlignedBuffer) -> Result<Self> {
198 let required = Repacketizer::size()?;
199 if buf.capacity_bytes() < required {
200 return Err(Error::BadArg);
201 }
202 let ptr = buf.as_mut_ptr::<OpusRepacketizer>();
203 unsafe { Repacketizer::init_in_place(ptr)? };
204 Ok(unsafe { Self::from_raw(ptr) })
205 }
206}
207
208impl Deref for RepacketizerRef<'_> {
209 type Target = Repacketizer;
210
211 fn deref(&self) -> &Self::Target {
212 &self.inner
213 }
214}
215
216impl DerefMut for RepacketizerRef<'_> {
217 fn deref_mut(&mut self) -> &mut Self::Target {
218 &mut self.inner
219 }
220}