Skip to main content

bt_a2dp/
media_types.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use bitfield::bitfield;
6use bitflags::bitflags;
7use bt_avdtp as avdtp;
8
9bitflags! {
10    /// Sampling Frequency field for SBC (Octet 0; b4-7).
11    /// 44100Hz and 48000Hz are mandatory for A2DP sink.
12    /// A2DP source must support at least one of 44100Hz and 48000Hz.
13    /// A2DP Sec. 4.3.2.1
14    #[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    /// Select the "best" sampling frequency of the ones available.
26    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    /// Channel Mode field for SBC (Octet 0; b0-3).
34    /// Support for all modes is mandatory in A2DP sink.
35    /// Mono and at least one of Dual Channel, Stereo, and Joint Stereo must be
36    /// supported by A2DP source.
37    /// A2DP Sec. 4.3.2.2
38    #[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    /// The Block Length field for SBC (Octet 1; b4-7).
60    /// Support for all block lengths is mandatory in both A2DP Sink and Source.
61    /// A2DP Sec. 4.3.2.3
62    #[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    /// The Number of Subbands field for SBC (Octet 1; b2-3).
81    /// Support for both 4 and 8 subbands is mandatory in A2DP Sink.
82    /// Support for only 8 subbands is mandatory in A2DP Source.
83    /// 4 subbands is optional.
84    /// A2DP Sec. 4.3.2.4
85    #[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    /// Allocation Method field for SBC (Octet 1; b0-1).
96    /// Support for both SNR and Loudness is mandatory in A2DP Sink.
97    /// Support for at least Loudness is mandatory in A2DP Source. SNR is optional.
98    /// A2DP Sec. 4.3.2.5
99    #[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    /// SBC Codec Specific Information Elements (A2DP Sec. 4.3.2).
112    /// Packet structure:
113    ///     Octet0: Sampling Frequency (b4-7), Channel Mode (b0-3)
114    ///     Octet1: Block Length (b4-7), Subbands (b2-3), Allocation Method (b0-1)
115    ///     Octet2: Minimum Bitpool Value [2,250]
116    ///     Octet3: Maximum Bitpool Value [2,250]
117    /// Some fields are mandatory choose 1, and therefore do not have a mandatory parameter method.
118    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    // Bitpool values can range from [2,250].
135    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    /// Returns the number of channels selected.
189    /// Returns Error::OutOfRange if both mono and stereo are selected.
190    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    /// Returns the sampling frequency selected, in hz.
205    /// Returns Error::OutOfRange if multiple frequencies are selected.
206    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    /// Returns true if `other` is a compatible configuration of `self`
218    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    /// Return the best intersection of a and b's capabilities, if one exists.
248    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        // All sources and sinks must support these options. A2DP 1.3.2 Sec 4.3.2
261        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    /// Object Type field for MPEG-2,4 AAC (Octet 0; b0-7).
306    /// Support for MPEG-2 AAC LC is mandatory in both A2DP Sink and Source.
307    /// Bits 0 to 4 are RFA.
308    /// A2DP Sec. 4.5.2.1
309    #[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    /// Sampling Frequency field for MPEG-2,4 AAC (Octet 1; b0-7, Octet 2; b4-7)
322    /// Support for 44.1KHz & 48.0KHz is mandatory in A2DP Sink.
323    /// Support for either 44.1KHz or 48.0KHz is mandatory in A2DP Source.
324    /// A2DP Sec. 4.5.2.2
325    #[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        // Since one of 48000 or 44100 is mandatory, this list should find one.
346        let ordered = [Self::FREQ96000HZ, Self::FREQ48000HZ, Self::FREQ44100HZ];
347        ordered.iter().find(|freq| self.contains(**freq)).copied()
348    }
349}
350
351bitflags! {
352    /// Channels field for MPEG-2,4 AAC (Octet 2; b2-3).
353    /// Support for both 1 and 2 channels is mandatory in A2DP Sink.
354    /// Support for either 1 or 2 channels is mandatory in A2DP Source.
355    /// A2DP Sec 4.5.2.3
356    #[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    /// Support of Variable Bit Rate (VBR) field for MPEG-2,4 AAC (Octet 3; b7).
373    /// Support for VBR is mandatory in A2DP Sink.
374    /// A2DP Sec 4.5.2.5
375    #[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    /// MPEG-2 AAC Codec Specific Information Elements (A2DP Sec 4.5.2)
386    /// Structure:
387    ///     Octet0: Object Type (b 40-47)
388    ///     Octet1: Sampling Frequency (b 32-39)
389    ///     Octet2: Sampling Frequency (b 28-31), Channels (b 26-27), RFA (b 24-25)
390    ///     Octet3: VBR (b 23), Bit Rate (b 16-22)
391    ///     Octet4: Bit Rate (b 8-15)
392    ///     Octet5: Bit Rate (b 0-7)
393    /// Some fields are mandatory choose 1, and therefore do not have a mandatory parameter method.
394    struct AacCodecInfoBits(u64);
395    impl Debug;
396    u8;
397    u32, bitrate, set_bitrate: 22, 0;
398    vbr, set_vbr: 23, 23;
399    // Bits 24-25 RFA.
400    channels, set_channels: 27,26;
401    u16, sampling_frequency, set_sampling_frequency: 39, 28;
402    object_type, set_object_type: 47, 40;
403    // Bits 48-63 Unused.
404}
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        // Bitrate is expressed as a 23bit UiMsbf, stored in a u32.
418        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    /// `AacCodecInfoBytes` is represented as an u64, with upper 16 bits unused.
433    /// Return a vector of the lower 6 bytes.
434    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    /// Returns the number of channels selected.
454    /// Returns Error::OutOfRange if both mono and stereo are selected.
455    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    /// Returns the sampling frequeency selected, in hz.
469    /// Returns Error::OutOfRange if multiple frequencies are selected.
470    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    /// Returns true if `other` is a compatable configuration of `self`
490    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        // Note: the "capabilities" bitrate field is unclear in the A2DP spec: 4.5.2.4.
508        // Interpreting this as the max bitrate for either constant or vbr.
509        // Zero is "not known", which we interpret to be "any bitrate is okay", but only
510        // if we are interpreting our bitrate support
511        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        // If either bitrate is unspecified, take the other one, otherwise, the minimum.
526        // If both are unspecified, choose a reasonable one.
527        let bitrate = match (a.bitrate(), b.bitrate()) {
528            // Pick a reasonable quality bitrate to use by default. 64k average per channel.
529            (0, 0) => 128000,
530            (0, b) => b,
531            (a, 0) => a,
532            (a, b) => std::cmp::min(a, b),
533        };
534        // This option is mandatory for source and sink and we prefer it. See A2DP 1.3.2 Sec 4.5.2
535        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    /// Create `AacCodecInfo` from slice of length `AAC_CODEC_EXTRA_LEN`
544    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        // AacCodecInfo is represented as 8 bytes, with lower 6 bytes containing
551        // the codec extra data.
552        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    /// Unit test for the SBC media codec info generation.
574    fn test_sbc_codec_info() {
575        // Mandatory A2DP Sink support case.
576        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        // reverse parsing and check we match
591        let res = SbcCodecInfo::try_from(&codec_extra[..]).expect("created codec info");
592        assert_eq!((res.0).0, (sbc_codec_info.0).0);
593
594        // Mandatory A2DP source support case. Some fields are choose 1 fields.
595        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        // No supported codec information
609        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        // All codec field values are supported
624        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, // Smallest bitpool value.
631            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
632        )
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        // Out of range bitpool value
639        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, // Too large.
647        );
648        assert!(sbc_codec_info.is_err());
649
650        // Out of range bitpool value
651        let sbc_codec_info = SbcCodecInfo::new(
652            SbcSamplingFrequency::all(),
653            SbcChannelMode::all(),
654            SbcBlockCount::all(),
655            SbcSubBands::all(),
656            SbcAllocation::all(),
657            0, // Too small
658            240,
659        );
660        assert!(sbc_codec_info.is_err());
661
662        // Invalid bitpool value
663        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        // Mono and Stereo
682        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, // Smallest bitpool value.
716            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
717        )
718        .expect("Couldn't create sbc media codec info.");
719        // Should support itself.
720        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,                        // Smallest bitpool value.
729            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
730        )
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, // Smallest bitpool value.
740            53,                        // Largest bitpool value.
741        )
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        // Frequency mismatches
748        assert!(!sbc_codec_48.supports(&sbc_codec_441));
749        assert!(!sbc_codec_441.supports(&sbc_codec_48));
750
751        // Min / Max bitpools
752        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, // Smallest bitpool value.
762            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
763        )
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, // Smallest bitpool value.
772            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
773        )
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, // Smallest bitpool value.
788            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
789        )
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, // Smallest bitpool value.
798            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
799        )
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, // Smallest bitpool value.
814            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
815        )
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, // Smallest bitpool value.
824            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
825        )
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, // Smallest bitpool value.
840            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
841        )
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, // Smallest bitpool value.
850            SbcCodecInfo::BITPOOL_MAX, // Largest bitpool value.
851        )
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        // Empty case.
863        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        // All codec info supported case.
875        let aac_codec_info = AacCodecInfo::new(
876            AacObjectType::all(),
877            AacSamplingFrequency::all(),
878            AacChannels::all(),
879            true,
880            8388607, // Largest 23-bit bit rate.
881        )
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        // Only VBR specified.
888        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        // A2DP Sink mandatory fields supported.
901        let aac_codec_info = AacCodecInfo::new(
902            AacObjectType::MANDATORY_SNK,
903            AacSamplingFrequency::MANDATORY_SNK,
904            AacChannels::MANDATORY_SNK,
905            true,
906            0xAAFF, // Arbitrary bit rate.
907        )
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        // reverse parsing and check we match
914        let res = AacCodecInfo::try_from(&codec_extra[..]).expect("created codec info");
915        assert_eq!((res.0).0, (aac_codec_info.0).0);
916
917        // A2DP Source mandatory fields supported.
918        let aac_codec_info = AacCodecInfo::new(
919            AacObjectType::MANDATORY_SRC,
920            AacSamplingFrequency::FREQ44100HZ,
921            AacChannels::ONE,
922            false,  // VBR is optional in SRC.
923            0xAAFF, // Arbitrary
924        )
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        // A2DP Source with two channels
931        let aac_codec_info = AacCodecInfo::new(
932            AacObjectType::MANDATORY_SRC,
933            AacSamplingFrequency::FREQ44100HZ,
934            AacChannels::TWO,
935            false,  // VBR is optional in SRC.
936            0xAAFF, // Arbitrary
937        )
938        .expect("Error creating aac media codec info.");
939        assert_matches!(aac_codec_info.channel_count(), Ok(2));
940
941        // Out of range bit rate.
942        let aac_codec_info = AacCodecInfo::new(
943            AacObjectType::MANDATORY_SRC,
944            AacSamplingFrequency::FREQ44100HZ,
945            AacChannels::ONE,
946            false,
947            0xFFFFFF, // Too large
948        );
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        // All codec info supported case.
962        let aac_codec_all = AacCodecInfo::new(
963            AacObjectType::all(),
964            AacSamplingFrequency::all(),
965            AacChannels::all(),
966            true,
967            8388607, // Largest 23-bit bit rate.
968        )
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, // Lower than largest.
979        )
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, // Largest 23-bit bit rate.
988        )
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        // Frequencies
995        assert!(!aac_codec_441.supports(&aac_codec_48));
996        assert!(!aac_codec_48.supports(&aac_codec_441));
997
998        // Max bitrate.
999        assert!(!aac_codec_441.supports(&aac_codec_all));
1000
1001        // Channels
1002        let aac_codec_chan_one = AacCodecInfo::new(
1003            AacObjectType::all(),
1004            AacSamplingFrequency::all(),
1005            AacChannels::ONE,
1006            true,
1007            8388607, // Largest 23-bit bit rate.
1008        )
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, // Largest 23-bit bit rate.
1017        )
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        // object type
1026        let aac_codec_mpeg2 = AacCodecInfo::new(
1027            AacObjectType::MPEG2_AAC_LC,
1028            AacSamplingFrequency::all(),
1029            AacChannels::ONE,
1030            true,
1031            8388607, // Largest 23-bit bit rate.
1032        )
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, // Largest 23-bit bit rate.
1041        )
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, // Largest 23-bit bit rate.
1055        )
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, // Bitrate "Not known"
1066        )
1067        .expect("Error creating aac media codec info.");
1068
1069        assert!(aac_codec_bitrate_not_known.supports(&aac_codec_not_vbr));
1070    }
1071}