a2dp_sbc.cc revision 1394c197027c0907932a814a786cc033870eb1c9
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2002-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Utility functions to help build and parse SBC Codec Information Element
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  and Media Payload.
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#define LOG_TAG "a2d_sbc"
2779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
2924ff5af9e40aaebc236bb6a16849c63bff0f23baSharvil Nanavati
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "a2d_api.h"
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "a2d_int.h"
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "a2d_sbc.h"
341394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov#include "a2d_sbc_encoder.h"
350df29ac95d057a1bf74b003fa6dd6459743bcf54Mike J. Chen#include "bt_utils.h"
36d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov#include "embdrv/sbc/encoder/include/sbc_encoder.h"
3779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#include "osi/include/log.h"
38b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov#include "osi/include/osi.h"
3979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
4079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
4179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#define A2D_SBC_MAX_BITPOOL  53
4279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
43b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov/* data type for the SBC Codec Information Element*/
44b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovtypedef struct
45b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov{
46b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    uint8_t samp_freq;      /* Sampling frequency */
47b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    uint8_t ch_mode;        /* Channel mode */
48b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    uint8_t block_len;      /* Block length */
49b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    uint8_t num_subbands;   /* Number of subbands */
50b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    uint8_t alloc_method;   /* Allocation method */
51b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    uint8_t min_bitpool;    /* Minimum bitpool */
52b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    uint8_t max_bitpool;    /* Maximum bitpool */
53b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov} tA2D_SBC_CIE;
54b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
5579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov/* SBC SRC codec capabilities */
5679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovstatic const tA2D_SBC_CIE a2d_sbc_caps =
5779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
5879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    A2D_SBC_IE_SAMP_FREQ_44,            /* samp_freq */
5979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    A2D_SBC_IE_CH_MD_JOINT,             /* ch_mode */
6079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    A2D_SBC_IE_BLOCKS_16,               /* block_len */
6179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    A2D_SBC_IE_SUBBAND_8,               /* num_subbands */
62d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_SBC_IE_ALLOC_MD_L,              /* alloc_method */
63d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_SBC_IE_MIN_BITPOOL,             /* min_bitpool */
64d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_SBC_MAX_BITPOOL                 /* max_bitpool */
6579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov};
6679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
6779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov/* SBC SINK codec capabilities */
6879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovstatic const tA2D_SBC_CIE a2d_sbc_sink_caps =
6979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
7079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    (A2D_SBC_IE_SAMP_FREQ_48 | A2D_SBC_IE_SAMP_FREQ_44),        /* samp_freq */
7179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    (A2D_SBC_IE_CH_MD_MONO | A2D_SBC_IE_CH_MD_STEREO |
7279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov     A2D_SBC_IE_CH_MD_JOINT | A2D_SBC_IE_CH_MD_DUAL),           /* ch_mode */
7379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    (A2D_SBC_IE_BLOCKS_16 | A2D_SBC_IE_BLOCKS_12 |
7479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov     A2D_SBC_IE_BLOCKS_8 | A2D_SBC_IE_BLOCKS_4),                /* block_len */
7579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    (A2D_SBC_IE_SUBBAND_4 | A2D_SBC_IE_SUBBAND_8),      /* num_subbands */
76d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    (A2D_SBC_IE_ALLOC_MD_L | A2D_SBC_IE_ALLOC_MD_S),    /* alloc_method */
77d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_SBC_IE_MIN_BITPOOL,                             /* min_bitpool */
78d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_SBC_IE_MAX_BITPOOL                              /* max_bitpool */
7979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov};
8079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
8179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov/* Default SBC codec configuration */
8279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovconst tA2D_SBC_CIE a2d_sbc_default_config =
8379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
8479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    A2D_SBC_IE_SAMP_FREQ_44,            /* samp_freq */
8579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    A2D_SBC_IE_CH_MD_JOINT,             /* ch_mode */
8679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    A2D_SBC_IE_BLOCKS_16,               /* block_len */
8779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    A2D_SBC_IE_SUBBAND_8,               /* num_subbands */
88d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_SBC_IE_ALLOC_MD_L,              /* alloc_method */
89d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_SBC_IE_MIN_BITPOOL,             /* min_bitpool */
90d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_SBC_MAX_BITPOOL                 /* max_bitpool */
9179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov};
920df29ac95d057a1bf74b003fa6dd6459743bcf54Mike J. Chen
931394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavovstatic const tA2D_ENCODER_INTERFACE a2d_encoder_interface_sbc = {
941394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    a2d_sbc_encoder_init,
951394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    a2d_sbc_encoder_update,
961394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    a2d_sbc_encoder_cleanup,
971394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    a2d_sbc_feeding_init,
981394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    a2d_sbc_feeding_reset,
991394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    a2d_sbc_feeding_flush,
1001394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    a2d_sbc_get_encoder_interval_ms,
1011394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    a2d_sbc_send_frames
1021394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov};
1031394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov
104b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovstatic tA2D_STATUS A2D_CodecInfoMatchesCapabilitySbc(
105b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        const tA2D_SBC_CIE *p_cap,
106b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        const uint8_t *p_codec_info,
107b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        bool is_peer_codec_info);
108b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
109b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// Builds the SBC Media Codec Capabilities byte sequence beginning from the
110b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// LOSC octet. |media_type| is the media type |AVDT_MEDIA_TYPE_*|.
111b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// |p_ie| is a pointer to the SBC Codec Information Element information.
112b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// The result is stored in |p_result|. Returns A2D_SUCCESS on success,
113b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// otherwise the corresponding A2DP error status code.
114b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovstatic tA2D_STATUS A2D_BldSbcInfo(uint8_t media_type, const tA2D_SBC_CIE *p_ie,
115b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov                                  uint8_t *p_result)
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tA2D_STATUS status;
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if( p_ie == NULL || p_result == NULL ||
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_ie->samp_freq & ~A2D_SBC_IE_SAMP_FREQ_MSK) ||
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_ie->ch_mode & ~A2D_SBC_IE_CH_MD_MSK) ||
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_ie->block_len & ~A2D_SBC_IE_BLOCKS_MSK) ||
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_ie->num_subbands & ~A2D_SBC_IE_SUBBAND_MSK) ||
124d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        (p_ie->alloc_method & ~A2D_SBC_IE_ALLOC_MD_MSK) ||
125d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        (p_ie->min_bitpool > p_ie->max_bitpool) ||
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        (p_ie->min_bitpool < A2D_SBC_IE_MIN_BITPOOL) ||
127d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        (p_ie->min_bitpool > A2D_SBC_IE_MAX_BITPOOL) ||
128d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        (p_ie->max_bitpool < A2D_SBC_IE_MIN_BITPOOL) ||
129c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        (p_ie->max_bitpool > A2D_SBC_IE_MAX_BITPOOL)) {
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* if any unused bit is set */
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        status = A2D_INVALID_PARAMS;
132c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    } else {
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        status = A2D_SUCCESS;
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_result++ = A2D_SBC_INFO_LEN;
135d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        *p_result++ = (media_type << 4);
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_result++ = A2D_MEDIA_CT_SBC;
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        /* Media Codec Specific Information Element */
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_result++ = p_ie->samp_freq | p_ie->ch_mode;
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
141d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        *p_result++ = p_ie->block_len | p_ie->num_subbands | p_ie->alloc_method;
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_result++ = p_ie->min_bitpool;
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_result   = p_ie->max_bitpool;
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
149b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// Parses the SBC Media Codec Capabilities byte sequence beginning from the
150b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// LOSC octet. The result is stored in |p_ie|. The byte sequence to parse is
151b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// |p_codec_info|. If |for_caps| is true, the byte sequence is for get
152b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// capabilities response. Returns A2D_SUCCESS on success, otherwise the
153b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// corresponding A2DP error status code.
154b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovstatic tA2D_STATUS A2D_ParsSbcInfo(tA2D_SBC_CIE *p_ie,
155b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov                                   const uint8_t *p_codec_info,
156b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov                                   bool is_peer_src_codec_info)
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
15876198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge    tA2D_STATUS status = A2D_SUCCESS;
159d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    uint8_t losc;
160d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    uint8_t media_type;
161d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_CODEC_TYPE codec_type;
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (p_ie == NULL || p_codec_info == NULL)
16476198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        return A2D_INVALID_PARAMS;
165cab5fc179730ce6910989307680b275195876c4dArman Uguray
166d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    // Check the codec capability length
167d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    losc = *p_codec_info++;
168d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (losc != A2D_SBC_INFO_LEN)
169d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return A2D_WRONG_CODEC;
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
171d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    media_type = (*p_codec_info++) >> 4;
172d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    codec_type = *p_codec_info++;
173d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    /* Check the Media Type and Media Codec Type */
174d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (media_type != AVDT_MEDIA_TYPE_AUDIO ||
175d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        codec_type != A2D_MEDIA_CT_SBC) {
17676198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        return A2D_WRONG_CODEC;
177d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
17876198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge
17979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_ie->samp_freq = *p_codec_info & A2D_SBC_IE_SAMP_FREQ_MSK;
18079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_ie->ch_mode   = *p_codec_info & A2D_SBC_IE_CH_MD_MSK;
18179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_codec_info++;
18279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_ie->block_len     = *p_codec_info & A2D_SBC_IE_BLOCKS_MSK;
18379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_ie->num_subbands  = *p_codec_info & A2D_SBC_IE_SUBBAND_MSK;
184d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    p_ie->alloc_method  = *p_codec_info & A2D_SBC_IE_ALLOC_MD_MSK;
18579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_codec_info++;
18679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_ie->min_bitpool = *p_codec_info++;
18779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_ie->max_bitpool = *p_codec_info;
188d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (p_ie->min_bitpool < A2D_SBC_IE_MIN_BITPOOL ||
189d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        p_ie->min_bitpool > A2D_SBC_IE_MAX_BITPOOL) {
19076198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        status = A2D_BAD_MIN_BITPOOL;
191d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
19276198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge
193d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (p_ie->max_bitpool < A2D_SBC_IE_MIN_BITPOOL ||
194d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        p_ie->max_bitpool > A2D_SBC_IE_MAX_BITPOOL ||
195d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        p_ie->max_bitpool < p_ie->min_bitpool) {
19676198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        status = A2D_BAD_MAX_BITPOOL;
197d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
19876198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge
19979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (is_peer_src_codec_info)
20076198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        return status;
20176198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge
20276198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge    if (A2D_BitsSet(p_ie->samp_freq) != A2D_SET_ONE_BIT)
20376198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        status = A2D_BAD_SAMP_FREQ;
20476198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge    if (A2D_BitsSet(p_ie->ch_mode) != A2D_SET_ONE_BIT)
20576198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        status = A2D_BAD_CH_MODE;
20676198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge    if (A2D_BitsSet(p_ie->block_len) != A2D_SET_ONE_BIT)
20776198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        status = A2D_BAD_BLOCK_LEN;
20876198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge    if (A2D_BitsSet(p_ie->num_subbands) != A2D_SET_ONE_BIT)
20976198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge        status = A2D_BAD_SUBBANDS;
210d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (A2D_BitsSet(p_ie->alloc_method) != A2D_SET_ONE_BIT)
211d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        status = A2D_BAD_ALLOC_METHOD;
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return status;
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         A2D_BldSbcMplHdr
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called by an application to parse
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the SBC Media Payload header.
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      frag:  1, if fragmented. 0, otherwise.
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      start:  1, if the starting packet of a fragmented frame.
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      last:  1, if the last packet of a fragmented frame.
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      num:  If frag is 1, this is the number of remaining fragments
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                            (including this fragment) of this frame.
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                            If frag is 0, this is the number of frames in this packet.
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_dst:  the resulting media payload header byte sequence.
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
238b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovstatic void A2D_BldSbcMplHdr(uint8_t *p_dst, bool frag, bool start, bool last,
239b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov                             uint8_t num)
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
241b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    if (p_dst == NULL)
242b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov        return;
243b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov
244b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    *p_dst = 0;
245b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    if (frag)
246b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov        *p_dst |= A2D_SBC_HDR_F_MSK;
247b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    if (start)
248b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov        *p_dst |= A2D_SBC_HDR_S_MSK;
249b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    if (last)
250b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov        *p_dst |= A2D_SBC_HDR_L_MSK;
251b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    *p_dst |= (A2D_SBC_HDR_NUM_MSK & num);
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         A2D_ParsSbcMplHdr
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      This function is called by an application to parse
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  the SBC Media Payload header.
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Input Parameters:
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      p_src:  the byte sequence to parse..
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                  Output Parameters:
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      frag:  1, if fragmented. 0, otherwise.
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      start:  1, if the starting packet of a fragmented frame.
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      last:  1, if the last packet of a fragmented frame.
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                      num:  If frag is 1, this is the number of remaining fragments
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                            (including this fragment) of this frame.
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**                            If frag is 0, this is the number of frames in this packet.
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/
276d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid A2D_ParsSbcMplHdr(uint8_t *p_src, bool *p_frag, bool *p_start, bool *p_last, uint8_t *p_num)
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(p_src && p_frag && p_start && p_last && p_num)
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
280d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        *p_frag = (*p_src & A2D_SBC_HDR_F_MSK) ? true: false;
281d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        *p_start= (*p_src & A2D_SBC_HDR_S_MSK) ? true: false;
282d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen        *p_last = (*p_src & A2D_SBC_HDR_L_MSK) ? true: false;
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *p_num  = (*p_src & A2D_SBC_HDR_NUM_MSK);
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_InitCodecConfigSbc(tAVDT_CFG *p_cfg)
28879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
289d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &a2d_sbc_caps,
29079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                       p_cfg->codec_info) != A2D_SUCCESS) {
29179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return false;
29279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
29379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
29479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#if (BTA_AV_CO_CP_SCMS_T == TRUE)
29579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* Content protection info - support SCMS-T */
29679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    uint8_t *p = p_cfg->protect_info;
29779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    *p++ = BTA_AV_CP_LOSC;
29879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID);
29979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    p_cfg->num_protect = 1;
30079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#endif
30179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
30279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    return true;
30379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
30479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
305b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovconst char *A2D_CodecNameSbc(UNUSED_ATTR const uint8_t *p_codec_info)
306b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov{
307b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    return "SBC";
308b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov}
309b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov
31079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_InitCodecConfigSbcSink(tAVDT_CFG *p_cfg)
31179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
312d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &a2d_sbc_sink_caps,
31379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                       p_cfg->codec_info) != A2D_SUCCESS) {
31479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return false;
31579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
31679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
31779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    return true;
31879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
31979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
320a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavovbool A2D_IsSourceCodecValidSbc(const uint8_t *p_codec_info)
321a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov{
322a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    tA2D_SBC_CIE cfg_cie;
323a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov
324a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    /* Use a liberal check when parsing the codec info */
325a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    return (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, false) == A2D_SUCCESS) ||
326a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov      (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, true) == A2D_SUCCESS);
327a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov}
328a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov
329a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavovbool A2D_IsSinkCodecValidSbc(const uint8_t *p_codec_info)
330a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov{
331a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    tA2D_SBC_CIE cfg_cie;
332a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov
333a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    /* Use a liberal check when parsing the codec info */
334a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    return (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, false) == A2D_SUCCESS) ||
335a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov      (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, true) == A2D_SUCCESS);
336a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov}
337a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov
338a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavovbool A2D_IsPeerSourceCodecValidSbc(const uint8_t *p_codec_info)
339a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov{
340a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    tA2D_SBC_CIE cfg_cie;
341a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov
342a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    /* Use a liberal check when parsing the codec info */
343a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    return (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, false) == A2D_SUCCESS) ||
344a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov      (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, true) == A2D_SUCCESS);
345a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov}
346a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov
347a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavovbool A2D_IsPeerSinkCodecValidSbc(const uint8_t *p_codec_info)
348b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov{
349b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_SBC_CIE cfg_cie;
350b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
351b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    /* Use a liberal check when parsing the codec info */
352b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    return (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, false) == A2D_SUCCESS) ||
353b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov      (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, true) == A2D_SUCCESS);
354b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov}
355b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
35679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_IsSourceCodecSupportedSbc(const uint8_t *p_codec_info)
35779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
35879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    return (A2D_CodecInfoMatchesCapabilitySbc(&a2d_sbc_caps, p_codec_info,
35979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                                              false) == A2D_SUCCESS);
36079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
36179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
36279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_IsSinkCodecSupportedSbc(const uint8_t *p_codec_info)
36379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
36479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    return (A2D_CodecInfoMatchesCapabilitySbc(&a2d_sbc_sink_caps, p_codec_info,
36579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                                              false) == A2D_SUCCESS);
36679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
36779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
36879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_IsPeerSourceCodecSupportedSbc(const uint8_t *p_codec_info)
36979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
37079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    return (A2D_CodecInfoMatchesCapabilitySbc(&a2d_sbc_sink_caps, p_codec_info,
37179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                                              true) == A2D_SUCCESS);
37279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
37379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
37479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovvoid A2D_InitDefaultCodecSbc(uint8_t *p_codec_info)
37579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
376d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &a2d_sbc_default_config,
37779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                       p_codec_info) != A2D_SUCCESS) {
37879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: A2D_BldSbcInfo failed", __func__);
37979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
38079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
38179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
3821394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavovbool A2D_SetCodecSbc(const tA2D_FEEDING_PARAMS *p_feeding_params,
38379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                     uint8_t *p_codec_info)
38479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
385c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE sbc_config = a2d_sbc_default_config;
386c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
3871394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    LOG_VERBOSE(LOG_TAG, "%s", __func__);
388c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
389c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* Check the number of channels */
3901394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    if ((p_feeding_params->num_channel != 1) &&
3911394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        (p_feeding_params->num_channel != 2)) {
392c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: Unsupported PCM channel number %d",
3931394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                  __func__, p_feeding_params->num_channel);
394c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return false;
395c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
396c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
397c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* Check the bits per sample */
3981394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    if ((p_feeding_params->bit_per_sample != 8) &&
3991394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        (p_feeding_params->bit_per_sample != 16)) {
400c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: Unsupported PCM sample size %d",
4011394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                  __func__, p_feeding_params->bit_per_sample);
402c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return false;
403c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
40479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
405c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* Check the sampling frequency */
4061394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    switch (p_feeding_params->sampling_freq) {
407c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 8000:
408c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 12000:
409c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 16000:
410c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 24000:
411c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 32000:
412c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 48000:
413c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_48;
414c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        break;
415c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 11025:
416c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 22050:
417c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    case 44100:
418c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_44;
419c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        break;
42079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    default:
421c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: Unsupported PCM sampling frequency %d",
4221394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                  __func__, p_feeding_params->sampling_freq);
423c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return false;
424c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
425c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
426c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* Build the codec config */
427c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &sbc_config, p_codec_info)
428c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        != A2D_SUCCESS) {
429c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: A2D_BldSbcInfo failed", __func__);
43079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return false;
43179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
43279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
43379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    return true;
43479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
43579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
436b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// Checks whether A2DP SBC codec configuration matches with a device's codec
437b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// capabilities. |p_cap| is the SBC codec configuration. |p_codec_info| is
438b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// the device's codec capabilities. |is_peer_src_codec_info| is true if
439b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// |p_codec_info| contains the codec capabilities for a peer device that
440b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// is acting as an A2DP source.
441b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// Returns A2D_SUCCESS if the codec configuration matches with capabilities,
442b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// otherwise the corresponding A2DP error status code.
44379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovstatic tA2D_STATUS A2D_CodecInfoMatchesCapabilitySbc(
44479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        const tA2D_SBC_CIE *p_cap,
44579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        const uint8_t *p_codec_info,
44679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        bool is_peer_src_codec_info)
44779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
44879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    tA2D_STATUS status;
44979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    tA2D_SBC_CIE cfg_cie;
45079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
45179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* parse configuration */
45279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    status = A2D_ParsSbcInfo(&cfg_cie, p_codec_info, is_peer_src_codec_info);
45379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (status != A2D_SUCCESS) {
45479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: parsing failed %d", __func__, status);
45579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return status;
45679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
45779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
45879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* verify that each parameter is in range */
45979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
46079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "FREQ peer: 0x%x, capability 0x%x",
46179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov              cfg_cie.samp_freq, p_cap->samp_freq);
46279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "CH_MODE peer: 0x%x, capability 0x%x",
46379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov              cfg_cie.ch_mode, p_cap->ch_mode);
46479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "BLOCK_LEN peer: 0x%x, capability 0x%x",
46579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov              cfg_cie.block_len, p_cap->block_len);
46679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "SUB_BAND peer: 0x%x, capability 0x%x",
46779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov              cfg_cie.num_subbands, p_cap->num_subbands);
468d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    LOG_DEBUG(LOG_TAG, "ALLOC_METHOD peer: 0x%x, capability 0x%x",
469d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov              cfg_cie.alloc_method, p_cap->alloc_method);
47079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "MIN_BitPool peer: 0x%x, capability 0x%x",
47179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov              cfg_cie.min_bitpool, p_cap->min_bitpool);
472d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    LOG_DEBUG(LOG_TAG, "MAX_BitPool peer: 0x%x, capability 0x%x",
473d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov              cfg_cie.max_bitpool, p_cap->max_bitpool);
47479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
47579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* sampling frequency */
47679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0)
47779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return A2D_NS_SAMP_FREQ;
47879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
47979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* channel mode */
48079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0)
48179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return A2D_NS_CH_MODE;
48279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
48379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* block length */
48479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if ((cfg_cie.block_len & p_cap->block_len) == 0)
48579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return A2D_BAD_BLOCK_LEN;
48679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
48779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* subbands */
48879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0)
48979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return A2D_NS_SUBBANDS;
49079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
49179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* allocation method */
492d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if ((cfg_cie.alloc_method & p_cap->alloc_method) == 0)
493d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return A2D_NS_ALLOC_METHOD;
49479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
49579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* min bitpool */
49679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (cfg_cie.min_bitpool < p_cap->min_bitpool)
49779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return A2D_NS_MIN_BITPOOL;
49879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
499d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    /* max bitpool */
500d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (cfg_cie.max_bitpool > p_cap->max_bitpool)
501d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return A2D_NS_MAX_BITPOOL;
502d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
50379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    return A2D_SUCCESS;
50479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
50579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
506c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin RadoslavovtA2D_STATUS A2D_BuildSrc2SinkConfigSbc(const uint8_t *p_src_cap,
507c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                                       uint8_t *p_pref_cfg)
50879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
50979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    tA2D_SBC_CIE    src_cap;
51079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    tA2D_SBC_CIE    pref_cap;
51179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
51279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* initialize it to default SBC configuration */
513d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &a2d_sbc_default_config, p_pref_cfg);
51479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
51579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* now try to build a preferred one */
51679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    /* parse configuration */
51779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    tA2D_STATUS status = A2D_ParsSbcInfo(&src_cap, p_src_cap, true);
51879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (status != A2D_SUCCESS) {
51979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: can't parse src cap ret = %d",
52079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                  __func__, status);
52179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        return A2D_FAIL;
52279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
52379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
52479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (src_cap.samp_freq & A2D_SBC_IE_SAMP_FREQ_48)
52579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.samp_freq = A2D_SBC_IE_SAMP_FREQ_48;
52679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    else if (src_cap.samp_freq & A2D_SBC_IE_SAMP_FREQ_44)
52779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.samp_freq = A2D_SBC_IE_SAMP_FREQ_44;
52879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
52979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_JOINT)
53079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.ch_mode = A2D_SBC_IE_CH_MD_JOINT;
53179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_STEREO)
53279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.ch_mode = A2D_SBC_IE_CH_MD_STEREO;
53379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_DUAL)
53479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.ch_mode = A2D_SBC_IE_CH_MD_DUAL;
53579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_MONO)
53679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.ch_mode = A2D_SBC_IE_CH_MD_MONO;
53779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
53879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (src_cap.block_len & A2D_SBC_IE_BLOCKS_16)
53979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.block_len = A2D_SBC_IE_BLOCKS_16;
54079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_12)
54179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.block_len = A2D_SBC_IE_BLOCKS_12;
54279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_8)
54379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.block_len = A2D_SBC_IE_BLOCKS_8;
54479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_4)
54579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.block_len = A2D_SBC_IE_BLOCKS_4;
54679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
54779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (src_cap.num_subbands & A2D_SBC_IE_SUBBAND_8)
54879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.num_subbands = A2D_SBC_IE_SUBBAND_8;
54979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    else if(src_cap.num_subbands & A2D_SBC_IE_SUBBAND_4)
55079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        pref_cap.num_subbands = A2D_SBC_IE_SUBBAND_4;
55179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
552d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (src_cap.alloc_method & A2D_SBC_IE_ALLOC_MD_L)
553d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        pref_cap.alloc_method = A2D_SBC_IE_ALLOC_MD_L;
554d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    else if(src_cap.alloc_method & A2D_SBC_IE_ALLOC_MD_S)
555d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        pref_cap.alloc_method = A2D_SBC_IE_ALLOC_MD_S;
55679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
55779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    pref_cap.min_bitpool = src_cap.min_bitpool;
558d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    pref_cap.max_bitpool = src_cap.max_bitpool;
55979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
560d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &pref_cap, p_pref_cfg);
56179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
56279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    return A2D_SUCCESS;
56379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
56479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
565c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin RadoslavovtA2D_STATUS A2D_BuildSinkConfigSbc(const uint8_t *p_src_config,
566c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                                   const uint8_t *p_sink_cap,
567c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                                   uint8_t *p_result_sink_config)
568c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov{
569c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE src_config_cie;
570c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE sink_cap_cie;
571c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
572c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* Decode the source codec config */
573c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&src_config_cie,
574c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                                             p_src_config, false);
575c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
576c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode source codec information: %d",
577c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                  __func__, a2d_status);
578c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return A2D_FAIL;
579c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
580c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
581c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* Decode the sink codec capabilities */
582c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    a2d_status = A2D_ParsSbcInfo(&sink_cap_cie, p_sink_cap, true);
583c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
584c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode sink capability information: %d",
585c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                  __func__, a2d_status);
586c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return A2D_FAIL;
587c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
588c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
589c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* Update the bitpool boundaries from the sink codec capabilities */
590c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    src_config_cie.min_bitpool = sink_cap_cie.min_bitpool;
591c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    src_config_cie.max_bitpool = sink_cap_cie.max_bitpool;
592c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
593c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* Build the result sink config from the source config */
594c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &src_config_cie,
595c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                   p_result_sink_config);
596c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
597c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    return A2D_SUCCESS;
598c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov}
599c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
600b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovbool A2D_CodecTypeEqualsSbc(const uint8_t *p_codec_info_a,
601b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov                            const uint8_t *p_codec_info_b)
60279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
603b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_SBC_CIE sbc_cie_a;
604b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_SBC_CIE sbc_cie_b;
605b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
606b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    // Check whether the codec info contains valid data
607b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie_a, p_codec_info_a, false);
608b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
609b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
610b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov                  __func__, a2d_status);
611b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        return false;
612b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    }
613b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    a2d_status = A2D_ParsSbcInfo(&sbc_cie_b, p_codec_info_b, false);
614b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
615b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
616b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov                  __func__, a2d_status);
617b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        return false;
618b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    }
619b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
620b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_CODEC_TYPE codec_type_a = A2D_GetCodecType(p_codec_info_a);
621b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_CODEC_TYPE codec_type_b = A2D_GetCodecType(p_codec_info_b);
622b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
623b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    return (codec_type_a == codec_type_b) && (codec_type_a == A2D_MEDIA_CT_SBC);
62479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}
62579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
626c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovbool A2D_CodecEqualsSbc(const uint8_t *p_codec_info_a,
627c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                        const uint8_t *p_codec_info_b)
628c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov{
629c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE sbc_cie_a;
630c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE sbc_cie_b;
631c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
632c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    // Check whether the codec info contains valid data
633c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie_a, p_codec_info_a, false);
634c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
635c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
636c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                  __func__, a2d_status);
637c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return false;
638c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
639c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    a2d_status = A2D_ParsSbcInfo(&sbc_cie_b, p_codec_info_b, false);
640c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
641c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
642c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                  __func__, a2d_status);
643c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return false;
644c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
645c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
646c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_CODEC_TYPE codec_type_a = A2D_GetCodecType(p_codec_info_a);
647c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_CODEC_TYPE codec_type_b = A2D_GetCodecType(p_codec_info_b);
648c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
649c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if ((codec_type_a != codec_type_b) || (codec_type_a != A2D_MEDIA_CT_SBC))
650c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return false;
651c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
652c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    return (sbc_cie_a.samp_freq == sbc_cie_b.samp_freq) &&
653c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.ch_mode == sbc_cie_b.ch_mode) &&
654c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.block_len == sbc_cie_b.block_len) &&
655c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.num_subbands == sbc_cie_b.num_subbands) &&
656c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.alloc_method == sbc_cie_b.alloc_method) &&
657c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.min_bitpool == sbc_cie_b.min_bitpool) &&
658c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.max_bitpool == sbc_cie_b.max_bitpool);
659c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov}
660c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
661c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovbool A2D_CodecRequiresReconfigSbc(const uint8_t *p_codec_info_a,
662c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                                  const uint8_t *p_codec_info_b)
663c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov{
664c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE sbc_cie_a;
665c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE sbc_cie_b;
666c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
667c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    // Check whether the codec info contains valid data
668c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie_a, p_codec_info_a, false);
669c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
670c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
671c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                  __func__, a2d_status);
672c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return true;
673c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
674c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    a2d_status = A2D_ParsSbcInfo(&sbc_cie_b, p_codec_info_b, false);
675c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
676c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
677c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                  __func__, a2d_status);
678c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return true;
679c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
680c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
681c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_CODEC_TYPE codec_type_a = A2D_GetCodecType(p_codec_info_a);
682c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_CODEC_TYPE codec_type_b = A2D_GetCodecType(p_codec_info_b);
683c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
684c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if ((codec_type_a != codec_type_b) || (codec_type_a != A2D_MEDIA_CT_SBC))
685c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return true;
686c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
687c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /* NOTE: The min_bitpool and max_bitpool fields are ignored */
688c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    return (sbc_cie_a.samp_freq != sbc_cie_b.samp_freq) ||
689c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.ch_mode != sbc_cie_b.ch_mode) ||
690c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.block_len != sbc_cie_b.block_len) ||
691c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.num_subbands != sbc_cie_b.num_subbands) ||
692c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_a.alloc_method != sbc_cie_b.alloc_method);
693c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov}
694c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
695c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovbool A2D_CodecConfigMatchesCapabilitiesSbc(const uint8_t *p_codec_config,
696c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                                           const uint8_t *p_codec_caps)
697c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov{
698c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE sbc_cie_config;
699c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_SBC_CIE sbc_cie_caps;
700c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
701c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    // Check whether the codec info contains valid data
702c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie_config, p_codec_config,
703c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                                             false);
704c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
705c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec config: %d",
706c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                  __func__, a2d_status);
707c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return false;
708c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
709c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    a2d_status = A2D_ParsSbcInfo(&sbc_cie_caps, p_codec_caps, true);
710c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
711c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec capabilities: %d",
712c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov                  __func__, a2d_status);
713c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov        return false;
714c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    }
715c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
716c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov    /*
717c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov     * Must match all SBC codec fields except min/max bitpool boundaries which
718c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov     * can be adjusted.
719c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov     */
720a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    bool result =
721a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov      (sbc_cie_config.samp_freq & sbc_cie_caps.samp_freq) &&
722c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_config.ch_mode & sbc_cie_caps.ch_mode) &&
723c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_config.block_len & sbc_cie_caps.block_len) &&
724c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_config.num_subbands & sbc_cie_caps.num_subbands) &&
725c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov      (sbc_cie_config.alloc_method & sbc_cie_caps.alloc_method);
726a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov
727a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    LOG_DEBUG(LOG_TAG, "%s: result=%s", __func__, result ? "true" : "false");
7281394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "%s: config samp_freq=0x%x ch_mode=0x%x "
7291394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov              "block_len=0x%x num_subbands=0x%x alloc_method=0x%x",
730a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov              __func__,
731a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov              sbc_cie_config.samp_freq, sbc_cie_config.ch_mode,
732a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov              sbc_cie_config.block_len, sbc_cie_config.num_subbands,
733a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov              sbc_cie_config.alloc_method);
7341394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "%s: caps   samp_freq=0x%x ch_mode=0x%x "
7351394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov              "block_len=0x%x num_subbands=0x%x alloc_method=0x%x",
736a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov              __func__,
737a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov              sbc_cie_caps.samp_freq, sbc_cie_caps.ch_mode,
738a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov              sbc_cie_caps.block_len, sbc_cie_caps.num_subbands,
739a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov              sbc_cie_caps.alloc_method);
740a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov
741a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov    return result;
742c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov}
743c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov
744d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetTrackFrequencySbc(const uint8_t *p_codec_info)
74579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{
746d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
747d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
748d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
749d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
750d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
751d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
752d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
753d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
754d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
755d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.samp_freq) {
756d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_16:
757d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 16000;
758d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_32:
759d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 32000;
760d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_44:
761d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 44100;
762d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_48:
763d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 48000;
764d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
765d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
766d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
767d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
768d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return -1;
769d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov}
770d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
771d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetTrackChannelCountSbc(const uint8_t *p_codec_info)
772d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{
773d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
774d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
775d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
776d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
777d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
778d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
779d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
780d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
781d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
782d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.ch_mode) {
783d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_MONO:
784d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 1;
785d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_DUAL:
786d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_STEREO:
787d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_JOINT:
788d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 2;
789d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
790d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
791d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
792d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
793d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return -1;
794d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov}
795d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
796d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetNumberOfSubbandsSbc(const uint8_t *p_codec_info)
797d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{
798d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
799d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
800d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
801d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
802d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
803d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
804d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
805d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
806d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
807d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.num_subbands) {
808d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SUBBAND_4:
809d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 4;
810d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SUBBAND_8:
811d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 8;
812d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
813d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
814d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
815d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
816d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return -1;
817d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov}
818d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
819d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetNumberOfBlocksSbc(const uint8_t *p_codec_info)
820d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{
821d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
822d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
823d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
824d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
825d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
826d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
827d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
828d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
829d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
830d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.block_len) {
831d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_BLOCKS_4:
832d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 4;
833d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_BLOCKS_8:
834d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 8;
835d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_BLOCKS_12:
836d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 12;
837d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_BLOCKS_16:
838d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 16;
839d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
840d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
841d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
842d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
843d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return -1;
844d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov}
845d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
846d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetAllocationMethodCodeSbc(const uint8_t *p_codec_info)
847d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{
848d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
849d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
850d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
851d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
852d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
853d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
854d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
8557aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov    }
856d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
857d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.alloc_method) {
858d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_ALLOC_MD_S:
859d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_SNR;
860d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_ALLOC_MD_L:
861d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_LOUDNESS;
862d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
863d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
864d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
865d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
866d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return -1;
867d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov}
868d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
869d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetChannelModeCodeSbc(const uint8_t *p_codec_info)
870d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{
871d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
872d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
873d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
874d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
875d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
876d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
877d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
878d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
879d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
880d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.ch_mode) {
881d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_MONO:
882d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_MONO;
883d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_DUAL:
884d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_DUAL;
885d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_STEREO:
886d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_STEREO;
887d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_JOINT:
888d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_JOINT_STEREO;
889d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
890d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
891d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
892d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
893d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return -1;
894d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov}
895d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
896d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetSamplingFrequencyCodeSbc(const uint8_t *p_codec_info)
897d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{
898d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
899d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
900d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
901d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
902d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
903d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
904d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
905d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
906d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
907d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.samp_freq) {
908d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_16:
909d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_sf16000;
910d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_32:
911d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_sf32000;
912d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_44:
913d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_sf44100;
914d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_48:
915d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return SBC_sf48000;
916d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
917d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
918d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
919d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
920d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return -1;
921d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov}
922d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
923b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovint A2D_GetMinBitpoolSbc(const uint8_t *p_codec_info)
924b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov{
925b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
926b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
927b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
928b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
929b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
930b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov                  __func__, a2d_status);
931b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        return -1;
932b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    }
933b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
934b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    return sbc_cie.min_bitpool;
935b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov}
936b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
937b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovint A2D_GetMaxBitpoolSbc(const uint8_t *p_codec_info)
938b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov{
939b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
940b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
941b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
942b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
943b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
944b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov                  __func__, a2d_status);
945b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov        return -1;
946b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    }
947b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
948b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov    return sbc_cie.max_bitpool;
949b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov}
950b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov
951d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetSinkTrackChannelTypeSbc(const uint8_t *p_codec_info)
952d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{
953d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
954d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
955d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
956d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
957d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
958d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
959d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
960d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
961d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
962d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.ch_mode) {
963d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_MONO:
964d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 1;
965d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_DUAL:
966d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_STEREO:
967d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_JOINT:
968d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return 3;
969d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
970d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
971d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
972d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
973d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return -1;
974d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov}
975d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
976d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetSinkFramesCountToProcessSbc(uint64_t time_interval_ms,
977d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                                       const uint8_t *p_codec_info)
978d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{
979d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
980d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    uint32_t freq_multiple;
981d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    uint32_t num_blocks;
982d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    uint32_t num_subbands;
983d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    int frames_to_process;
984d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
985d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
986d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
987d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d",
988d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  __func__, a2d_status);
989d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
990d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
991d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
992d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    // Check the sample frequency
993d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.samp_freq) {
994d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_16:
9951394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: samp_freq:%d (16000)", __func__,
9961394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.samp_freq);
997d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        freq_multiple = 16 * time_interval_ms;
998d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
999d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_32:
10001394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: samp_freq:%d (32000)", __func__,
10011394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.samp_freq);
1002d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        freq_multiple = 32 * time_interval_ms;
1003d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1004d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_44:
10051394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: samp_freq:%d (44100)", __func__,
10061394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.samp_freq);
1007d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        freq_multiple = (441 * time_interval_ms) / 10;
1008d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1009d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SAMP_FREQ_48:
10101394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: samp_freq:%d (48000)", __func__,
10111394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.samp_freq);
1012d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        freq_multiple = 48 * time_interval_ms;
1013d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1014d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
1015d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: unknown frequency: %d", __func__,
1016d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  sbc_cie.samp_freq);
1017d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
1018d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
1019d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
1020d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    // Check the channel mode
1021d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.ch_mode) {
1022d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_MONO:
10231394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: ch_mode:%d (Mono)", __func__,
10241394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.ch_mode);
1025d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1026d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_DUAL:
10271394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: ch_mode:%d (DUAL)", __func__,
10281394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.ch_mode);
1029d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1030d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_STEREO:
10311394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: ch_mode:%d (STEREO)", __func__,
10321394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.ch_mode);
1033d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1034d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_CH_MD_JOINT:
10351394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: ch_mode:%d (JOINT)", __func__,
10361394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.ch_mode);
1037d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1038d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
1039d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: unknown channel mode: %d", __func__,
1040d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  sbc_cie.ch_mode);
1041d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
1042d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
1043d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
1044d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    // Check the block length
1045d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.block_len) {
1046d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_BLOCKS_4:
10471394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: block_len:%d (4)", __func__,
10481394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.block_len);
1049d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        num_blocks = 4;
1050d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1051d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_BLOCKS_8:
10521394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: block_len:%d (8)", __func__,
10531394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.block_len);
1054d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        num_blocks = 8;
1055d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1056d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_BLOCKS_12:
10571394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: block_len:%d (12)", __func__,
10581394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.block_len);
1059d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        num_blocks = 12;
1060d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1061d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_BLOCKS_16:
10621394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: block_len:%d (16)", __func__,
10631394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.block_len);
1064d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        num_blocks = 16;
1065d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1066d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
1067d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: unknown block length: %d", __func__,
1068d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  sbc_cie.block_len);
1069d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
1070d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
1071d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
1072d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    // Check the number of sub-bands
1073d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.num_subbands) {
1074d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SUBBAND_4:
10751394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: num_subbands:%d (4)", __func__,
10761394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.num_subbands);
1077d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        num_subbands = 4;
1078d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1079d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_SUBBAND_8:
10801394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: num_subbands:%d (8)", __func__,
10811394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.num_subbands);
1082d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        num_subbands = 8;
1083d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1084d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
1085d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: unknown number of subbands: %d", __func__,
1086d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  sbc_cie.num_subbands);
1087d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
1088d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
1089d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
1090d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    // Check the allocation method
1091d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    switch (sbc_cie.alloc_method) {
1092d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_ALLOC_MD_S:
10931394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: alloc_method:%d (SNR)", __func__,
10941394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.alloc_method);
1095d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1096d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    case A2D_SBC_IE_ALLOC_MD_L:
10971394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        LOG_VERBOSE(LOG_TAG, "%s: alloc_method:%d (Loudness)", __func__,
10981394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                    sbc_cie.alloc_method);
1099d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        break;
1100d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    default:
1101d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: unknown allocation method: %d", __func__,
1102d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov                  sbc_cie.alloc_method);
1103d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        return -1;
1104d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    }
1105d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
11061394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    LOG_VERBOSE(LOG_TAG, "%s: Bit pool Min:%d Max:%d", __func__,
11071394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov                sbc_cie.min_bitpool, sbc_cie.max_bitpool);
1108d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
1109d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    frames_to_process = ((freq_multiple) / (num_blocks * num_subbands)) + 1;
1110d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov
1111d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    return frames_to_process;
11127aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov}
11137aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov
1114b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovbool A2D_GetPacketTimestampSbc(const uint8_t *p_codec_info,
1115b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov                               const uint8_t *p_data, uint32_t *p_timestamp)
1116b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov{
1117b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    *p_timestamp = *(const uint32_t *)p_data;
1118b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    return true;
1119b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov}
1120b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov
1121b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovbool A2D_BuildCodecHeaderSbc(UNUSED_ATTR const uint8_t *p_codec_info,
1122b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov                             BT_HDR *p_buf, uint16_t frames_per_packet)
1123b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov{
1124b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    uint8_t *p;
1125b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov
1126b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    p_buf->offset -= A2D_SBC_MPL_HDR_LEN;
1127b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    p = (uint8_t *) (p_buf + 1) + p_buf->offset;
1128b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    p_buf->len += A2D_SBC_MPL_HDR_LEN;
1129b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    A2D_BldSbcMplHdr(p, false, false, false, (uint8_t) frames_per_packet);
1130b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov
1131b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov    return true;
1132b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov}
1133b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov
1134d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovvoid A2D_DumpCodecInfoSbc(const uint8_t *p_codec_info)
11357aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov{
11367aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov    tA2D_STATUS a2d_status;
11377aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov    tA2D_SBC_CIE sbc_cie;
11387aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov
113979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "%s", __func__);
11407aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov
1141d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false);
11427aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov    if (a2d_status != A2D_SUCCESS) {
114379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_ERROR(LOG_TAG, "%s: A2D_ParsSbcInfo fail:%d",
114479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov                  __func__, a2d_status);
11457aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov        return;
11467aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov    }
11477aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov
114879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_16) {
114979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tsamp_freq:%d (16000)", sbc_cie.samp_freq);
115079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_32) {
115179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tsamp_freq:%d (32000)", sbc_cie.samp_freq);
115279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_44) {
115379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tsamp_freq:%d (44.100)", sbc_cie.samp_freq);
115479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_48) {
115579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tsamp_freq:%d (48000)", sbc_cie.samp_freq);
115679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else {
115779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tBAD samp_freq:%d", sbc_cie.samp_freq);
115879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
11597aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov
116079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_MONO) {
116179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tch_mode:%d (Mono)", sbc_cie.ch_mode);
116279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_DUAL) {
116379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tch_mode:%d (Dual)", sbc_cie.ch_mode);
116479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_STEREO) {
116579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tch_mode:%d (Stereo)", sbc_cie.ch_mode);
116679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_JOINT) {
116779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tch_mode:%d (Joint)", sbc_cie.ch_mode);
116879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else {
116979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tBAD ch_mode:%d", sbc_cie.ch_mode);
117079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
11717aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov
117279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_4) {
117379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tblock_len:%d (4)", sbc_cie.block_len);
117479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_8) {
117579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tblock_len:%d (8)", sbc_cie.block_len);
117679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_12) {
117779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tblock_len:%d (12)", sbc_cie.block_len);
117879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_16) {
117979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tblock_len:%d (16)", sbc_cie.block_len);
118079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else {
118179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tBAD block_len:%d", sbc_cie.block_len);
118279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
118379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
118479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_4) {
118579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tnum_subbands:%d (4)", sbc_cie.num_subbands);
118679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_8) {
118779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tnum_subbands:%d (8)", sbc_cie.num_subbands);
118879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else {
118979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tBAD num_subbands:%d", sbc_cie.num_subbands);
119079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
119179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov
1192d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    if (sbc_cie.alloc_method == A2D_SBC_IE_ALLOC_MD_S) {
1193d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\talloc_method:%d (SNR)", sbc_cie.alloc_method);
1194d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov    } else if (sbc_cie.alloc_method == A2D_SBC_IE_ALLOC_MD_L) {
1195d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\talloc_method:%d (Loundess)", sbc_cie.alloc_method);
119679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    } else {
1197d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov        LOG_DEBUG(LOG_TAG, "\tBAD alloc_method:%d", sbc_cie.alloc_method);
119879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    }
11997aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov
120079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov    LOG_DEBUG(LOG_TAG, "\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool,
120179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov              sbc_cie.max_bitpool);
12027aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov}
12031394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov
12041394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavovconst tA2D_ENCODER_INTERFACE *A2D_GetEncoderInterfaceSbc(
12051394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    const uint8_t *p_codec_info)
12061394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov{
12071394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    if (!A2D_IsSourceCodecValidSbc(p_codec_info))
12081394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov        return NULL;
12091394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov
12101394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov    return &a2d_encoder_interface_sbc;
12111394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov}
1212