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