1use crate::bindings::{
4 OPUS_AUTO, OPUS_BANDWIDTH_FULLBAND, OPUS_BANDWIDTH_MEDIUMBAND, OPUS_BANDWIDTH_NARROWBAND,
5 OPUS_BANDWIDTH_SUPERWIDEBAND, OPUS_BANDWIDTH_WIDEBAND, OPUS_BITRATE_MAX,
6 OPUS_GET_BANDWIDTH_REQUEST, OPUS_GET_BITRATE_REQUEST, OPUS_GET_COMPLEXITY_REQUEST,
7 OPUS_GET_DTX_REQUEST, OPUS_GET_FINAL_RANGE_REQUEST, OPUS_GET_FORCE_CHANNELS_REQUEST,
8 OPUS_GET_GAIN_REQUEST, OPUS_GET_IN_DTX_REQUEST, OPUS_GET_INBAND_FEC_REQUEST,
9 OPUS_GET_LAST_PACKET_DURATION_REQUEST, OPUS_GET_LOOKAHEAD_REQUEST, OPUS_GET_LSB_DEPTH_REQUEST,
10 OPUS_GET_MAX_BANDWIDTH_REQUEST, OPUS_GET_PACKET_LOSS_PERC_REQUEST,
11 OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_PITCH_REQUEST,
12 OPUS_GET_SAMPLE_RATE_REQUEST, OPUS_GET_SIGNAL_REQUEST, OPUS_GET_VBR_CONSTRAINT_REQUEST,
13 OPUS_GET_VBR_REQUEST, OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST,
14 OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, OPUS_RESET_STATE, OPUS_SET_BANDWIDTH_REQUEST,
15 OPUS_SET_BITRATE_REQUEST, OPUS_SET_COMPLEXITY_REQUEST, OPUS_SET_DTX_REQUEST,
16 OPUS_SET_FORCE_CHANNELS_REQUEST, OPUS_SET_GAIN_REQUEST, OPUS_SET_INBAND_FEC_REQUEST,
17 OPUS_SET_LSB_DEPTH_REQUEST, OPUS_SET_MAX_BANDWIDTH_REQUEST, OPUS_SET_PACKET_LOSS_PERC_REQUEST,
18 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_SET_SIGNAL_REQUEST,
19 OPUS_SET_VBR_CONSTRAINT_REQUEST, OPUS_SET_VBR_REQUEST, OPUS_SIGNAL_MUSIC, OPUS_SIGNAL_VOICE,
20 OpusDecoder, OpusEncoder, OpusMSDecoder, OpusMSEncoder, opus_decoder_ctl, opus_encoder_ctl,
21 opus_multistream_decode, opus_multistream_decode_float, opus_multistream_decoder_create,
22 opus_multistream_decoder_ctl, opus_multistream_decoder_destroy,
23 opus_multistream_decoder_get_size, opus_multistream_decoder_init, opus_multistream_encode,
24 opus_multistream_encode_float, opus_multistream_encoder_create, opus_multistream_encoder_ctl,
25 opus_multistream_encoder_destroy, opus_multistream_encoder_get_size,
26 opus_multistream_encoder_init, opus_multistream_surround_encoder_create,
27 opus_multistream_surround_encoder_get_size, opus_multistream_surround_encoder_init,
28};
29use crate::constants::{is_frame_size_2_5ms_aligned, max_frame_samples_for};
30use crate::error::{Error, Result};
31use crate::types::{Application, Bandwidth, Bitrate, Channels, Complexity, SampleRate, Signal};
32use crate::{AlignedBuffer, Ownership, RawHandle};
33use std::marker::PhantomData;
34use std::num::{NonZeroU8, NonZeroUsize};
35use std::ops::Deref;
36use std::ptr::NonNull;
37
38#[derive(Debug, Clone, Copy)]
40pub struct Mapping<'a> {
41 pub channels: u8,
43 pub streams: u8,
45 pub coupled_streams: u8,
47 pub mapping: &'a [u8],
49}
50
51impl Mapping<'_> {
52 fn validate_common(&self) -> Result<(usize, usize, usize)> {
53 let channel_count = NonZeroU8::new(self.channels).ok_or(Error::BadArg)?;
54 let channel_count = usize::from(channel_count.get());
55 if self.mapping.len() != channel_count {
56 return Err(Error::BadArg);
57 }
58
59 let streams = NonZeroU8::new(self.streams).ok_or(Error::BadArg)?;
60 let streams = usize::from(streams.get());
61 let coupled = usize::from(self.coupled_streams);
62 if coupled > streams {
63 return Err(Error::BadArg);
64 }
65 if streams + coupled > u8::MAX as usize {
66 return Err(Error::BadArg);
67 }
68 let total_streams = streams + coupled;
69 for &entry in self.mapping {
70 if entry == u8::MAX {
71 continue;
72 }
73 if usize::from(entry) >= total_streams {
74 return Err(Error::BadArg);
75 }
76 }
77 Ok((channel_count, streams, coupled))
78 }
79
80 fn validate_for_decoder(&self) -> Result<()> {
82 self.validate_common()?;
83 Ok(())
84 }
85
86 fn validate_for_encoder(&self) -> Result<()> {
88 let (channel_count, streams, coupled) = self.validate_common()?;
89 if streams + coupled > channel_count {
90 return Err(Error::BadArg);
91 }
92
93 let mut has_left = [false; u8::MAX as usize];
94 let mut has_right = [false; u8::MAX as usize];
95 let mut has_mono = [false; u8::MAX as usize];
96 for &entry in self.mapping {
97 if entry == u8::MAX {
98 continue;
99 }
100 let idx = usize::from(entry);
101 if idx < 2 * coupled {
102 let stream = idx / 2;
103 if idx % 2 == 0 {
104 has_left[stream] = true;
105 } else {
106 has_right[stream] = true;
107 }
108 } else {
109 let stream = idx - coupled;
110 if stream >= coupled && stream < streams {
111 has_mono[stream - coupled] = true;
112 }
113 }
114 }
115
116 if has_left[..coupled].iter().any(|has| !has) || has_right[..coupled].iter().any(|has| !has)
117 {
118 return Err(Error::BadArg);
119 }
120 if has_mono[..streams.saturating_sub(coupled)]
121 .iter()
122 .any(|has| !has)
123 {
124 return Err(Error::BadArg);
125 }
126 Ok(())
127 }
128}
129
130const VORBIS_SURROUND_MAPPINGS: [(&[u8], u8, u8); 8] = [
135 (&[0], 1, 0),
136 (&[0, 1], 1, 1),
137 (&[0, 2, 1], 2, 1),
138 (&[0, 1, 2, 3], 2, 2),
139 (&[0, 4, 1, 2, 3], 3, 2),
140 (&[0, 4, 1, 2, 3, 5], 4, 2),
141 (&[0, 4, 1, 2, 3, 5, 6], 4, 3),
142 (&[0, 6, 1, 2, 3, 4, 5, 7], 5, 3),
143];
144
145fn surround_mapping(channels: u8, mapping_family: i32) -> Result<(Vec<u8>, u8, u8)> {
146 let channel_count = usize::from(NonZeroU8::new(channels).ok_or(Error::BadArg)?.get());
147 match mapping_family {
148 0 => match channels {
149 1 => Ok((vec![0], 1, 0)),
150 2 => Ok((vec![0, 1], 1, 1)),
151 _ => Err(Error::BadArg),
152 },
153 1 if channel_count <= VORBIS_SURROUND_MAPPINGS.len() => {
154 let (mapping, streams, coupled) = VORBIS_SURROUND_MAPPINGS[channel_count - 1];
155 Ok((mapping.to_vec(), streams, coupled))
156 }
157 2 => {
158 if channels > 227 {
159 return Err(Error::BadArg);
160 }
161 let order_plus_one = (1usize..=15)
162 .take_while(|value| value * value <= channel_count)
163 .last()
164 .ok_or(Error::BadArg)?;
165 let ambisonic_channels = order_plus_one * order_plus_one;
166 let nondiegetic_channels = channel_count - ambisonic_channels;
167 if nondiegetic_channels != 0 && nondiegetic_channels != 2 {
168 return Err(Error::BadArg);
169 }
170
171 let coupled = u8::from(nondiegetic_channels != 0);
172 let streams = u8::try_from(ambisonic_channels + usize::from(coupled))
173 .map_err(|_| Error::BadArg)?;
174 let mut mapping = Vec::with_capacity(channel_count);
175 for channel in 0..ambisonic_channels {
176 mapping.push(
177 u8::try_from(channel + 2 * usize::from(coupled)).map_err(|_| Error::BadArg)?,
178 );
179 }
180 mapping.extend(0..2 * coupled);
181 Ok((mapping, streams, coupled))
182 }
183 255 => Ok(((0..channels).collect(), channels, 0)),
184 _ => Err(Error::BadArg),
185 }
186}
187
188fn validate_stream_counts(streams: u8, coupled_streams: u8) -> Result<()> {
189 let streams = NonZeroU8::new(streams).ok_or(Error::BadArg)?;
190 if coupled_streams > streams.get() {
191 return Err(Error::BadArg);
192 }
193 if usize::from(streams.get()) + usize::from(coupled_streams) > u8::MAX as usize {
194 return Err(Error::BadArg);
195 }
196 Ok(())
197}
198
199fn bandwidth_from_ctl(value: i32) -> Result<Bandwidth> {
200 let value = u32::try_from(value).map_err(|_| Error::InternalError)?;
201 match value {
202 x if x == OPUS_BANDWIDTH_NARROWBAND => Ok(Bandwidth::Narrowband),
203 x if x == OPUS_BANDWIDTH_MEDIUMBAND => Ok(Bandwidth::Mediumband),
204 x if x == OPUS_BANDWIDTH_WIDEBAND => Ok(Bandwidth::Wideband),
205 x if x == OPUS_BANDWIDTH_SUPERWIDEBAND => Ok(Bandwidth::SuperWideband),
206 x if x == OPUS_BANDWIDTH_FULLBAND => Ok(Bandwidth::Fullband),
207 _ => Err(Error::InternalError),
208 }
209}
210
211pub struct MultistreamEncoder {
213 raw: RawHandle<OpusMSEncoder>,
214 sample_rate: SampleRate,
215 channels: u8,
216 streams: u8,
217 coupled_streams: u8,
218}
219
220unsafe impl Send for MultistreamEncoder {}
221
222pub struct MultistreamEncoderRef<'a> {
236 inner: MultistreamEncoder,
237 _marker: PhantomData<&'a mut OpusMSEncoder>,
238}
239
240unsafe impl Send for MultistreamEncoderRef<'_> {}
241
242impl MultistreamEncoder {
243 fn from_raw(
244 ptr: NonNull<OpusMSEncoder>,
245 sample_rate: SampleRate,
246 channels: u8,
247 streams: u8,
248 coupled_streams: u8,
249 ownership: Ownership,
250 ) -> Self {
251 Self {
252 raw: RawHandle::new(ptr, ownership, opus_multistream_encoder_destroy),
253 sample_rate,
254 channels,
255 streams,
256 coupled_streams,
257 }
258 }
259
260 pub fn size(streams: u8, coupled_streams: u8) -> Result<usize> {
266 validate_stream_counts(streams, coupled_streams)?;
267 let raw = unsafe {
268 opus_multistream_encoder_get_size(i32::from(streams), i32::from(coupled_streams))
269 };
270 if raw <= 0 {
271 return Err(Error::BadArg);
272 }
273 usize::try_from(raw).map_err(|_| Error::InternalError)
274 }
275
276 pub fn surround_size(channels: u8, mapping_family: i32) -> Result<usize> {
281 if channels == 0 {
282 return Err(Error::BadArg);
283 }
284 let raw = unsafe {
285 opus_multistream_surround_encoder_get_size(i32::from(channels), mapping_family)
286 };
287 if raw <= 0 {
288 return Err(Error::BadArg);
289 }
290 usize::try_from(raw).map_err(|_| Error::InternalError)
291 }
292
293 pub fn surround_mapping(channels: u8, mapping_family: i32) -> Result<(Vec<u8>, u8, u8)> {
302 surround_mapping(channels, mapping_family)
303 }
304
305 pub unsafe fn init_in_place(
315 ptr: *mut OpusMSEncoder,
316 sr: SampleRate,
317 app: Application,
318 mapping: Mapping<'_>,
319 ) -> Result<()> {
320 if ptr.is_null() {
321 return Err(Error::BadArg);
322 }
323 if !crate::opus_ptr_is_aligned(ptr.cast()) {
324 return Err(Error::BadArg);
325 }
326 mapping.validate_for_encoder()?;
327 let r = unsafe {
328 opus_multistream_encoder_init(
329 ptr,
330 sr as i32,
331 i32::from(mapping.channels),
332 i32::from(mapping.streams),
333 i32::from(mapping.coupled_streams),
334 mapping.mapping.as_ptr(),
335 app as i32,
336 )
337 };
338 if r != 0 {
339 return Err(Error::from_code(r));
340 }
341 Ok(())
342 }
343
344 pub unsafe fn init_surround_in_place(
353 ptr: *mut OpusMSEncoder,
354 sr: SampleRate,
355 channels: u8,
356 mapping_family: i32,
357 app: Application,
358 ) -> Result<(u8, u8, Vec<u8>)> {
359 if ptr.is_null() || channels == 0 {
360 return Err(Error::BadArg);
361 }
362 if !crate::opus_ptr_is_aligned(ptr.cast()) {
363 return Err(Error::BadArg);
364 }
365 Self::surround_size(channels, mapping_family)?;
366 let mut streams = 0i32;
367 let mut coupled = 0i32;
368 let mut mapping = vec![0u8; channels as usize];
369 let r = unsafe {
370 opus_multistream_surround_encoder_init(
371 ptr,
372 sr as i32,
373 i32::from(channels),
374 mapping_family,
375 std::ptr::addr_of_mut!(streams),
376 std::ptr::addr_of_mut!(coupled),
377 mapping.as_mut_ptr(),
378 app as i32,
379 )
380 };
381 if r != 0 {
382 return Err(Error::from_code(r));
383 }
384 Ok((
385 u8::try_from(streams).map_err(|_| Error::BadArg)?,
386 u8::try_from(coupled).map_err(|_| Error::BadArg)?,
387 mapping,
388 ))
389 }
390
391 pub fn new(sr: SampleRate, app: Application, mapping: Mapping<'_>) -> Result<Self> {
400 mapping.validate_for_encoder()?;
401 let mut err = 0i32;
402 let enc = unsafe {
403 opus_multistream_encoder_create(
404 sr as i32,
405 i32::from(mapping.channels),
406 i32::from(mapping.streams),
407 i32::from(mapping.coupled_streams),
408 mapping.mapping.as_ptr(),
409 app as i32,
410 std::ptr::addr_of_mut!(err),
411 )
412 };
413 if err != 0 {
414 return Err(Error::from_code(err));
415 }
416 let enc = NonNull::new(enc).ok_or(Error::AllocFail)?;
417 Ok(Self::from_raw(
418 enc,
419 sr,
420 mapping.channels,
421 mapping.streams,
422 mapping.coupled_streams,
423 Ownership::Owned,
424 ))
425 }
426
427 #[allow(clippy::missing_panics_doc)]
433 pub fn encode(
434 &mut self,
435 pcm: &[i16],
436 frame_size_per_ch: usize,
437 out: &mut [u8],
438 ) -> Result<usize> {
439 let frame_size_per_ch = NonZeroUsize::new(frame_size_per_ch).ok_or(Error::BadArg)?;
440 if frame_size_per_ch.get() > max_frame_samples_for(self.sample_rate) {
441 return Err(Error::BadArg);
442 }
443 if pcm.len() != frame_size_per_ch.get() * self.channels as usize {
444 return Err(Error::BadArg);
445 }
446 if out.is_empty() || out.len() > i32::MAX as usize {
447 return Err(Error::BadArg);
448 }
449 let n = unsafe {
450 opus_multistream_encode(
451 self.raw.as_ptr(),
452 pcm.as_ptr(),
453 i32::try_from(frame_size_per_ch.get()).map_err(|_| Error::BadArg)?,
454 out.as_mut_ptr(),
455 i32::try_from(out.len()).map_err(|_| Error::BadArg)?,
456 )
457 };
458 if n < 0 {
459 return Err(Error::from_code(n));
460 }
461 usize::try_from(n).map_err(|_| Error::InternalError)
462 }
463
464 pub fn encode_float(
470 &mut self,
471 pcm: &[f32],
472 frame_size_per_ch: usize,
473 out: &mut [u8],
474 ) -> Result<usize> {
475 let frame_size_per_ch = NonZeroUsize::new(frame_size_per_ch).ok_or(Error::BadArg)?;
476 if frame_size_per_ch.get() > max_frame_samples_for(self.sample_rate) {
477 return Err(Error::BadArg);
478 }
479 if pcm.len() != frame_size_per_ch.get() * self.channels as usize {
480 return Err(Error::BadArg);
481 }
482 if out.is_empty() || out.len() > i32::MAX as usize {
483 return Err(Error::BadArg);
484 }
485 let n = unsafe {
486 opus_multistream_encode_float(
487 self.raw.as_ptr(),
488 pcm.as_ptr(),
489 i32::try_from(frame_size_per_ch.get()).map_err(|_| Error::BadArg)?,
490 out.as_mut_ptr(),
491 i32::try_from(out.len()).map_err(|_| Error::BadArg)?,
492 )
493 };
494 if n < 0 {
495 return Err(Error::from_code(n));
496 }
497 usize::try_from(n).map_err(|_| Error::InternalError)
498 }
499
500 pub fn final_range(&mut self) -> Result<u32> {
506 let mut v: u32 = 0;
507 let r = unsafe {
508 opus_multistream_encoder_ctl(
509 self.raw.as_ptr(),
510 OPUS_GET_FINAL_RANGE_REQUEST as i32,
511 &mut v,
512 )
513 };
514 if r != 0 {
515 return Err(Error::from_code(r));
516 }
517 Ok(v)
518 }
519
520 pub fn set_bitrate(&mut self, bitrate: Bitrate) -> Result<()> {
526 self.simple_ctl(OPUS_SET_BITRATE_REQUEST as i32, bitrate.value())
527 }
528
529 pub fn bitrate(&mut self) -> Result<Bitrate> {
536 let v = self.get_int_ctl(OPUS_GET_BITRATE_REQUEST as i32)?;
537 Ok(match v {
538 x if x == OPUS_AUTO => Bitrate::Auto,
539 x if x == OPUS_BITRATE_MAX => Bitrate::Max,
540 other => Bitrate::Custom(other),
541 })
542 }
543
544 pub fn set_complexity(&mut self, complexity: Complexity) -> Result<()> {
550 self.simple_ctl(
551 OPUS_SET_COMPLEXITY_REQUEST as i32,
552 complexity.value() as i32,
553 )
554 }
555
556 pub fn complexity(&mut self) -> Result<Complexity> {
562 let v = self.get_int_ctl(OPUS_GET_COMPLEXITY_REQUEST as i32)?;
563 let complexity = u32::try_from(v).map_err(|_| Error::InternalError)?;
564 Complexity::try_new(complexity).ok_or(Error::InternalError)
565 }
566
567 pub fn set_dtx(&mut self, enabled: bool) -> Result<()> {
573 self.simple_ctl(OPUS_SET_DTX_REQUEST as i32, i32::from(enabled))
574 }
575
576 pub fn dtx(&mut self) -> Result<bool> {
582 self.get_bool_ctl(OPUS_GET_DTX_REQUEST as i32)
583 }
584
585 pub fn in_dtx(&mut self) -> Result<bool> {
594 for stream_index in 0..i32::from(self.streams) {
595 if self.encoder_int_ctl(stream_index, OPUS_GET_IN_DTX_REQUEST as i32)? == 0 {
596 return Ok(false);
597 }
598 }
599 Ok(true)
600 }
601
602 pub fn set_inband_fec(&mut self, enabled: bool) -> Result<()> {
608 self.simple_ctl(OPUS_SET_INBAND_FEC_REQUEST as i32, i32::from(enabled))
609 }
610
611 pub fn inband_fec(&mut self) -> Result<bool> {
617 self.get_bool_ctl(OPUS_GET_INBAND_FEC_REQUEST as i32)
618 }
619
620 pub fn set_packet_loss_perc(&mut self, perc: i32) -> Result<()> {
626 if !(0..=100).contains(&perc) {
627 return Err(Error::BadArg);
628 }
629 self.simple_ctl(OPUS_SET_PACKET_LOSS_PERC_REQUEST as i32, perc)
630 }
631
632 pub fn packet_loss_perc(&mut self) -> Result<i32> {
638 self.get_int_ctl(OPUS_GET_PACKET_LOSS_PERC_REQUEST as i32)
639 }
640
641 pub fn set_vbr(&mut self, enabled: bool) -> Result<()> {
647 self.simple_ctl(OPUS_SET_VBR_REQUEST as i32, i32::from(enabled))
648 }
649
650 pub fn vbr(&mut self) -> Result<bool> {
656 self.get_bool_ctl(OPUS_GET_VBR_REQUEST as i32)
657 }
658
659 pub fn set_vbr_constraint(&mut self, constrained: bool) -> Result<()> {
665 self.simple_ctl(
666 OPUS_SET_VBR_CONSTRAINT_REQUEST as i32,
667 i32::from(constrained),
668 )
669 }
670
671 pub fn vbr_constraint(&mut self) -> Result<bool> {
677 self.get_bool_ctl(OPUS_GET_VBR_CONSTRAINT_REQUEST as i32)
678 }
679
680 pub fn set_max_bandwidth(&mut self, bw: Bandwidth) -> Result<()> {
686 self.simple_ctl(OPUS_SET_MAX_BANDWIDTH_REQUEST as i32, bw as i32)
687 }
688
689 pub fn max_bandwidth(&mut self) -> Result<Bandwidth> {
699 bandwidth_from_ctl(self.encoder_int_ctl(0, OPUS_GET_MAX_BANDWIDTH_REQUEST as i32)?)
700 }
701
702 pub fn set_bandwidth(&mut self, bw: Bandwidth) -> Result<()> {
708 self.simple_ctl(OPUS_SET_BANDWIDTH_REQUEST as i32, bw as i32)
709 }
710
711 pub fn bandwidth(&mut self) -> Result<Bandwidth> {
717 self.get_bandwidth_ctl(OPUS_GET_BANDWIDTH_REQUEST as i32)
718 }
719
720 pub fn set_force_channels(&mut self, channels: Option<Channels>) -> Result<()> {
726 let value = match channels {
727 Some(Channels::Mono) => 1,
728 Some(Channels::Stereo) => 2,
729 None => OPUS_AUTO,
730 };
731 self.simple_ctl(OPUS_SET_FORCE_CHANNELS_REQUEST as i32, value)
732 }
733
734 pub fn force_channels(&mut self) -> Result<Option<Channels>> {
740 let v = self.get_int_ctl(OPUS_GET_FORCE_CHANNELS_REQUEST as i32)?;
741 Ok(match v {
742 1 => Some(Channels::Mono),
743 2 => Some(Channels::Stereo),
744 x if x == OPUS_AUTO => None,
745 _ => None,
746 })
747 }
748
749 pub fn set_signal(&mut self, signal: Signal) -> Result<()> {
755 self.simple_ctl(OPUS_SET_SIGNAL_REQUEST as i32, signal as i32)
756 }
757
758 pub fn signal(&mut self) -> Result<Signal> {
764 let v = self.get_int_ctl(OPUS_GET_SIGNAL_REQUEST as i32)?;
765 match v {
766 x if x == OPUS_AUTO => Ok(Signal::Auto),
767 x if x == OPUS_SIGNAL_VOICE as i32 => Ok(Signal::Voice),
768 x if x == OPUS_SIGNAL_MUSIC as i32 => Ok(Signal::Music),
769 _ => Err(Error::InternalError),
770 }
771 }
772
773 pub fn lookahead(&mut self) -> Result<i32> {
779 self.get_int_ctl(OPUS_GET_LOOKAHEAD_REQUEST as i32)
780 }
781
782 pub fn set_lsb_depth(&mut self, bits: i32) -> Result<()> {
788 if !(8..=24).contains(&bits) {
789 return Err(Error::BadArg);
790 }
791 self.simple_ctl(OPUS_SET_LSB_DEPTH_REQUEST as i32, bits)
792 }
793
794 pub fn lsb_depth(&mut self) -> Result<i32> {
799 self.get_int_ctl(OPUS_GET_LSB_DEPTH_REQUEST as i32)
800 }
801
802 pub fn reset(&mut self) -> Result<()> {
808 let r = unsafe { opus_multistream_encoder_ctl(self.raw.as_ptr(), OPUS_RESET_STATE as i32) };
809 if r != 0 {
810 return Err(Error::from_code(r));
811 }
812 Ok(())
813 }
814
815 #[must_use]
817 pub const fn channels(&self) -> u8 {
818 self.channels
819 }
820 #[must_use]
822 pub const fn sample_rate(&self) -> SampleRate {
823 self.sample_rate
824 }
825 #[must_use]
827 pub const fn streams(&self) -> u8 {
828 self.streams
829 }
830 #[must_use]
832 pub const fn coupled_streams(&self) -> u8 {
833 self.coupled_streams
834 }
835
836 pub fn new_surround(
842 sr: SampleRate,
843 channels: u8,
844 mapping_family: i32,
845 app: Application,
846 ) -> Result<(Self, Vec<u8>)> {
847 Self::surround_size(channels, mapping_family)?;
848 let mut err = 0i32;
849 let mut streams = 0i32;
850 let mut coupled = 0i32;
851 let mut mapping = vec![0u8; channels as usize];
852 let enc = unsafe {
853 opus_multistream_surround_encoder_create(
854 sr as i32,
855 i32::from(channels),
856 mapping_family,
857 std::ptr::addr_of_mut!(streams),
858 std::ptr::addr_of_mut!(coupled),
859 mapping.as_mut_ptr(),
860 app as i32,
861 std::ptr::addr_of_mut!(err),
862 )
863 };
864 if err != 0 {
865 return Err(Error::from_code(err));
866 }
867 let enc = NonNull::new(enc).ok_or(Error::AllocFail)?;
868 let streams_u8 = u8::try_from(streams).map_err(|_| Error::BadArg)?;
869 let coupled_u8 = u8::try_from(coupled).map_err(|_| Error::BadArg)?;
870 Ok((
871 Self::from_raw(enc, sr, channels, streams_u8, coupled_u8, Ownership::Owned),
872 mapping,
873 ))
874 }
875
876 pub unsafe fn encoder_state_ptr(&mut self, stream_index: i32) -> Result<*mut OpusEncoder> {
886 Ok(self.encoder_state(stream_index)?.as_ptr())
887 }
888
889 fn encoder_state(&mut self, stream_index: i32) -> Result<NonNull<OpusEncoder>> {
890 if stream_index < 0 || stream_index >= i32::from(self.streams) {
891 return Err(Error::BadArg);
892 }
893 let mut state: *mut OpusEncoder = std::ptr::null_mut();
894 let r = unsafe {
895 opus_multistream_encoder_ctl(
896 self.raw.as_ptr(),
897 OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST as i32,
898 stream_index,
899 &mut state,
900 )
901 };
902 if r != 0 {
903 return Err(Error::from_code(r));
904 }
905 NonNull::new(state).ok_or(Error::InternalError)
906 }
907
908 fn encoder_int_ctl(&mut self, stream_index: i32, req: i32) -> Result<i32> {
909 let state = self.encoder_state(stream_index)?;
910 let mut value = 0i32;
911 let r = unsafe { opus_encoder_ctl(state.as_ptr(), req, &mut value) };
912 if r != 0 {
913 return Err(Error::from_code(r));
914 }
915 Ok(value)
916 }
917
918 fn simple_ctl(&mut self, req: i32, val: i32) -> Result<()> {
919 let r = unsafe { opus_multistream_encoder_ctl(self.raw.as_ptr(), req, val) };
920 if r != 0 {
921 return Err(Error::from_code(r));
922 }
923 Ok(())
924 }
925
926 fn get_int_ctl(&mut self, req: i32) -> Result<i32> {
927 let mut v: i32 = 0;
928 let r = unsafe { opus_multistream_encoder_ctl(self.raw.as_ptr(), req, &mut v) };
929 if r != 0 {
930 return Err(Error::from_code(r));
931 }
932 Ok(v)
933 }
934
935 fn get_bool_ctl(&mut self, req: i32) -> Result<bool> {
936 Ok(self.get_int_ctl(req)? != 0)
937 }
938
939 fn get_bandwidth_ctl(&mut self, req: i32) -> Result<Bandwidth> {
940 bandwidth_from_ctl(self.get_int_ctl(req)?)
941 }
942}
943
944impl<'a> MultistreamEncoderRef<'a> {
945 unsafe fn from_raw_parts(
946 ptr: *mut OpusMSEncoder,
947 sr: SampleRate,
948 channels: u8,
949 streams: u8,
950 coupled_streams: u8,
951 caller: &str,
952 ) -> Self {
953 assert!(channels != 0, "{caller} called with zero channels");
954 assert!(
955 validate_stream_counts(streams, coupled_streams).is_ok(),
956 "{caller} called with invalid stream counts"
957 );
958 let encoder = MultistreamEncoder::from_raw(
959 crate::checked_non_null(ptr, caller),
960 sr,
961 channels,
962 streams,
963 coupled_streams,
964 Ownership::Borrowed,
965 );
966 Self {
967 inner: encoder,
968 _marker: PhantomData,
969 }
970 }
971
972 #[must_use]
989 pub unsafe fn from_raw(ptr: *mut OpusMSEncoder, sr: SampleRate, mapping: Mapping<'_>) -> Self {
990 assert!(
991 mapping.validate_for_encoder().is_ok(),
992 "MultistreamEncoderRef::from_raw called with invalid mapping"
993 );
994 unsafe {
995 Self::from_raw_parts(
996 ptr,
997 sr,
998 mapping.channels,
999 mapping.streams,
1000 mapping.coupled_streams,
1001 "MultistreamEncoderRef::from_raw",
1002 )
1003 }
1004 }
1005
1006 pub fn init_in(
1011 buf: &'a mut AlignedBuffer,
1012 sr: SampleRate,
1013 app: Application,
1014 mapping: Mapping<'_>,
1015 ) -> Result<Self> {
1016 let required = MultistreamEncoder::size(mapping.streams, mapping.coupled_streams)?;
1017 if buf.capacity_bytes() < required {
1018 return Err(Error::BadArg);
1019 }
1020 let ptr = buf.as_mut_ptr::<OpusMSEncoder>();
1021 unsafe { MultistreamEncoder::init_in_place(ptr, sr, app, mapping)? };
1022 Ok(unsafe { Self::from_raw(ptr, sr, mapping) })
1023 }
1024
1025 pub fn init_in_surround(
1030 buf: &'a mut AlignedBuffer,
1031 sr: SampleRate,
1032 channels: u8,
1033 mapping_family: i32,
1034 app: Application,
1035 ) -> Result<(Self, Vec<u8>)> {
1036 let required = MultistreamEncoder::surround_size(channels, mapping_family)?;
1037 if buf.capacity_bytes() < required {
1038 return Err(Error::BadArg);
1039 }
1040 let ptr = buf.as_mut_ptr::<OpusMSEncoder>();
1041 let (streams, coupled, mapping) = unsafe {
1042 MultistreamEncoder::init_surround_in_place(ptr, sr, channels, mapping_family, app)?
1043 };
1044 let encoder = unsafe {
1045 Self::from_raw_parts(
1046 ptr,
1047 sr,
1048 channels,
1049 streams,
1050 coupled,
1051 "MultistreamEncoderRef::init_in_surround",
1052 )
1053 };
1054 Ok((encoder, mapping))
1055 }
1056
1057 delegate_ref_mut_methods! {
1058 fn encode(pcm: &[i16], frame_size_per_ch: usize, out: &mut [u8]) -> Result<usize>;
1059 fn encode_float(pcm: &[f32], frame_size_per_ch: usize, out: &mut [u8]) -> Result<usize>;
1060 fn final_range() -> Result<u32>;
1061 fn set_bitrate(bitrate: Bitrate) -> Result<()>;
1062 fn bitrate() -> Result<Bitrate>;
1063 fn set_complexity(complexity: Complexity) -> Result<()>;
1064 fn complexity() -> Result<Complexity>;
1065 fn set_dtx(enabled: bool) -> Result<()>;
1066 fn dtx() -> Result<bool>;
1067 fn in_dtx() -> Result<bool>;
1068 fn set_inband_fec(enabled: bool) -> Result<()>;
1069 fn inband_fec() -> Result<bool>;
1070 fn set_packet_loss_perc(perc: i32) -> Result<()>;
1071 fn packet_loss_perc() -> Result<i32>;
1072 fn set_vbr(enabled: bool) -> Result<()>;
1073 fn vbr() -> Result<bool>;
1074 fn set_vbr_constraint(constrained: bool) -> Result<()>;
1075 fn vbr_constraint() -> Result<bool>;
1076 fn set_max_bandwidth(bw: Bandwidth) -> Result<()>;
1077 fn max_bandwidth() -> Result<Bandwidth>;
1078 fn set_bandwidth(bw: Bandwidth) -> Result<()>;
1079 fn bandwidth() -> Result<Bandwidth>;
1080 fn set_force_channels(channels: Option<Channels>) -> Result<()>;
1081 fn force_channels() -> Result<Option<Channels>>;
1082 fn set_signal(signal: Signal) -> Result<()>;
1083 fn signal() -> Result<Signal>;
1084 fn lookahead() -> Result<i32>;
1085 fn set_lsb_depth(bits: i32) -> Result<()>;
1086 fn lsb_depth() -> Result<i32>;
1087 fn reset() -> Result<()>;
1088 }
1089
1090 delegate_ref_unsafe_mut_methods! {
1091 unsafe fn encoder_state_ptr(stream_index: i32) -> Result<*mut OpusEncoder>;
1092 }
1093}
1094
1095impl Deref for MultistreamEncoderRef<'_> {
1096 type Target = MultistreamEncoder;
1097
1098 fn deref(&self) -> &Self::Target {
1099 &self.inner
1100 }
1101}
1102
1103pub struct MultistreamDecoder {
1105 raw: RawHandle<OpusMSDecoder>,
1106 sample_rate: SampleRate,
1107 channels: u8,
1108}
1109
1110unsafe impl Send for MultistreamDecoder {}
1111
1112pub struct MultistreamDecoderRef<'a> {
1126 inner: MultistreamDecoder,
1127 _marker: PhantomData<&'a mut OpusMSDecoder>,
1128}
1129
1130unsafe impl Send for MultistreamDecoderRef<'_> {}
1131
1132impl MultistreamDecoder {
1133 fn from_raw(
1134 ptr: NonNull<OpusMSDecoder>,
1135 sample_rate: SampleRate,
1136 channels: u8,
1137 ownership: Ownership,
1138 ) -> Self {
1139 Self {
1140 raw: RawHandle::new(ptr, ownership, opus_multistream_decoder_destroy),
1141 sample_rate,
1142 channels,
1143 }
1144 }
1145
1146 pub fn size(streams: u8, coupled_streams: u8) -> Result<usize> {
1152 validate_stream_counts(streams, coupled_streams)?;
1153 let raw = unsafe {
1154 opus_multistream_decoder_get_size(i32::from(streams), i32::from(coupled_streams))
1155 };
1156 if raw <= 0 {
1157 return Err(Error::BadArg);
1158 }
1159 usize::try_from(raw).map_err(|_| Error::InternalError)
1160 }
1161
1162 pub unsafe fn init_in_place(
1172 ptr: *mut OpusMSDecoder,
1173 sr: SampleRate,
1174 mapping: Mapping<'_>,
1175 ) -> Result<()> {
1176 if ptr.is_null() {
1177 return Err(Error::BadArg);
1178 }
1179 if !crate::opus_ptr_is_aligned(ptr.cast()) {
1180 return Err(Error::BadArg);
1181 }
1182 mapping.validate_for_decoder()?;
1183 let r = unsafe {
1184 opus_multistream_decoder_init(
1185 ptr,
1186 sr as i32,
1187 i32::from(mapping.channels),
1188 i32::from(mapping.streams),
1189 i32::from(mapping.coupled_streams),
1190 mapping.mapping.as_ptr(),
1191 )
1192 };
1193 if r != 0 {
1194 return Err(Error::from_code(r));
1195 }
1196 Ok(())
1197 }
1198
1199 pub fn new(sr: SampleRate, mapping: Mapping<'_>) -> Result<Self> {
1205 mapping.validate_for_decoder()?;
1206 let mut err = 0i32;
1207 let dec = unsafe {
1208 opus_multistream_decoder_create(
1209 sr as i32,
1210 i32::from(mapping.channels),
1211 i32::from(mapping.streams),
1212 i32::from(mapping.coupled_streams),
1213 mapping.mapping.as_ptr(),
1214 std::ptr::addr_of_mut!(err),
1215 )
1216 };
1217 if err != 0 {
1218 return Err(Error::from_code(err));
1219 }
1220 let dec = NonNull::new(dec).ok_or(Error::AllocFail)?;
1221 Ok(Self::from_raw(dec, sr, mapping.channels, Ownership::Owned))
1222 }
1223
1224 pub fn decode(
1230 &mut self,
1231 packet: &[u8],
1232 out: &mut [i16],
1233 frame_size_per_ch: usize,
1234 fec: bool,
1235 ) -> Result<usize> {
1236 let frame_size_per_ch = NonZeroUsize::new(frame_size_per_ch).ok_or(Error::BadArg)?;
1237 if frame_size_per_ch.get() > max_frame_samples_for(self.sample_rate) {
1238 return Err(Error::BadArg);
1239 }
1240 if out.len() != frame_size_per_ch.get() * self.channels as usize {
1241 return Err(Error::BadArg);
1242 }
1243 if (packet.is_empty() || fec)
1245 && !is_frame_size_2_5ms_aligned(frame_size_per_ch.get(), self.sample_rate)
1246 {
1247 return Err(Error::BadArg);
1248 }
1249 let n = unsafe {
1250 opus_multistream_decode(
1251 self.raw.as_ptr(),
1252 if packet.is_empty() {
1253 std::ptr::null()
1254 } else {
1255 packet.as_ptr()
1256 },
1257 if packet.is_empty() {
1258 0
1259 } else {
1260 i32::try_from(packet.len()).map_err(|_| Error::BadArg)?
1261 },
1262 out.as_mut_ptr(),
1263 i32::try_from(frame_size_per_ch.get()).map_err(|_| Error::BadArg)?,
1264 i32::from(fec),
1265 )
1266 };
1267 if n < 0 {
1268 return Err(Error::from_code(n));
1269 }
1270 usize::try_from(n).map_err(|_| Error::InternalError)
1271 }
1272
1273 pub fn decode_float(
1279 &mut self,
1280 packet: &[u8],
1281 out: &mut [f32],
1282 frame_size_per_ch: usize,
1283 fec: bool,
1284 ) -> Result<usize> {
1285 let frame_size_per_ch = NonZeroUsize::new(frame_size_per_ch).ok_or(Error::BadArg)?;
1286 if frame_size_per_ch.get() > max_frame_samples_for(self.sample_rate) {
1287 return Err(Error::BadArg);
1288 }
1289 if out.len() != frame_size_per_ch.get() * self.channels as usize {
1290 return Err(Error::BadArg);
1291 }
1292 if (packet.is_empty() || fec)
1294 && !is_frame_size_2_5ms_aligned(frame_size_per_ch.get(), self.sample_rate)
1295 {
1296 return Err(Error::BadArg);
1297 }
1298 let n = unsafe {
1299 opus_multistream_decode_float(
1300 self.raw.as_ptr(),
1301 if packet.is_empty() {
1302 std::ptr::null()
1303 } else {
1304 packet.as_ptr()
1305 },
1306 if packet.is_empty() {
1307 0
1308 } else {
1309 i32::try_from(packet.len()).map_err(|_| Error::BadArg)?
1310 },
1311 out.as_mut_ptr(),
1312 i32::try_from(frame_size_per_ch.get()).map_err(|_| Error::BadArg)?,
1313 i32::from(fec),
1314 )
1315 };
1316 if n < 0 {
1317 return Err(Error::from_code(n));
1318 }
1319 usize::try_from(n).map_err(|_| Error::InternalError)
1320 }
1321
1322 pub fn final_range(&mut self) -> Result<u32> {
1328 let mut v: u32 = 0;
1329 let r = unsafe {
1330 opus_multistream_decoder_ctl(
1331 self.raw.as_ptr(),
1332 OPUS_GET_FINAL_RANGE_REQUEST as i32,
1333 &mut v,
1334 )
1335 };
1336 if r != 0 {
1337 return Err(Error::from_code(r));
1338 }
1339 Ok(v)
1340 }
1341
1342 pub fn reset(&mut self) -> Result<()> {
1348 let r = unsafe { opus_multistream_decoder_ctl(self.raw.as_ptr(), OPUS_RESET_STATE as i32) };
1349 if r != 0 {
1350 return Err(Error::from_code(r));
1351 }
1352 Ok(())
1353 }
1354
1355 pub fn set_gain(&mut self, q8_db: i32) -> Result<()> {
1361 self.simple_ctl(OPUS_SET_GAIN_REQUEST as i32, q8_db)
1362 }
1363
1364 pub fn gain(&mut self) -> Result<i32> {
1370 self.get_int_ctl(OPUS_GET_GAIN_REQUEST as i32)
1371 }
1372
1373 pub fn set_phase_inversion_disabled(&mut self, disabled: bool) -> Result<()> {
1379 self.simple_ctl(
1380 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST as i32,
1381 i32::from(disabled),
1382 )
1383 }
1384
1385 pub fn phase_inversion_disabled(&mut self) -> Result<bool> {
1391 self.get_bool_ctl(OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST as i32)
1392 }
1393
1394 pub fn get_sample_rate(&mut self) -> Result<i32> {
1400 self.get_int_ctl(OPUS_GET_SAMPLE_RATE_REQUEST as i32)
1401 }
1402
1403 pub fn get_pitch(&mut self) -> Result<i32> {
1413 self.decoder_int_ctl(0, OPUS_GET_PITCH_REQUEST as i32)
1414 }
1415
1416 pub fn get_last_packet_duration(&mut self) -> Result<i32> {
1422 self.get_int_ctl(OPUS_GET_LAST_PACKET_DURATION_REQUEST as i32)
1423 }
1424
1425 #[must_use]
1427 pub const fn channels(&self) -> u8 {
1428 self.channels
1429 }
1430 #[must_use]
1432 pub const fn sample_rate(&self) -> SampleRate {
1433 self.sample_rate
1434 }
1435
1436 pub fn new_surround(
1442 sr: SampleRate,
1443 channels: u8,
1444 mapping_family: i32,
1445 ) -> Result<(Self, Vec<u8>, u8, u8)> {
1446 MultistreamEncoder::surround_size(channels, mapping_family)?;
1447 let (mapping, streams, coupled) =
1448 MultistreamEncoder::surround_mapping(channels, mapping_family)?;
1449 let mut err = 0i32;
1450 let dec = unsafe {
1451 opus_multistream_decoder_create(
1452 sr as i32,
1453 i32::from(channels),
1454 i32::from(streams),
1455 i32::from(coupled),
1456 mapping.as_ptr(),
1457 std::ptr::addr_of_mut!(err),
1458 )
1459 };
1460 if err != 0 {
1461 return Err(Error::from_code(err));
1462 }
1463 let dec = NonNull::new(dec).ok_or(Error::AllocFail)?;
1464 Ok((
1465 Self::from_raw(dec, sr, channels, Ownership::Owned),
1466 mapping,
1467 streams,
1468 coupled,
1469 ))
1470 }
1471
1472 pub unsafe fn decoder_state_ptr(&mut self, stream_index: i32) -> Result<*mut OpusDecoder> {
1482 Ok(self.decoder_state(stream_index)?.as_ptr())
1483 }
1484
1485 fn decoder_state(&mut self, stream_index: i32) -> Result<NonNull<OpusDecoder>> {
1486 let mut state: *mut OpusDecoder = std::ptr::null_mut();
1487 let r = unsafe {
1488 opus_multistream_decoder_ctl(
1489 self.raw.as_ptr(),
1490 OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST as i32,
1491 stream_index,
1492 &mut state,
1493 )
1494 };
1495 if r != 0 {
1496 return Err(Error::from_code(r));
1497 }
1498 NonNull::new(state).ok_or(Error::InternalError)
1499 }
1500
1501 fn decoder_int_ctl(&mut self, stream_index: i32, req: i32) -> Result<i32> {
1502 let state = self.decoder_state(stream_index)?;
1503 let mut value = 0i32;
1504 let r = unsafe { opus_decoder_ctl(state.as_ptr(), req, &mut value) };
1505 if r != 0 {
1506 return Err(Error::from_code(r));
1507 }
1508 Ok(value)
1509 }
1510
1511 fn simple_ctl(&mut self, req: i32, val: i32) -> Result<()> {
1512 let r = unsafe { opus_multistream_decoder_ctl(self.raw.as_ptr(), req, val) };
1513 if r != 0 {
1514 return Err(Error::from_code(r));
1515 }
1516 Ok(())
1517 }
1518
1519 fn get_int_ctl(&mut self, req: i32) -> Result<i32> {
1520 let mut v: i32 = 0;
1521 let r = unsafe { opus_multistream_decoder_ctl(self.raw.as_ptr(), req, &mut v) };
1522 if r != 0 {
1523 return Err(Error::from_code(r));
1524 }
1525 Ok(v)
1526 }
1527
1528 fn get_bool_ctl(&mut self, req: i32) -> Result<bool> {
1529 Ok(self.get_int_ctl(req)? != 0)
1530 }
1531}
1532
1533impl<'a> MultistreamDecoderRef<'a> {
1534 #[must_use]
1551 pub unsafe fn from_raw(ptr: *mut OpusMSDecoder, sr: SampleRate, mapping: Mapping<'_>) -> Self {
1552 assert!(
1553 mapping.validate_for_decoder().is_ok(),
1554 "MultistreamDecoderRef::from_raw called with invalid mapping"
1555 );
1556 let decoder = MultistreamDecoder::from_raw(
1557 crate::checked_non_null(ptr, "MultistreamDecoderRef::from_raw"),
1558 sr,
1559 mapping.channels,
1560 Ownership::Borrowed,
1561 );
1562 Self {
1563 inner: decoder,
1564 _marker: PhantomData,
1565 }
1566 }
1567
1568 pub fn init_in(
1573 buf: &'a mut AlignedBuffer,
1574 sr: SampleRate,
1575 mapping: Mapping<'_>,
1576 ) -> Result<Self> {
1577 let required = MultistreamDecoder::size(mapping.streams, mapping.coupled_streams)?;
1578 if buf.capacity_bytes() < required {
1579 return Err(Error::BadArg);
1580 }
1581 let ptr = buf.as_mut_ptr::<OpusMSDecoder>();
1582 unsafe { MultistreamDecoder::init_in_place(ptr, sr, mapping)? };
1583 Ok(unsafe { Self::from_raw(ptr, sr, mapping) })
1584 }
1585
1586 delegate_ref_mut_methods! {
1587 fn decode(packet: &[u8], out: &mut [i16], frame_size_per_ch: usize, fec: bool) -> Result<usize>;
1588 fn decode_float(packet: &[u8], out: &mut [f32], frame_size_per_ch: usize, fec: bool) -> Result<usize>;
1589 fn final_range() -> Result<u32>;
1590 fn reset() -> Result<()>;
1591 fn set_gain(q8_db: i32) -> Result<()>;
1592 fn gain() -> Result<i32>;
1593 fn set_phase_inversion_disabled(disabled: bool) -> Result<()>;
1594 fn phase_inversion_disabled() -> Result<bool>;
1595 fn get_sample_rate() -> Result<i32>;
1596 fn get_pitch() -> Result<i32>;
1597 fn get_last_packet_duration() -> Result<i32>;
1598 }
1599
1600 delegate_ref_unsafe_mut_methods! {
1601 unsafe fn decoder_state_ptr(stream_index: i32) -> Result<*mut OpusDecoder>;
1602 }
1603}
1604
1605impl Deref for MultistreamDecoderRef<'_> {
1606 type Target = MultistreamDecoder;
1607
1608 fn deref(&self) -> &Self::Target {
1609 &self.inner
1610 }
1611}
1612
1613#[cfg(test)]
1614mod tests {
1615 use super::*;
1616
1617 #[test]
1618 fn mapping_allows_dropped_channels() {
1619 let mapping = Mapping {
1620 channels: 6,
1621 streams: 2,
1622 coupled_streams: 1,
1623 mapping: &[0, 1, 2, u8::MAX, u8::MAX, u8::MAX],
1624 };
1625 assert!(mapping.validate_for_encoder().is_ok());
1626 }
1627
1628 #[test]
1629 fn mapping_requires_encoder_stream_coverage() {
1630 let mapping = Mapping {
1631 channels: 2,
1632 streams: 1,
1633 coupled_streams: 1,
1634 mapping: &[0, 0],
1635 };
1636 assert!(mapping.validate_for_decoder().is_ok());
1637 assert!(mapping.validate_for_encoder().is_err());
1638 }
1639}