1use bitfield::bitfield;
6use bitflags::bitflags;
7use bt_avdtp as avdtp;
8
9bitflags! {
10 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
15 pub struct SbcSamplingFrequency:u8 {
16 const FREQ16000HZ = 0b1000;
17 const FREQ32000HZ = 0b0100;
18 const FREQ44100HZ = 0b0010;
19 const FREQ48000HZ = 0b0001;
20 const MANDATORY_SNK = Self::FREQ44100HZ.bits() | Self::FREQ48000HZ.bits();
21 }
22}
23
24impl SbcSamplingFrequency {
25 fn best(&self) -> Option<Self> {
27 let ordered = [Self::FREQ48000HZ, Self::FREQ44100HZ, Self::FREQ32000HZ, Self::FREQ16000HZ];
28 ordered.iter().find(|freq| self.contains(**freq)).copied()
29 }
30}
31
32bitflags! {
33 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
39 pub struct SbcChannelMode:u8 {
40 const MONO = 0b1000;
41 const DUAL_CHANNEL = 0b0100;
42 const STEREO = 0b0010;
43 const JOINT_STEREO = 0b0001;
44 const MANDATORY_SNK = Self::MONO.bits()
45 | Self::DUAL_CHANNEL.bits()
46 | Self::STEREO.bits()
47 | Self::JOINT_STEREO.bits();
48 }
49}
50
51impl SbcChannelMode {
52 fn best(&self) -> Option<Self> {
53 let ordered = [Self::JOINT_STEREO, Self::STEREO, Self::DUAL_CHANNEL, Self::MONO];
54 ordered.iter().find(|mode| self.contains(**mode)).copied()
55 }
56}
57
58bitflags! {
59 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
63 pub struct SbcBlockCount:u8 {
64 const FOUR = 0b1000;
65 const EIGHT = 0b0100;
66 const TWELVE = 0b0010;
67 const SIXTEEN = 0b0001;
68 const MANDATORY_SNK = Self::FOUR.bits()
69 | Self::EIGHT.bits()
70 | Self::TWELVE.bits()
71 | Self::SIXTEEN.bits();
72 const MANDATORY_SRC = Self::FOUR.bits()
73 | Self::EIGHT.bits()
74 | Self::TWELVE.bits()
75 | Self::SIXTEEN.bits();
76 }
77}
78
79bitflags! {
80 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
86 pub struct SbcSubBands:u8 {
87 const FOUR = 0b0010;
88 const EIGHT = 0b0001;
89 const MANDATORY_SNK = Self::FOUR.bits() | Self::EIGHT.bits();
90 const MANDATORY_SRC = Self::EIGHT.bits();
91 }
92}
93
94bitflags! {
95 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
100 pub struct SbcAllocation:u8 {
101 const SNR = 0b0010;
102 const LOUDNESS = 0b0001;
103 const MANDATORY_SNK = Self::SNR.bits() | Self::LOUDNESS.bits();
104 const MANDATORY_SRC = Self::LOUDNESS.bits();
105 }
106}
107
108pub const SBC_CODEC_EXTRA_LEN: usize = 4;
109
110bitfield! {
111 struct SbcCodecInfoBits(u32);
119 impl Debug;
120 u8;
121 maxbitpoolval, set_maxbpv: 7, 0;
122 minbitpoolval, set_minbpv: 15, 8;
123 allocation_method, set_allocation_method: 17,16;
124 sub_bands, set_sub_bands: 19, 18;
125 block_count, set_block_count: 23, 20;
126 channel_mode, set_channel_mode: 27, 24;
127 sampling_frequency, set_sampling_frequency: 31, 28;
128}
129
130#[derive(Debug)]
131pub struct SbcCodecInfo(SbcCodecInfoBits);
132
133impl SbcCodecInfo {
134 pub const BITPOOL_MIN: u8 = 2;
136 pub const BITPOOL_MAX: u8 = 250;
137 pub fn new(
138 sampling_frequency: SbcSamplingFrequency,
139 channel_mode: SbcChannelMode,
140 block_count: SbcBlockCount,
141 sub_bands: SbcSubBands,
142 allocation: SbcAllocation,
143 min_bpv: u8,
144 max_bpv: u8,
145 ) -> avdtp::Result<Self> {
146 if min_bpv > max_bpv {
147 return Err(avdtp::Error::OutOfRange);
148 }
149 if min_bpv < Self::BITPOOL_MIN
150 || min_bpv > Self::BITPOOL_MAX
151 || max_bpv < Self::BITPOOL_MIN
152 || max_bpv > Self::BITPOOL_MAX
153 {
154 return Err(avdtp::Error::OutOfRange);
155 }
156
157 let mut res = SbcCodecInfoBits(0);
158 res.set_maxbpv(max_bpv);
159 res.set_minbpv(min_bpv);
160 res.set_allocation_method(allocation.bits());
161 res.set_sub_bands(sub_bands.bits());
162 res.set_block_count(block_count.bits());
163 res.set_channel_mode(channel_mode.bits());
164 res.set_sampling_frequency(sampling_frequency.bits());
165 Ok(Self(res))
166 }
167
168 pub fn to_bytes(&self) -> [u8; 4] {
169 (self.0).0.to_be_bytes()
170 }
171
172 pub fn sub_bands(&self) -> SbcSubBands {
173 SbcSubBands::from_bits_truncate(self.0.sub_bands())
174 }
175
176 pub fn allocation_method(&self) -> SbcAllocation {
177 SbcAllocation::from_bits_truncate(self.0.allocation_method())
178 }
179
180 pub fn block_count(&self) -> SbcBlockCount {
181 SbcBlockCount::from_bits_truncate(self.0.block_count())
182 }
183
184 pub fn channel_mode(&self) -> SbcChannelMode {
185 SbcChannelMode::from_bits_truncate(self.0.channel_mode())
186 }
187
188 pub fn channel_count(&self) -> avdtp::Result<usize> {
191 let chan_mode = self.channel_mode();
192 if chan_mode == SbcChannelMode::MONO {
193 return Ok(1);
194 } else if !chan_mode.is_empty() && (chan_mode & SbcChannelMode::MONO).is_empty() {
195 return Ok(2);
196 }
197 Err(avdtp::Error::OutOfRange)
198 }
199
200 pub fn max_bitpool(&self) -> u8 {
201 self.0.maxbitpoolval()
202 }
203
204 pub fn sampling_frequency(&self) -> avdtp::Result<u32> {
207 let hz = match SbcSamplingFrequency::from_bits_truncate(self.0.sampling_frequency()) {
208 SbcSamplingFrequency::FREQ16000HZ => 16000,
209 SbcSamplingFrequency::FREQ32000HZ => 32000,
210 SbcSamplingFrequency::FREQ44100HZ => 44100,
211 SbcSamplingFrequency::FREQ48000HZ => 48000,
212 _ => return Err(avdtp::Error::OutOfRange),
213 };
214 Ok(hz)
215 }
216
217 pub fn supports(&self, other: &Self) -> bool {
219 let allowed_frequencies =
220 SbcSamplingFrequency::from_bits_truncate(self.0.sampling_frequency());
221 let selected_frequencies =
222 SbcSamplingFrequency::from_bits_truncate(other.0.sampling_frequency());
223 if !(allowed_frequencies.intersects(selected_frequencies)) {
224 return false;
225 }
226 if !(self.allocation_method().intersects(other.allocation_method())) {
227 return false;
228 }
229 if !(self.channel_mode().intersects(other.channel_mode())) {
230 return false;
231 }
232 if !(self.block_count().intersects(other.block_count())) {
233 return false;
234 }
235 if !(self.sub_bands().intersects(other.sub_bands())) {
236 return false;
237 }
238 if self.0.minbitpoolval() > other.0.minbitpoolval() {
239 return false;
240 }
241 if self.0.maxbitpoolval() < other.0.maxbitpoolval() {
242 return false;
243 }
244 return true;
245 }
246
247 pub fn negotiate(a: &Self, b: &Self) -> Option<Self> {
249 let min_bitpool = std::cmp::max(a.0.minbitpoolval(), b.0.minbitpoolval());
250 let max_bitpool = std::cmp::min(a.0.maxbitpoolval(), b.0.maxbitpoolval());
251 if max_bitpool < min_bitpool {
252 return None;
253 }
254 let available_frequencies = SbcSamplingFrequency::from_bits_truncate(
255 a.0.sampling_frequency() & b.0.sampling_frequency(),
256 );
257 let frequency = available_frequencies.best()?;
258 let available_mode = a.channel_mode() & b.channel_mode();
259 let channel_mode = available_mode.best()?;
260 let allocation = SbcAllocation::LOUDNESS;
262 let block_count = SbcBlockCount::SIXTEEN;
263 let sub_bands = SbcSubBands::EIGHT;
264 Some(
265 SbcCodecInfo::new(
266 frequency,
267 channel_mode,
268 block_count,
269 sub_bands,
270 allocation,
271 min_bitpool,
272 max_bitpool,
273 )
274 .expect("supported options"),
275 )
276 }
277}
278
279impl TryFrom<&[u8]> for SbcCodecInfo {
280 type Error = avdtp::Error;
281
282 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
283 if value.len() != SBC_CODEC_EXTRA_LEN {
284 return Err(avdtp::Error::OutOfRange);
285 }
286
287 let mut codec_info_bytes = [0_u8; SBC_CODEC_EXTRA_LEN];
288 codec_info_bytes.copy_from_slice(&value);
289
290 Ok(Self(SbcCodecInfoBits(u32::from_be_bytes(codec_info_bytes))))
291 }
292}
293
294impl From<SbcCodecInfo> for avdtp::ServiceCapability {
295 fn from(codec_info: SbcCodecInfo) -> Self {
296 Self::MediaCodec {
297 media_type: avdtp::MediaType::Audio,
298 codec_type: avdtp::MediaCodecType::AUDIO_SBC,
299 codec_extra: codec_info.to_bytes().to_vec(),
300 }
301 }
302}
303
304bitflags! {
305 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
310 pub struct AacObjectType:u8 {
311 const MPEG2_AAC_LC = 0b10000000;
312 const MPEG4_AAC_LC = 0b01000000;
313 const MPEG4_AAC_LTP = 0b00100000;
314 const MPEG4_AAC_SCALABLE = 0b00010000;
315 const MANDATORY_SNK = Self::MPEG2_AAC_LC.bits();
316 const MANDATORY_SRC = Self::MPEG2_AAC_LC.bits();
317 }
318}
319
320bitflags! {
321 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
326 pub struct AacSamplingFrequency:u16 {
327 const FREQ8000HZ = 0b100000000000;
328 const FREQ11025HZ = 0b010000000000;
329 const FREQ12000HZ = 0b001000000000;
330 const FREQ16000HZ = 0b000100000000;
331 const FREQ22050HZ = 0b000010000000;
332 const FREQ24000HZ = 0b000001000000;
333 const FREQ32000HZ = 0b000000100000;
334 const FREQ44100HZ = 0b000000010000;
335 const FREQ48000HZ = 0b000000001000;
336 const FREQ64000HZ = 0b000000000100;
337 const FREQ88200HZ = 0b000000000010;
338 const FREQ96000HZ = 0b000000000001;
339 const MANDATORY_SNK = Self::FREQ44100HZ.bits() | Self::FREQ48000HZ.bits();
340 }
341}
342
343impl AacSamplingFrequency {
344 fn best(&self) -> Option<Self> {
345 let ordered = [Self::FREQ96000HZ, Self::FREQ48000HZ, Self::FREQ44100HZ];
347 ordered.iter().find(|freq| self.contains(**freq)).copied()
348 }
349}
350
351bitflags! {
352 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
357 pub struct AacChannels:u8 {
358 const ONE = 0b10;
359 const TWO = 0b01;
360 const MANDATORY_SNK = Self::ONE.bits() | Self::TWO.bits();
361 }
362}
363
364impl AacChannels {
365 fn best(&self) -> Option<Self> {
366 let ordered = [Self::TWO, Self::ONE];
367 ordered.iter().find(|channels| self.contains(**channels)).copied()
368 }
369}
370
371bitflags! {
372 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
376 struct AacVariableBitRate: u8 {
377 const VBR_SUPPORTED = 0b1;
378 const MANDATORY_SNK = Self::VBR_SUPPORTED.bits();
379 }
380}
381
382pub const AAC_CODEC_EXTRA_LEN: usize = 6;
383
384bitfield! {
385 struct AacCodecInfoBits(u64);
395 impl Debug;
396 u8;
397 u32, bitrate, set_bitrate: 22, 0;
398 vbr, set_vbr: 23, 23;
399 channels, set_channels: 27,26;
401 u16, sampling_frequency, set_sampling_frequency: 39, 28;
402 object_type, set_object_type: 47, 40;
403 }
405
406#[derive(Debug)]
407pub struct AacCodecInfo(AacCodecInfoBits);
408
409impl AacCodecInfo {
410 pub fn new(
411 object_type: AacObjectType,
412 sampling_frequency: AacSamplingFrequency,
413 channels: AacChannels,
414 vbr: bool,
415 bitrate: u32,
416 ) -> avdtp::Result<Self> {
417 if bitrate > 0x7fffff {
419 return Err(avdtp::Error::OutOfRange);
420 }
421 let mut res = AacCodecInfoBits(0);
422 res.set_bitrate(bitrate);
423 if vbr {
424 res.set_vbr(AacVariableBitRate::VBR_SUPPORTED.bits());
425 }
426 res.set_channels(channels.bits());
427 res.set_sampling_frequency(sampling_frequency.bits());
428 res.set_object_type(object_type.bits());
429 Ok(Self(res))
430 }
431
432 pub fn to_bytes(&self) -> [u8; 6] {
435 let codec_info = (self.0).0.to_be_bytes();
436 let mut res = [0u8; 6];
437 res.copy_from_slice(&codec_info[2..8]);
438 res
439 }
440
441 pub fn variable_bit_rate(&self) -> bool {
442 self.0.vbr() == 0b1
443 }
444
445 pub fn bitrate(&self) -> u32 {
446 self.0.bitrate()
447 }
448
449 pub fn channels(&self) -> AacChannels {
450 AacChannels::from_bits_truncate(self.0.channels())
451 }
452
453 pub fn channel_count(&self) -> avdtp::Result<usize> {
456 let count = match self.channels() {
457 AacChannels::ONE => 1,
458 AacChannels::TWO => 2,
459 _ => return Err(avdtp::Error::OutOfRange),
460 };
461 Ok(count)
462 }
463
464 fn object_type(&self) -> AacObjectType {
465 AacObjectType::from_bits_truncate(self.0.object_type())
466 }
467
468 pub fn sampling_frequency(&self) -> avdtp::Result<u32> {
471 let hz = match AacSamplingFrequency::from_bits_truncate(self.0.sampling_frequency()) {
472 AacSamplingFrequency::FREQ8000HZ => 8000,
473 AacSamplingFrequency::FREQ11025HZ => 11025,
474 AacSamplingFrequency::FREQ12000HZ => 12000,
475 AacSamplingFrequency::FREQ16000HZ => 16000,
476 AacSamplingFrequency::FREQ22050HZ => 22050,
477 AacSamplingFrequency::FREQ24000HZ => 24000,
478 AacSamplingFrequency::FREQ32000HZ => 32000,
479 AacSamplingFrequency::FREQ44100HZ => 44100,
480 AacSamplingFrequency::FREQ48000HZ => 48000,
481 AacSamplingFrequency::FREQ64000HZ => 64000,
482 AacSamplingFrequency::FREQ88200HZ => 88200,
483 AacSamplingFrequency::FREQ96000HZ => 96000,
484 _ => return Err(avdtp::Error::OutOfRange),
485 };
486 Ok(hz)
487 }
488
489 pub fn supports(&self, other: &Self) -> bool {
491 let allowed_frequencies =
492 AacSamplingFrequency::from_bits_truncate(self.0.sampling_frequency());
493 let selected_frequencies =
494 AacSamplingFrequency::from_bits_truncate(other.0.sampling_frequency());
495 if !(allowed_frequencies.intersects(selected_frequencies)) {
496 return false;
497 }
498 if !(self.channels().intersects(other.channels())) {
499 return false;
500 }
501 if !(self.object_type().intersects(other.object_type())) {
502 return false;
503 }
504 if !self.variable_bit_rate() && other.variable_bit_rate() {
505 return false;
506 }
507 if self.bitrate() != 0 && (self.bitrate() < other.bitrate()) {
512 return false;
513 }
514 return true;
515 }
516
517 pub fn negotiate(a: &Self, b: &Self) -> Option<Self> {
518 let available_frequencies = AacSamplingFrequency::from_bits_truncate(
519 a.0.sampling_frequency() & b.0.sampling_frequency(),
520 );
521 let sampling_frequency = available_frequencies.best()?;
522 let available_channels = a.channels() & b.channels();
523 let channels = available_channels.best()?;
524 let vbr = a.variable_bit_rate() && b.variable_bit_rate();
525 let bitrate = match (a.bitrate(), b.bitrate()) {
528 (0, 0) => 128000,
530 (0, b) => b,
531 (a, 0) => a,
532 (a, b) => std::cmp::min(a, b),
533 };
534 let object_type = AacObjectType::MPEG2_AAC_LC;
536 Some(AacCodecInfo::new(object_type, sampling_frequency, channels, vbr, bitrate).unwrap())
537 }
538}
539
540impl TryFrom<&[u8]> for AacCodecInfo {
541 type Error = avdtp::Error;
542
543 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
545 if value.len() != AAC_CODEC_EXTRA_LEN {
546 return Err(avdtp::Error::OutOfRange);
547 }
548 let mut codec_info_bytes = [0_u8; 8];
549 let codec_info_slice = &mut codec_info_bytes[2..8];
550 codec_info_slice.copy_from_slice(&value);
553 Ok(Self(AacCodecInfoBits(u64::from_be_bytes(codec_info_bytes))))
554 }
555}
556
557impl From<AacCodecInfo> for avdtp::ServiceCapability {
558 fn from(codec_info: AacCodecInfo) -> Self {
559 Self::MediaCodec {
560 media_type: avdtp::MediaType::Audio,
561 codec_type: avdtp::MediaCodecType::AUDIO_AAC,
562 codec_extra: codec_info.to_bytes().to_vec(),
563 }
564 }
565}
566
567#[cfg(test)]
568mod tests {
569 use super::*;
570 use assert_matches::assert_matches;
571
572 #[test]
573 fn test_sbc_codec_info() {
575 let sbc_codec_info: SbcCodecInfo = SbcCodecInfo::new(
577 SbcSamplingFrequency::MANDATORY_SNK,
578 SbcChannelMode::MANDATORY_SNK,
579 SbcBlockCount::MANDATORY_SNK,
580 SbcSubBands::MANDATORY_SNK,
581 SbcAllocation::MANDATORY_SNK,
582 2,
583 250,
584 )
585 .expect("Couldn't create sbc media codec info.");
586 let res = sbc_codec_info.to_bytes();
587 let codec_extra: Vec<u8> = vec![0x3F, 0xFF, 2, 250];
588 assert_eq!(codec_extra, res);
589
590 let res = SbcCodecInfo::try_from(&codec_extra[..]).expect("created codec info");
592 assert_eq!((res.0).0, (sbc_codec_info.0).0);
593
594 let sbc_codec_info: SbcCodecInfo = SbcCodecInfo::new(
596 SbcSamplingFrequency::FREQ44100HZ,
597 SbcChannelMode::MONO | SbcChannelMode::DUAL_CHANNEL,
598 SbcBlockCount::MANDATORY_SRC,
599 SbcSubBands::MANDATORY_SRC,
600 SbcAllocation::MANDATORY_SRC,
601 2,
602 250,
603 )
604 .expect("Couldn't create sbc media codec info.");
605 let res = sbc_codec_info.to_bytes();
606 assert_eq!(vec![0x2C, 0xF5, 2, 250], res);
607
608 let sbc_codec_info: SbcCodecInfo = SbcCodecInfo::new(
610 SbcSamplingFrequency::empty(),
611 SbcChannelMode::empty(),
612 SbcBlockCount::empty(),
613 SbcSubBands::empty(),
614 SbcAllocation::empty(),
615 2,
616 250,
617 )
618 .expect("Couldn't create sbc media codec info.");
619 assert_matches!(sbc_codec_info.channel_count(), Err(avdtp::Error::OutOfRange));
620 let res = sbc_codec_info.to_bytes();
621 assert_eq!(vec![0x00, 0x00, 2, 250], res);
622
623 let sbc_codec_info: SbcCodecInfo = SbcCodecInfo::new(
625 SbcSamplingFrequency::all(),
626 SbcChannelMode::all(),
627 SbcBlockCount::all(),
628 SbcSubBands::all(),
629 SbcAllocation::all(),
630 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
633 .expect("Couldn't create sbc media codec info.");
634 assert_matches!(sbc_codec_info.channel_count(), Err(avdtp::Error::OutOfRange));
635 let res = sbc_codec_info.to_bytes();
636 assert_eq!(vec![0xFF, 0xFF, 2, 250], res);
637
638 let sbc_codec_info = SbcCodecInfo::new(
640 SbcSamplingFrequency::all(),
641 SbcChannelMode::all(),
642 SbcBlockCount::all(),
643 SbcSubBands::all(),
644 SbcAllocation::all(),
645 20,
646 252, );
648 assert!(sbc_codec_info.is_err());
649
650 let sbc_codec_info = SbcCodecInfo::new(
652 SbcSamplingFrequency::all(),
653 SbcChannelMode::all(),
654 SbcBlockCount::all(),
655 SbcSubBands::all(),
656 SbcAllocation::all(),
657 0, 240,
659 );
660 assert!(sbc_codec_info.is_err());
661
662 let sbc_codec_info = SbcCodecInfo::new(
664 SbcSamplingFrequency::all(),
665 SbcChannelMode::all(),
666 SbcBlockCount::all(),
667 SbcSubBands::all(),
668 SbcAllocation::all(),
669 100,
670 50,
671 );
672 assert!(sbc_codec_info.is_err());
673
674 let empty = vec![0, 0, 0, 0];
675 let res = SbcCodecInfo::try_from(&empty[..]).expect("created codec info");
676 assert_eq!((res.0).0, 0);
677
678 let too_big = vec![0, 0, 0, 0, 0];
679 assert_matches!(SbcCodecInfo::try_from(&too_big[..]), Err(avdtp::Error::OutOfRange));
680
681 let sbc_codec_info: SbcCodecInfo = SbcCodecInfo::new(
683 SbcSamplingFrequency::FREQ44100HZ,
684 SbcChannelMode::MONO,
685 SbcBlockCount::MANDATORY_SRC,
686 SbcSubBands::MANDATORY_SRC,
687 SbcAllocation::MANDATORY_SRC,
688 2,
689 250,
690 )
691 .expect("Couldn't create sbc media codec info.");
692 assert_matches!(sbc_codec_info.channel_count(), Ok(1));
693
694 let sbc_codec_info: SbcCodecInfo = SbcCodecInfo::new(
695 SbcSamplingFrequency::FREQ44100HZ,
696 SbcChannelMode::JOINT_STEREO,
697 SbcBlockCount::MANDATORY_SRC,
698 SbcSubBands::MANDATORY_SRC,
699 SbcAllocation::MANDATORY_SRC,
700 2,
701 250,
702 )
703 .expect("Couldn't create sbc media codec info.");
704 assert_matches!(sbc_codec_info.channel_count(), Ok(2));
705 }
706
707 #[test]
708 fn test_sbc_codec_supports() {
709 let sbc_codec_all = SbcCodecInfo::new(
710 SbcSamplingFrequency::all(),
711 SbcChannelMode::all(),
712 SbcBlockCount::all(),
713 SbcSubBands::all(),
714 SbcAllocation::all(),
715 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
718 .expect("Couldn't create sbc media codec info.");
719 assert!(sbc_codec_all.supports(&sbc_codec_all));
721
722 let sbc_codec_441 = SbcCodecInfo::new(
723 SbcSamplingFrequency::FREQ44100HZ,
724 SbcChannelMode::all(),
725 SbcBlockCount::all(),
726 SbcSubBands::all(),
727 SbcAllocation::all(),
728 53, SbcCodecInfo::BITPOOL_MAX, )
731 .expect("Couldn't create sbc media codec info.");
732
733 let sbc_codec_48 = SbcCodecInfo::new(
734 SbcSamplingFrequency::FREQ48000HZ,
735 SbcChannelMode::all(),
736 SbcBlockCount::all(),
737 SbcSubBands::all(),
738 SbcAllocation::all(),
739 SbcCodecInfo::BITPOOL_MIN, 53, )
742 .expect("Couldn't create sbc media codec info.");
743
744 assert!(sbc_codec_all.supports(&sbc_codec_441));
745 assert!(sbc_codec_all.supports(&sbc_codec_48));
746
747 assert!(!sbc_codec_48.supports(&sbc_codec_441));
749 assert!(!sbc_codec_441.supports(&sbc_codec_48));
750
751 assert!(!sbc_codec_48.supports(&sbc_codec_all));
753 assert!(!sbc_codec_441.supports(&sbc_codec_all));
754
755 let sbc_codec_mono = SbcCodecInfo::new(
756 SbcSamplingFrequency::all(),
757 SbcChannelMode::MONO,
758 SbcBlockCount::all(),
759 SbcSubBands::all(),
760 SbcAllocation::all(),
761 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
764 .expect("Couldn't create sbc media codec info.");
765 let sbc_codec_stereo = SbcCodecInfo::new(
766 SbcSamplingFrequency::all(),
767 SbcChannelMode::JOINT_STEREO,
768 SbcBlockCount::all(),
769 SbcSubBands::all(),
770 SbcAllocation::all(),
771 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
774 .expect("Couldn't create sbc media codec info.");
775
776 assert!(sbc_codec_all.supports(&sbc_codec_mono));
777 assert!(sbc_codec_all.supports(&sbc_codec_stereo));
778 assert!(!sbc_codec_mono.supports(&sbc_codec_stereo));
779 assert!(!sbc_codec_stereo.supports(&sbc_codec_mono));
780
781 let sbc_codec_blocks_4 = SbcCodecInfo::new(
782 SbcSamplingFrequency::all(),
783 SbcChannelMode::all(),
784 SbcBlockCount::FOUR,
785 SbcSubBands::all(),
786 SbcAllocation::all(),
787 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
790 .expect("Couldn't create sbc media codec info.");
791 let sbc_codec_blocks_8 = SbcCodecInfo::new(
792 SbcSamplingFrequency::all(),
793 SbcChannelMode::all(),
794 SbcBlockCount::EIGHT,
795 SbcSubBands::all(),
796 SbcAllocation::all(),
797 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
800 .expect("Couldn't create sbc media codec info.");
801
802 assert!(sbc_codec_all.supports(&sbc_codec_blocks_4));
803 assert!(sbc_codec_all.supports(&sbc_codec_blocks_8));
804 assert!(!sbc_codec_blocks_4.supports(&sbc_codec_blocks_8));
805 assert!(!sbc_codec_blocks_8.supports(&sbc_codec_blocks_4));
806
807 let sbc_codec_bands_4 = SbcCodecInfo::new(
808 SbcSamplingFrequency::all(),
809 SbcChannelMode::all(),
810 SbcBlockCount::FOUR,
811 SbcSubBands::FOUR,
812 SbcAllocation::all(),
813 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
816 .expect("Couldn't create sbc media codec info.");
817 let sbc_codec_bands_8 = SbcCodecInfo::new(
818 SbcSamplingFrequency::all(),
819 SbcChannelMode::all(),
820 SbcBlockCount::FOUR,
821 SbcSubBands::EIGHT,
822 SbcAllocation::all(),
823 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
826 .expect("Couldn't create sbc media codec info.");
827
828 assert!(sbc_codec_all.supports(&sbc_codec_bands_4));
829 assert!(sbc_codec_all.supports(&sbc_codec_bands_8));
830 assert!(!sbc_codec_bands_4.supports(&sbc_codec_bands_8));
831 assert!(!sbc_codec_bands_8.supports(&sbc_codec_bands_4));
832
833 let sbc_codec_snr = SbcCodecInfo::new(
834 SbcSamplingFrequency::all(),
835 SbcChannelMode::all(),
836 SbcBlockCount::FOUR,
837 SbcSubBands::FOUR,
838 SbcAllocation::SNR,
839 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
842 .expect("Couldn't create sbc media codec info.");
843 let sbc_codec_loudness = SbcCodecInfo::new(
844 SbcSamplingFrequency::all(),
845 SbcChannelMode::all(),
846 SbcBlockCount::FOUR,
847 SbcSubBands::FOUR,
848 SbcAllocation::LOUDNESS,
849 SbcCodecInfo::BITPOOL_MIN, SbcCodecInfo::BITPOOL_MAX, )
852 .expect("Couldn't create sbc media codec info.");
853
854 assert!(sbc_codec_all.supports(&sbc_codec_snr));
855 assert!(sbc_codec_all.supports(&sbc_codec_loudness));
856 assert!(!sbc_codec_snr.supports(&sbc_codec_loudness));
857 assert!(!sbc_codec_loudness.supports(&sbc_codec_snr));
858 }
859
860 #[test]
861 fn test_aac_codec_info() {
862 let aac_codec_info = AacCodecInfo::new(
864 AacObjectType::empty(),
865 AacSamplingFrequency::empty(),
866 AacChannels::empty(),
867 false,
868 0,
869 )
870 .expect("Error creating aac media codec info.");
871 let res = aac_codec_info.to_bytes();
872 assert_eq!(vec![0, 0, 0, 0, 0, 0], res);
873
874 let aac_codec_info = AacCodecInfo::new(
876 AacObjectType::all(),
877 AacSamplingFrequency::all(),
878 AacChannels::all(),
879 true,
880 8388607, )
882 .expect("Error creating aac media codec info.");
883 assert_matches!(aac_codec_info.channel_count(), Err(avdtp::Error::OutOfRange));
884 let res = aac_codec_info.to_bytes();
885 assert_eq!(vec![0xF0, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF], res);
886
887 let aac_codec_info = AacCodecInfo::new(
889 AacObjectType::empty(),
890 AacSamplingFrequency::empty(),
891 AacChannels::empty(),
892 true,
893 0,
894 )
895 .expect("Error creating aac media codec info.");
896 assert_matches!(aac_codec_info.channel_count(), Err(avdtp::Error::OutOfRange));
897 let res = aac_codec_info.to_bytes();
898 assert_eq!(vec![0x00, 0x00, 0x00, 0x80, 0x00, 0x00], res);
899
900 let aac_codec_info = AacCodecInfo::new(
902 AacObjectType::MANDATORY_SNK,
903 AacSamplingFrequency::MANDATORY_SNK,
904 AacChannels::MANDATORY_SNK,
905 true,
906 0xAAFF, )
908 .expect("Error creating aac media codec info.");
909 let res = aac_codec_info.to_bytes();
910 let codec_extra: Vec<u8> = vec![0x80, 0x01, 0x8C, 0x80, 0xAA, 0xFF];
911 assert_eq!(codec_extra, res);
912
913 let res = AacCodecInfo::try_from(&codec_extra[..]).expect("created codec info");
915 assert_eq!((res.0).0, (aac_codec_info.0).0);
916
917 let aac_codec_info = AacCodecInfo::new(
919 AacObjectType::MANDATORY_SRC,
920 AacSamplingFrequency::FREQ44100HZ,
921 AacChannels::ONE,
922 false, 0xAAFF, )
925 .expect("Error creating aac media codec info.");
926 assert_matches!(aac_codec_info.channel_count(), Ok(1));
927 let res = aac_codec_info.to_bytes();
928 assert_eq!(vec![0x80, 0x01, 0x08, 0x00, 0xAA, 0xFF], res);
929
930 let aac_codec_info = AacCodecInfo::new(
932 AacObjectType::MANDATORY_SRC,
933 AacSamplingFrequency::FREQ44100HZ,
934 AacChannels::TWO,
935 false, 0xAAFF, )
938 .expect("Error creating aac media codec info.");
939 assert_matches!(aac_codec_info.channel_count(), Ok(2));
940
941 let aac_codec_info = AacCodecInfo::new(
943 AacObjectType::MANDATORY_SRC,
944 AacSamplingFrequency::FREQ44100HZ,
945 AacChannels::ONE,
946 false,
947 0xFFFFFF, );
949 assert!(aac_codec_info.is_err());
950
951 let empty = vec![0, 0, 0, 0, 0, 0];
952 let res = AacCodecInfo::try_from(&empty[..]).expect("created codec info");
953 assert_eq!((res.0).0, 0);
954
955 let too_big = vec![0, 0, 0, 0, 0, 0, 0];
956 assert_matches!(AacCodecInfo::try_from(&too_big[..]), Err(avdtp::Error::OutOfRange));
957 }
958
959 #[test]
960 fn test_aac_codec_supports() {
961 let aac_codec_all = AacCodecInfo::new(
963 AacObjectType::all(),
964 AacSamplingFrequency::all(),
965 AacChannels::all(),
966 true,
967 8388607, )
969 .expect("Error creating aac media codec info.");
970
971 assert!(aac_codec_all.supports(&aac_codec_all));
972
973 let aac_codec_441 = AacCodecInfo::new(
974 AacObjectType::all(),
975 AacSamplingFrequency::FREQ44100HZ,
976 AacChannels::all(),
977 true,
978 50, )
980 .expect("Error creating aac media codec info.");
981
982 let aac_codec_48 = AacCodecInfo::new(
983 AacObjectType::all(),
984 AacSamplingFrequency::FREQ48000HZ,
985 AacChannels::all(),
986 true,
987 8388607, )
989 .expect("Error creating aac media codec info.");
990
991 assert!(aac_codec_all.supports(&aac_codec_441));
992 assert!(aac_codec_all.supports(&aac_codec_48));
993
994 assert!(!aac_codec_441.supports(&aac_codec_48));
996 assert!(!aac_codec_48.supports(&aac_codec_441));
997
998 assert!(!aac_codec_441.supports(&aac_codec_all));
1000
1001 let aac_codec_chan_one = AacCodecInfo::new(
1003 AacObjectType::all(),
1004 AacSamplingFrequency::all(),
1005 AacChannels::ONE,
1006 true,
1007 8388607, )
1009 .expect("Error creating aac media codec info.");
1010
1011 let aac_codec_chan_two = AacCodecInfo::new(
1012 AacObjectType::all(),
1013 AacSamplingFrequency::all(),
1014 AacChannels::TWO,
1015 true,
1016 8388607, )
1018 .expect("Error creating aac media codec info.");
1019
1020 assert!(aac_codec_all.supports(&aac_codec_chan_one));
1021 assert!(aac_codec_all.supports(&aac_codec_chan_two));
1022 assert!(!aac_codec_chan_one.supports(&aac_codec_chan_two));
1023 assert!(!aac_codec_chan_two.supports(&aac_codec_chan_one));
1024
1025 let aac_codec_mpeg2 = AacCodecInfo::new(
1027 AacObjectType::MPEG2_AAC_LC,
1028 AacSamplingFrequency::all(),
1029 AacChannels::ONE,
1030 true,
1031 8388607, )
1033 .expect("Error creating aac media codec info.");
1034
1035 let aac_codec_mpeg4 = AacCodecInfo::new(
1036 AacObjectType::MPEG4_AAC_LC,
1037 AacSamplingFrequency::all(),
1038 AacChannels::ONE,
1039 true,
1040 8388607, )
1042 .expect("Error creating aac media codec info.");
1043
1044 assert!(aac_codec_all.supports(&aac_codec_mpeg2));
1045 assert!(aac_codec_all.supports(&aac_codec_mpeg4));
1046 assert!(!aac_codec_mpeg2.supports(&aac_codec_mpeg4));
1047 assert!(!aac_codec_mpeg4.supports(&aac_codec_mpeg2));
1048
1049 let aac_codec_not_vbr = AacCodecInfo::new(
1050 AacObjectType::MPEG4_AAC_LC,
1051 AacSamplingFrequency::all(),
1052 AacChannels::ONE,
1053 false,
1054 8388607, )
1056 .expect("Error creating aac media codec info.");
1057
1058 assert!(!aac_codec_not_vbr.supports(&aac_codec_mpeg4));
1059
1060 let aac_codec_bitrate_not_known = AacCodecInfo::new(
1061 AacObjectType::MPEG4_AAC_LC,
1062 AacSamplingFrequency::all(),
1063 AacChannels::ONE,
1064 true,
1065 0, )
1067 .expect("Error creating aac media codec info.");
1068
1069 assert!(aac_codec_bitrate_not_known.supports(&aac_codec_not_vbr));
1070 }
1071}