a2dp_sbc.cc revision a0db321d98c98e10f45720075fb9c83e3ef596bf
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" 340df29ac95d057a1bf74b003fa6dd6459743bcf54Mike J. Chen#include "bt_utils.h" 35d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov#include "embdrv/sbc/encoder/include/sbc_encoder.h" 3679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#include "osi/include/log.h" 37b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov#include "osi/include/osi.h" 3879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 3979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 4079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#define A2D_SBC_MAX_BITPOOL 53 4179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 42b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov/* data type for the SBC Codec Information Element*/ 43b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovtypedef struct 44b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov{ 45b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov uint8_t samp_freq; /* Sampling frequency */ 46b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov uint8_t ch_mode; /* Channel mode */ 47b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov uint8_t block_len; /* Block length */ 48b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov uint8_t num_subbands; /* Number of subbands */ 49b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov uint8_t alloc_method; /* Allocation method */ 50b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov uint8_t min_bitpool; /* Minimum bitpool */ 51b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov uint8_t max_bitpool; /* Maximum bitpool */ 52b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov} tA2D_SBC_CIE; 53b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 5479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov/* SBC SRC codec capabilities */ 5579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovstatic const tA2D_SBC_CIE a2d_sbc_caps = 5679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 5779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_SAMP_FREQ_44, /* samp_freq */ 5879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_CH_MD_JOINT, /* ch_mode */ 5979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_BLOCKS_16, /* block_len */ 6079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_SUBBAND_8, /* num_subbands */ 61d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_SBC_IE_ALLOC_MD_L, /* alloc_method */ 62d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_SBC_IE_MIN_BITPOOL, /* min_bitpool */ 63d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_SBC_MAX_BITPOOL /* max_bitpool */ 6479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}; 6579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 6679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov/* SBC SINK codec capabilities */ 6779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovstatic const tA2D_SBC_CIE a2d_sbc_sink_caps = 6879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 6979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov (A2D_SBC_IE_SAMP_FREQ_48 | A2D_SBC_IE_SAMP_FREQ_44), /* samp_freq */ 7079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov (A2D_SBC_IE_CH_MD_MONO | A2D_SBC_IE_CH_MD_STEREO | 7179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_CH_MD_JOINT | A2D_SBC_IE_CH_MD_DUAL), /* ch_mode */ 7279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov (A2D_SBC_IE_BLOCKS_16 | A2D_SBC_IE_BLOCKS_12 | 7379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_BLOCKS_8 | A2D_SBC_IE_BLOCKS_4), /* block_len */ 7479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov (A2D_SBC_IE_SUBBAND_4 | A2D_SBC_IE_SUBBAND_8), /* num_subbands */ 75d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov (A2D_SBC_IE_ALLOC_MD_L | A2D_SBC_IE_ALLOC_MD_S), /* alloc_method */ 76d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_SBC_IE_MIN_BITPOOL, /* min_bitpool */ 77d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_SBC_IE_MAX_BITPOOL /* max_bitpool */ 7879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}; 7979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 8079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov/* Default SBC codec configuration */ 8179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovconst tA2D_SBC_CIE a2d_sbc_default_config = 8279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 8379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_SAMP_FREQ_44, /* samp_freq */ 8479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_CH_MD_JOINT, /* ch_mode */ 8579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_BLOCKS_16, /* block_len */ 8679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov A2D_SBC_IE_SUBBAND_8, /* num_subbands */ 87d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_SBC_IE_ALLOC_MD_L, /* alloc_method */ 88d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_SBC_IE_MIN_BITPOOL, /* min_bitpool */ 89d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_SBC_MAX_BITPOOL /* max_bitpool */ 9079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov}; 910df29ac95d057a1bf74b003fa6dd6459743bcf54Mike J. Chen 92b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovstatic tA2D_STATUS A2D_CodecInfoMatchesCapabilitySbc( 93b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov const tA2D_SBC_CIE *p_cap, 94b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov const uint8_t *p_codec_info, 95b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov bool is_peer_codec_info); 96b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 97b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// Builds the SBC Media Codec Capabilities byte sequence beginning from the 98b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// LOSC octet. |media_type| is the media type |AVDT_MEDIA_TYPE_*|. 99b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// |p_ie| is a pointer to the SBC Codec Information Element information. 100b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// The result is stored in |p_result|. Returns A2D_SUCCESS on success, 101b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// otherwise the corresponding A2DP error status code. 102b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovstatic tA2D_STATUS A2D_BldSbcInfo(uint8_t media_type, const tA2D_SBC_CIE *p_ie, 103b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov uint8_t *p_result) 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tA2D_STATUS status; 1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if( p_ie == NULL || p_result == NULL || 1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (p_ie->samp_freq & ~A2D_SBC_IE_SAMP_FREQ_MSK) || 1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (p_ie->ch_mode & ~A2D_SBC_IE_CH_MD_MSK) || 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (p_ie->block_len & ~A2D_SBC_IE_BLOCKS_MSK) || 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (p_ie->num_subbands & ~A2D_SBC_IE_SUBBAND_MSK) || 112d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov (p_ie->alloc_method & ~A2D_SBC_IE_ALLOC_MD_MSK) || 113d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov (p_ie->min_bitpool > p_ie->max_bitpool) || 1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (p_ie->min_bitpool < A2D_SBC_IE_MIN_BITPOOL) || 115d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov (p_ie->min_bitpool > A2D_SBC_IE_MAX_BITPOOL) || 116d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov (p_ie->max_bitpool < A2D_SBC_IE_MIN_BITPOOL) || 117c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (p_ie->max_bitpool > A2D_SBC_IE_MAX_BITPOOL)) { 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* if any unused bit is set */ 1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project status = A2D_INVALID_PARAMS; 120c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } else { 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project status = A2D_SUCCESS; 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p_result++ = A2D_SBC_INFO_LEN; 123d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov *p_result++ = (media_type << 4); 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p_result++ = A2D_MEDIA_CT_SBC; 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Media Codec Specific Information Element */ 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p_result++ = p_ie->samp_freq | p_ie->ch_mode; 1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 129d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov *p_result++ = p_ie->block_len | p_ie->num_subbands | p_ie->alloc_method; 1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p_result++ = p_ie->min_bitpool; 1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p_result = p_ie->max_bitpool; 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return status; 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 137b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// Parses the SBC Media Codec Capabilities byte sequence beginning from the 138b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// LOSC octet. The result is stored in |p_ie|. The byte sequence to parse is 139b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// |p_codec_info|. If |for_caps| is true, the byte sequence is for get 140b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// capabilities response. Returns A2D_SUCCESS on success, otherwise the 141b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// corresponding A2DP error status code. 142b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovstatic tA2D_STATUS A2D_ParsSbcInfo(tA2D_SBC_CIE *p_ie, 143b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov const uint8_t *p_codec_info, 144b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov bool is_peer_src_codec_info) 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 14676198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge tA2D_STATUS status = A2D_SUCCESS; 147d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen uint8_t losc; 148d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov uint8_t media_type; 149d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_CODEC_TYPE codec_type; 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 15179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (p_ie == NULL || p_codec_info == NULL) 15276198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge return A2D_INVALID_PARAMS; 153cab5fc179730ce6910989307680b275195876c4dArman Uguray 154d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov // Check the codec capability length 155d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov losc = *p_codec_info++; 156d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (losc != A2D_SBC_INFO_LEN) 157d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return A2D_WRONG_CODEC; 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 159d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov media_type = (*p_codec_info++) >> 4; 160d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov codec_type = *p_codec_info++; 161d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov /* Check the Media Type and Media Codec Type */ 162d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (media_type != AVDT_MEDIA_TYPE_AUDIO || 163d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov codec_type != A2D_MEDIA_CT_SBC) { 16476198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge return A2D_WRONG_CODEC; 165d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 16676198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge 16779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_ie->samp_freq = *p_codec_info & A2D_SBC_IE_SAMP_FREQ_MSK; 16879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_ie->ch_mode = *p_codec_info & A2D_SBC_IE_CH_MD_MSK; 16979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_codec_info++; 17079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_ie->block_len = *p_codec_info & A2D_SBC_IE_BLOCKS_MSK; 17179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_ie->num_subbands = *p_codec_info & A2D_SBC_IE_SUBBAND_MSK; 172d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov p_ie->alloc_method = *p_codec_info & A2D_SBC_IE_ALLOC_MD_MSK; 17379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_codec_info++; 17479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_ie->min_bitpool = *p_codec_info++; 17579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_ie->max_bitpool = *p_codec_info; 176d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (p_ie->min_bitpool < A2D_SBC_IE_MIN_BITPOOL || 177d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov p_ie->min_bitpool > A2D_SBC_IE_MAX_BITPOOL) { 17876198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge status = A2D_BAD_MIN_BITPOOL; 179d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 18076198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge 181d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (p_ie->max_bitpool < A2D_SBC_IE_MIN_BITPOOL || 182d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov p_ie->max_bitpool > A2D_SBC_IE_MAX_BITPOOL || 183d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov p_ie->max_bitpool < p_ie->min_bitpool) { 18476198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge status = A2D_BAD_MAX_BITPOOL; 185d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 18676198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge 18779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (is_peer_src_codec_info) 18876198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge return status; 18976198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge 19076198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge if (A2D_BitsSet(p_ie->samp_freq) != A2D_SET_ONE_BIT) 19176198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge status = A2D_BAD_SAMP_FREQ; 19276198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge if (A2D_BitsSet(p_ie->ch_mode) != A2D_SET_ONE_BIT) 19376198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge status = A2D_BAD_CH_MODE; 19476198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge if (A2D_BitsSet(p_ie->block_len) != A2D_SET_ONE_BIT) 19576198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge status = A2D_BAD_BLOCK_LEN; 19676198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge if (A2D_BitsSet(p_ie->num_subbands) != A2D_SET_ONE_BIT) 19776198e72bf5b8942dbc97bb53c97dba62bf30da1Ian Coolidge status = A2D_BAD_SUBBANDS; 198d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (A2D_BitsSet(p_ie->alloc_method) != A2D_SET_ONE_BIT) 199d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov status = A2D_BAD_ALLOC_METHOD; 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return status; 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function A2D_BldSbcMplHdr 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is called by an application to parse 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** the SBC Media Payload header. 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Input Parameters: 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** frag: 1, if fragmented. 0, otherwise. 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** start: 1, if the starting packet of a fragmented frame. 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** last: 1, if the last packet of a fragmented frame. 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** num: If frag is 1, this is the number of remaining fragments 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** (including this fragment) of this frame. 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** If frag is 0, this is the number of frames in this packet. 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Output Parameters: 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** p_dst: the resulting media payload header byte sequence. 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns void. 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 226b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovstatic void A2D_BldSbcMplHdr(uint8_t *p_dst, bool frag, bool start, bool last, 227b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov uint8_t num) 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 229b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov if (p_dst == NULL) 230b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov return; 231b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov 232b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov *p_dst = 0; 233b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov if (frag) 234b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov *p_dst |= A2D_SBC_HDR_F_MSK; 235b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov if (start) 236b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov *p_dst |= A2D_SBC_HDR_S_MSK; 237b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov if (last) 238b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov *p_dst |= A2D_SBC_HDR_L_MSK; 239b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov *p_dst |= (A2D_SBC_HDR_NUM_MSK & num); 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function A2D_ParsSbcMplHdr 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is called by an application to parse 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** the SBC Media Payload header. 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Input Parameters: 2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** p_src: the byte sequence to parse.. 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Output Parameters: 2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** frag: 1, if fragmented. 0, otherwise. 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** start: 1, if the starting packet of a fragmented frame. 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** last: 1, if the last packet of a fragmented frame. 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** num: If frag is 1, this is the number of remaining fragments 2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** (including this fragment) of this frame. 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** If frag is 0, this is the number of frames in this packet. 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns void. 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 264d19e0785e662e640191a075eda07acce61c2aedaMarie Janssenvoid A2D_ParsSbcMplHdr(uint8_t *p_src, bool *p_frag, bool *p_start, bool *p_last, uint8_t *p_num) 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(p_src && p_frag && p_start && p_last && p_num) 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 268d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen *p_frag = (*p_src & A2D_SBC_HDR_F_MSK) ? true: false; 269d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen *p_start= (*p_src & A2D_SBC_HDR_S_MSK) ? true: false; 270d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen *p_last = (*p_src & A2D_SBC_HDR_L_MSK) ? true: false; 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p_num = (*p_src & A2D_SBC_HDR_NUM_MSK); 2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 27579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_InitCodecConfigSbc(tAVDT_CFG *p_cfg) 27679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 277d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &a2d_sbc_caps, 27879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_cfg->codec_info) != A2D_SUCCESS) { 27979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return false; 28079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 28179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 28279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#if (BTA_AV_CO_CP_SCMS_T == TRUE) 28379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* Content protection info - support SCMS-T */ 28479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov uint8_t *p = p_cfg->protect_info; 28579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov *p++ = BTA_AV_CP_LOSC; 28679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID); 28779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_cfg->num_protect = 1; 28879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov#endif 28979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 29079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return true; 29179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 29279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 293b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovconst char *A2D_CodecNameSbc(UNUSED_ATTR const uint8_t *p_codec_info) 294b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov{ 295b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov return "SBC"; 296b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov} 297b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov 29879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_InitCodecConfigSbcSink(tAVDT_CFG *p_cfg) 29979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 300d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &a2d_sbc_sink_caps, 30179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_cfg->codec_info) != A2D_SUCCESS) { 30279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return false; 30379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 30479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 30579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return true; 30679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 30779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 308a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavovbool A2D_IsSourceCodecValidSbc(const uint8_t *p_codec_info) 309a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov{ 310a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov tA2D_SBC_CIE cfg_cie; 311a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov 312a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov /* Use a liberal check when parsing the codec info */ 313a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov return (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, false) == A2D_SUCCESS) || 314a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, true) == A2D_SUCCESS); 315a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov} 316a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov 317a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavovbool A2D_IsSinkCodecValidSbc(const uint8_t *p_codec_info) 318a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov{ 319a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov tA2D_SBC_CIE cfg_cie; 320a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov 321a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov /* Use a liberal check when parsing the codec info */ 322a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov return (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, false) == A2D_SUCCESS) || 323a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, true) == A2D_SUCCESS); 324a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov} 325a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov 326a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavovbool A2D_IsPeerSourceCodecValidSbc(const uint8_t *p_codec_info) 327a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov{ 328a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov tA2D_SBC_CIE cfg_cie; 329a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov 330a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov /* Use a liberal check when parsing the codec info */ 331a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov return (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, false) == A2D_SUCCESS) || 332a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, true) == A2D_SUCCESS); 333a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov} 334a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov 335a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavovbool A2D_IsPeerSinkCodecValidSbc(const uint8_t *p_codec_info) 336b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov{ 337b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_SBC_CIE cfg_cie; 338b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 339b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov /* Use a liberal check when parsing the codec info */ 340b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov return (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, false) == A2D_SUCCESS) || 341b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov (A2D_ParsSbcInfo(&cfg_cie, p_codec_info, true) == A2D_SUCCESS); 342b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov} 343b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 34479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_IsSourceCodecSupportedSbc(const uint8_t *p_codec_info) 34579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 34679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return (A2D_CodecInfoMatchesCapabilitySbc(&a2d_sbc_caps, p_codec_info, 34779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov false) == A2D_SUCCESS); 34879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 34979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 35079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_IsSinkCodecSupportedSbc(const uint8_t *p_codec_info) 35179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 35279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return (A2D_CodecInfoMatchesCapabilitySbc(&a2d_sbc_sink_caps, p_codec_info, 35379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov false) == A2D_SUCCESS); 35479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 35579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 35679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_IsPeerSourceCodecSupportedSbc(const uint8_t *p_codec_info) 35779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 35879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return (A2D_CodecInfoMatchesCapabilitySbc(&a2d_sbc_sink_caps, p_codec_info, 35979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov true) == A2D_SUCCESS); 36079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 36179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 36279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovvoid A2D_InitDefaultCodecSbc(uint8_t *p_codec_info) 36379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 364d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &a2d_sbc_default_config, 36579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov p_codec_info) != A2D_SUCCESS) { 36679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: A2D_BldSbcInfo failed", __func__); 36779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 36879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 36979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 37079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovbool A2D_SetCodecSbc(const tA2D_AV_MEDIA_FEEDINGS *p_feeding, 37179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov uint8_t *p_codec_info) 37279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 373c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE sbc_config = a2d_sbc_default_config; 374c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 375c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s", __func__); 376c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 377c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* Check the number of channels */ 378c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if ((p_feeding->num_channel != 1) && (p_feeding->num_channel != 2)) { 379c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: Unsupported PCM channel number %d", 380c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, p_feeding->num_channel); 381c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return false; 382c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 383c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 384c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* Check the bits per sample */ 385c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if ((p_feeding->bit_per_sample != 8) && 386c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (p_feeding->bit_per_sample != 16)) { 387c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: Unsupported PCM sample size %d", 388c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, p_feeding->bit_per_sample); 389c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return false; 390c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 39179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 392c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* Check the sampling frequency */ 393c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov switch (p_feeding->sampling_freq) { 394c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 8000: 395c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 12000: 396c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 16000: 397c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 24000: 398c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 32000: 399c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 48000: 400c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_48; 401c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov break; 402c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 11025: 403c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 22050: 404c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov case 44100: 405c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_44; 406c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov break; 40779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov default: 408c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: Unsupported PCM sampling frequency %d", 409c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, p_feeding->sampling_freq); 410c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return false; 411c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 412c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 413c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* Build the codec config */ 414c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &sbc_config, p_codec_info) 415c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov != A2D_SUCCESS) { 416c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: A2D_BldSbcInfo failed", __func__); 41779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return false; 41879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 41979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 42079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return true; 42179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 42279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 423b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// Checks whether A2DP SBC codec configuration matches with a device's codec 424b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// capabilities. |p_cap| is the SBC codec configuration. |p_codec_info| is 425b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// the device's codec capabilities. |is_peer_src_codec_info| is true if 426b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// |p_codec_info| contains the codec capabilities for a peer device that 427b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// is acting as an A2DP source. 428b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// Returns A2D_SUCCESS if the codec configuration matches with capabilities, 429b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov// otherwise the corresponding A2DP error status code. 43079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavovstatic tA2D_STATUS A2D_CodecInfoMatchesCapabilitySbc( 43179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov const tA2D_SBC_CIE *p_cap, 43279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov const uint8_t *p_codec_info, 43379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov bool is_peer_src_codec_info) 43479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 43579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov tA2D_STATUS status; 43679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov tA2D_SBC_CIE cfg_cie; 43779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 43879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* parse configuration */ 43979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov status = A2D_ParsSbcInfo(&cfg_cie, p_codec_info, is_peer_src_codec_info); 44079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (status != A2D_SUCCESS) { 44179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: parsing failed %d", __func__, status); 44279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return status; 44379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 44479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 44579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* verify that each parameter is in range */ 44679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 44779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "FREQ peer: 0x%x, capability 0x%x", 44879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov cfg_cie.samp_freq, p_cap->samp_freq); 44979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "CH_MODE peer: 0x%x, capability 0x%x", 45079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov cfg_cie.ch_mode, p_cap->ch_mode); 45179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "BLOCK_LEN peer: 0x%x, capability 0x%x", 45279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov cfg_cie.block_len, p_cap->block_len); 45379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "SUB_BAND peer: 0x%x, capability 0x%x", 45479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov cfg_cie.num_subbands, p_cap->num_subbands); 455d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "ALLOC_METHOD peer: 0x%x, capability 0x%x", 456d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov cfg_cie.alloc_method, p_cap->alloc_method); 45779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "MIN_BitPool peer: 0x%x, capability 0x%x", 45879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov cfg_cie.min_bitpool, p_cap->min_bitpool); 459d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "MAX_BitPool peer: 0x%x, capability 0x%x", 460d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov cfg_cie.max_bitpool, p_cap->max_bitpool); 46179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 46279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* sampling frequency */ 46379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) 46479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return A2D_NS_SAMP_FREQ; 46579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 46679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* channel mode */ 46779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0) 46879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return A2D_NS_CH_MODE; 46979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 47079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* block length */ 47179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if ((cfg_cie.block_len & p_cap->block_len) == 0) 47279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return A2D_BAD_BLOCK_LEN; 47379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 47479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* subbands */ 47579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0) 47679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return A2D_NS_SUBBANDS; 47779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 47879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* allocation method */ 479d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if ((cfg_cie.alloc_method & p_cap->alloc_method) == 0) 480d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return A2D_NS_ALLOC_METHOD; 48179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 48279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* min bitpool */ 48379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (cfg_cie.min_bitpool < p_cap->min_bitpool) 48479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return A2D_NS_MIN_BITPOOL; 48579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 486d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov /* max bitpool */ 487d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (cfg_cie.max_bitpool > p_cap->max_bitpool) 488d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return A2D_NS_MAX_BITPOOL; 489d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 49079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return A2D_SUCCESS; 49179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 49279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 493c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin RadoslavovtA2D_STATUS A2D_BuildSrc2SinkConfigSbc(const uint8_t *p_src_cap, 494c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov uint8_t *p_pref_cfg) 49579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 49679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov tA2D_SBC_CIE src_cap; 49779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov tA2D_SBC_CIE pref_cap; 49879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 49979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* initialize it to default SBC configuration */ 500d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &a2d_sbc_default_config, p_pref_cfg); 50179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 50279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* now try to build a preferred one */ 50379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov /* parse configuration */ 50479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov tA2D_STATUS status = A2D_ParsSbcInfo(&src_cap, p_src_cap, true); 50579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (status != A2D_SUCCESS) { 50679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: can't parse src cap ret = %d", 50779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov __func__, status); 50879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return A2D_FAIL; 50979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 51079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 51179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (src_cap.samp_freq & A2D_SBC_IE_SAMP_FREQ_48) 51279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.samp_freq = A2D_SBC_IE_SAMP_FREQ_48; 51379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov else if (src_cap.samp_freq & A2D_SBC_IE_SAMP_FREQ_44) 51479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.samp_freq = A2D_SBC_IE_SAMP_FREQ_44; 51579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 51679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_JOINT) 51779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.ch_mode = A2D_SBC_IE_CH_MD_JOINT; 51879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_STEREO) 51979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.ch_mode = A2D_SBC_IE_CH_MD_STEREO; 52079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_DUAL) 52179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.ch_mode = A2D_SBC_IE_CH_MD_DUAL; 52279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_MONO) 52379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.ch_mode = A2D_SBC_IE_CH_MD_MONO; 52479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 52579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (src_cap.block_len & A2D_SBC_IE_BLOCKS_16) 52679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.block_len = A2D_SBC_IE_BLOCKS_16; 52779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_12) 52879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.block_len = A2D_SBC_IE_BLOCKS_12; 52979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_8) 53079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.block_len = A2D_SBC_IE_BLOCKS_8; 53179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov else if (src_cap.block_len & A2D_SBC_IE_BLOCKS_4) 53279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.block_len = A2D_SBC_IE_BLOCKS_4; 53379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 53479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (src_cap.num_subbands & A2D_SBC_IE_SUBBAND_8) 53579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.num_subbands = A2D_SBC_IE_SUBBAND_8; 53679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov else if(src_cap.num_subbands & A2D_SBC_IE_SUBBAND_4) 53779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.num_subbands = A2D_SBC_IE_SUBBAND_4; 53879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 539d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (src_cap.alloc_method & A2D_SBC_IE_ALLOC_MD_L) 540d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov pref_cap.alloc_method = A2D_SBC_IE_ALLOC_MD_L; 541d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov else if(src_cap.alloc_method & A2D_SBC_IE_ALLOC_MD_S) 542d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov pref_cap.alloc_method = A2D_SBC_IE_ALLOC_MD_S; 54379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 54479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov pref_cap.min_bitpool = src_cap.min_bitpool; 545d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov pref_cap.max_bitpool = src_cap.max_bitpool; 54679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 547d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &pref_cap, p_pref_cfg); 54879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 54979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov return A2D_SUCCESS; 55079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 55179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 552c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin RadoslavovtA2D_STATUS A2D_BuildSinkConfigSbc(const uint8_t *p_src_config, 553c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov const uint8_t *p_sink_cap, 554c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov uint8_t *p_result_sink_config) 555c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov{ 556c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE src_config_cie; 557c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE sink_cap_cie; 558c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 559c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* Decode the source codec config */ 560c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&src_config_cie, 561c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov p_src_config, false); 562c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 563c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode source codec information: %d", 564c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, a2d_status); 565c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return A2D_FAIL; 566c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 567c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 568c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* Decode the sink codec capabilities */ 569c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov a2d_status = A2D_ParsSbcInfo(&sink_cap_cie, p_sink_cap, true); 570c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 571c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode sink capability information: %d", 572c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, a2d_status); 573c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return A2D_FAIL; 574c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 575c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 576c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* Update the bitpool boundaries from the sink codec capabilities */ 577c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov src_config_cie.min_bitpool = sink_cap_cie.min_bitpool; 578c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov src_config_cie.max_bitpool = sink_cap_cie.max_bitpool; 579c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 580c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* Build the result sink config from the source config */ 581c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov A2D_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &src_config_cie, 582c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov p_result_sink_config); 583c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 584c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return A2D_SUCCESS; 585c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov} 586c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 587b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovbool A2D_CodecTypeEqualsSbc(const uint8_t *p_codec_info_a, 588b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov const uint8_t *p_codec_info_b) 58979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 590b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_SBC_CIE sbc_cie_a; 591b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_SBC_CIE sbc_cie_b; 592b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 593b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov // Check whether the codec info contains valid data 594b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie_a, p_codec_info_a, false); 595b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 596b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 597b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov __func__, a2d_status); 598b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov return false; 599b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov } 600b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov a2d_status = A2D_ParsSbcInfo(&sbc_cie_b, p_codec_info_b, false); 601b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 602b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 603b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov __func__, a2d_status); 604b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov return false; 605b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov } 606b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 607b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_CODEC_TYPE codec_type_a = A2D_GetCodecType(p_codec_info_a); 608b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_CODEC_TYPE codec_type_b = A2D_GetCodecType(p_codec_info_b); 609b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 610b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov return (codec_type_a == codec_type_b) && (codec_type_a == A2D_MEDIA_CT_SBC); 61179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov} 61279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 613c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovbool A2D_CodecEqualsSbc(const uint8_t *p_codec_info_a, 614c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov const uint8_t *p_codec_info_b) 615c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov{ 616c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE sbc_cie_a; 617c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE sbc_cie_b; 618c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 619c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov // Check whether the codec info contains valid data 620c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie_a, p_codec_info_a, false); 621c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 622c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 623c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, a2d_status); 624c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return false; 625c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 626c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov a2d_status = A2D_ParsSbcInfo(&sbc_cie_b, p_codec_info_b, false); 627c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 628c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 629c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, a2d_status); 630c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return false; 631c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 632c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 633c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_CODEC_TYPE codec_type_a = A2D_GetCodecType(p_codec_info_a); 634c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_CODEC_TYPE codec_type_b = A2D_GetCodecType(p_codec_info_b); 635c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 636c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if ((codec_type_a != codec_type_b) || (codec_type_a != A2D_MEDIA_CT_SBC)) 637c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return false; 638c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 639c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return (sbc_cie_a.samp_freq == sbc_cie_b.samp_freq) && 640c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.ch_mode == sbc_cie_b.ch_mode) && 641c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.block_len == sbc_cie_b.block_len) && 642c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.num_subbands == sbc_cie_b.num_subbands) && 643c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.alloc_method == sbc_cie_b.alloc_method) && 644c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.min_bitpool == sbc_cie_b.min_bitpool) && 645c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.max_bitpool == sbc_cie_b.max_bitpool); 646c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov} 647c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 648c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovbool A2D_CodecRequiresReconfigSbc(const uint8_t *p_codec_info_a, 649c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov const uint8_t *p_codec_info_b) 650c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov{ 651c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE sbc_cie_a; 652c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE sbc_cie_b; 653c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 654c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov // Check whether the codec info contains valid data 655c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie_a, p_codec_info_a, false); 656c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 657c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 658c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, a2d_status); 659c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return true; 660c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 661c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov a2d_status = A2D_ParsSbcInfo(&sbc_cie_b, p_codec_info_b, false); 662c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 663c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 664c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, a2d_status); 665c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return true; 666c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 667c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 668c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_CODEC_TYPE codec_type_a = A2D_GetCodecType(p_codec_info_a); 669c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_CODEC_TYPE codec_type_b = A2D_GetCodecType(p_codec_info_b); 670c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 671c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if ((codec_type_a != codec_type_b) || (codec_type_a != A2D_MEDIA_CT_SBC)) 672c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return true; 673c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 674c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* NOTE: The min_bitpool and max_bitpool fields are ignored */ 675c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return (sbc_cie_a.samp_freq != sbc_cie_b.samp_freq) || 676c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.ch_mode != sbc_cie_b.ch_mode) || 677c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.block_len != sbc_cie_b.block_len) || 678c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.num_subbands != sbc_cie_b.num_subbands) || 679c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_a.alloc_method != sbc_cie_b.alloc_method); 680c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov} 681c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 682c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovbool A2D_CodecConfigMatchesCapabilitiesSbc(const uint8_t *p_codec_config, 683c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov const uint8_t *p_codec_caps) 684c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov{ 685c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE sbc_cie_config; 686c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_SBC_CIE sbc_cie_caps; 687c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 688c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov // Check whether the codec info contains valid data 689c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie_config, p_codec_config, 690c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov false); 691c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 692c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec config: %d", 693c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, a2d_status); 694c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return false; 695c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 696c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov a2d_status = A2D_ParsSbcInfo(&sbc_cie_caps, p_codec_caps, true); 697c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 698c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec capabilities: %d", 699c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov __func__, a2d_status); 700c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov return false; 701c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov } 702c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 703c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov /* 704c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov * Must match all SBC codec fields except min/max bitpool boundaries which 705c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov * can be adjusted. 706c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov */ 707a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov bool result = 708a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov (sbc_cie_config.samp_freq & sbc_cie_caps.samp_freq) && 709c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_config.ch_mode & sbc_cie_caps.ch_mode) && 710c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_config.block_len & sbc_cie_caps.block_len) && 711c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_config.num_subbands & sbc_cie_caps.num_subbands) && 712c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov (sbc_cie_config.alloc_method & sbc_cie_caps.alloc_method); 713a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov 714a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: result=%s", __func__, result ? "true" : "false"); 715a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: config samp_freq=0x%x ch_mode=0x%x block_len=0x%x " 716a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov "num_subbands=0x%x alloc_method=0x%x", 717a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov __func__, 718a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov sbc_cie_config.samp_freq, sbc_cie_config.ch_mode, 719a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov sbc_cie_config.block_len, sbc_cie_config.num_subbands, 720a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov sbc_cie_config.alloc_method); 721a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: caps samp_freq=0x%x ch_mode=0x%x block_len=0x%x " 722a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov "num_subbands=0x%x alloc_method=0x%x", 723a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov __func__, 724a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov sbc_cie_caps.samp_freq, sbc_cie_caps.ch_mode, 725a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov sbc_cie_caps.block_len, sbc_cie_caps.num_subbands, 726a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov sbc_cie_caps.alloc_method); 727a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov 728a0db321d98c98e10f45720075fb9c83e3ef596bfPavlin Radoslavov return result; 729c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov} 730c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 731d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetTrackFrequencySbc(const uint8_t *p_codec_info) 73279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov{ 733d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 734d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 735d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 736d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 737d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 738d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 739d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 740d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 741d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 742d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.samp_freq) { 743d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_16: 744d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 16000; 745d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_32: 746d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 32000; 747d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_44: 748d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 44100; 749d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_48: 750d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 48000; 751d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 752d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 753d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 754d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 755d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 756d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov} 757d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 758d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetTrackChannelCountSbc(const uint8_t *p_codec_info) 759d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{ 760d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 761d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 762d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 763d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 764d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 765d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 766d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 767d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 768d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 769d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.ch_mode) { 770d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_MONO: 771d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 1; 772d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_DUAL: 773d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_STEREO: 774d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_JOINT: 775d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 2; 776d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 777d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 778d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 779d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 780d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 781d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov} 782d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 783d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetNumberOfSubbandsSbc(const uint8_t *p_codec_info) 784d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{ 785d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 786d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 787d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 788d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 789d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 790d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 791d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 792d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 793d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 794d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.num_subbands) { 795d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SUBBAND_4: 796d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 4; 797d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SUBBAND_8: 798d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 8; 799d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 800d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 801d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 802d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 803d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 804d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov} 805d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 806d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetNumberOfBlocksSbc(const uint8_t *p_codec_info) 807d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{ 808d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 809d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 810d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 811d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 812d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 813d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 814d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 815d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 816d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 817d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.block_len) { 818d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_BLOCKS_4: 819d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 4; 820d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_BLOCKS_8: 821d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 8; 822d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_BLOCKS_12: 823d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 12; 824d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_BLOCKS_16: 825d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 16; 826d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 827d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 828d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 829d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 830d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 831d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov} 832d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 833d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetAllocationMethodCodeSbc(const uint8_t *p_codec_info) 834d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{ 835d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 836d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 837d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 838d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 839d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 840d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 841d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 8427aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov } 843d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 844d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.alloc_method) { 845d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_ALLOC_MD_S: 846d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_SNR; 847d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_ALLOC_MD_L: 848d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_LOUDNESS; 849d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 850d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 851d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 852d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 853d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 854d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov} 855d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 856d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetChannelModeCodeSbc(const uint8_t *p_codec_info) 857d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{ 858d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 859d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 860d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 861d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 862d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 863d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 864d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 865d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 866d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 867d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.ch_mode) { 868d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_MONO: 869d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_MONO; 870d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_DUAL: 871d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_DUAL; 872d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_STEREO: 873d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_STEREO; 874d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_JOINT: 875d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_JOINT_STEREO; 876d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 877d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 878d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 879d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 880d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 881d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov} 882d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 883d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetSamplingFrequencyCodeSbc(const uint8_t *p_codec_info) 884d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{ 885d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 886d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 887d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 888d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 889d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 890d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 891d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 892d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 893d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 894d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.samp_freq) { 895d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_16: 896d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_sf16000; 897d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_32: 898d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_sf32000; 899d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_44: 900d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_sf44100; 901d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_48: 902d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return SBC_sf48000; 903d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 904d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 905d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 906d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 907d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 908d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov} 909d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 910b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovint A2D_GetMinBitpoolSbc(const uint8_t *p_codec_info) 911b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov{ 912b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_SBC_CIE sbc_cie; 913b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 914b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 915b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 916b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 917b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov __func__, a2d_status); 918b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov return -1; 919b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov } 920b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 921b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov return sbc_cie.min_bitpool; 922b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov} 923b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 924b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavovint A2D_GetMaxBitpoolSbc(const uint8_t *p_codec_info) 925b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov{ 926b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_SBC_CIE sbc_cie; 927b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 928b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 929b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 930b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 931b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov __func__, a2d_status); 932b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov return -1; 933b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov } 934b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 935b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov return sbc_cie.max_bitpool; 936b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov} 937b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 938d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetSinkTrackChannelTypeSbc(const uint8_t *p_codec_info) 939d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{ 940d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 941d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 942d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 943d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 944d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 945d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 946d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 947d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 948d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 949d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.ch_mode) { 950d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_MONO: 951d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 1; 952d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_DUAL: 953d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_STEREO: 954d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_JOINT: 955d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return 3; 956d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 957d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 958d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 959d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 960d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 961d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov} 962d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 963d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovint A2D_GetSinkFramesCountToProcessSbc(uint64_t time_interval_ms, 964d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov const uint8_t *p_codec_info) 965d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov{ 966d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 967d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov uint32_t freq_multiple; 968d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov uint32_t num_blocks; 969d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov uint32_t num_subbands; 970d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov int frames_to_process; 971d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 972d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov tA2D_STATUS a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 973d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 974d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", 975d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov __func__, a2d_status); 976d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 977d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 978d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 979d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov // Check the sample frequency 980d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.samp_freq) { 981d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_16: 982d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: samp_freq:%d (16000)", __func__, 983d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.samp_freq); 984d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov freq_multiple = 16 * time_interval_ms; 985d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 986d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_32: 987d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: samp_freq:%d (32000)", __func__, 988d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.samp_freq); 989d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov freq_multiple = 32 * time_interval_ms; 990d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 991d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_44: 992d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: samp_freq:%d (44100)", __func__, 993d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.samp_freq); 994d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov freq_multiple = (441 * time_interval_ms) / 10; 995d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 996d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SAMP_FREQ_48: 997d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: samp_freq:%d (48000)", __func__, 998d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.samp_freq); 999d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov freq_multiple = 48 * time_interval_ms; 1000d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1001d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 1002d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: unknown frequency: %d", __func__, 1003d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.samp_freq); 1004d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 1005d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 1006d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 1007d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov // Check the channel mode 1008d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.ch_mode) { 1009d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_MONO: 1010d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: ch_mode:%d (Mono)", __func__, 1011d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.ch_mode); 1012d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1013d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_DUAL: 1014d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: ch_mode:%d (DUAL)", __func__, 1015d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.ch_mode); 1016d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1017d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_STEREO: 1018d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: ch_mode:%d (STEREO)", __func__, 1019d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.ch_mode); 1020d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1021d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_CH_MD_JOINT: 1022d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: ch_mode:%d (JOINT)", __func__, 1023d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.ch_mode); 1024d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1025d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 1026d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: unknown channel mode: %d", __func__, 1027d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.ch_mode); 1028d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 1029d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 1030d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 1031d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov // Check the block length 1032d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.block_len) { 1033d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_BLOCKS_4: 1034d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: block_len:%d (4)", __func__, 1035d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.block_len); 1036d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov num_blocks = 4; 1037d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1038d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_BLOCKS_8: 1039d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: block_len:%d (8)", __func__, 1040d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.block_len); 1041d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov num_blocks = 8; 1042d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1043d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_BLOCKS_12: 1044d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: block_len:%d (12)", __func__, 1045d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.block_len); 1046d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov num_blocks = 12; 1047d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1048d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_BLOCKS_16: 1049d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: block_len:%d (16)", __func__, 1050d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.block_len); 1051d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov num_blocks = 16; 1052d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1053d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 1054d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: unknown block length: %d", __func__, 1055d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.block_len); 1056d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 1057d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 1058d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 1059d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov // Check the number of sub-bands 1060d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.num_subbands) { 1061d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SUBBAND_4: 1062d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: num_subbands:%d (4)", __func__, 1063d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.num_subbands); 1064d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov num_subbands = 4; 1065d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1066d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_SUBBAND_8: 1067d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: num_subbands:%d (8)", __func__, 1068d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.num_subbands); 1069d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov num_subbands = 8; 1070d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1071d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 1072d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: unknown number of subbands: %d", __func__, 1073d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.num_subbands); 1074d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 1075d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 1076d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 1077d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov // Check the allocation method 1078d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov switch (sbc_cie.alloc_method) { 1079d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_ALLOC_MD_S: 1080d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: alloc_method:%d (SNR)", __func__, 1081d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.alloc_method); 1082d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1083d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov case A2D_SBC_IE_ALLOC_MD_L: 1084d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: alloc_method:%d (Loudness)", __func__, 1085d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.alloc_method); 1086d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov break; 1087d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov default: 1088d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: unknown allocation method: %d", __func__, 1089d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.alloc_method); 1090d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return -1; 1091d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } 1092d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 1093d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s: Bit pool Min:%d Max:%d", __func__, 1094d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov sbc_cie.min_bitpool, sbc_cie.max_bitpool); 1095d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 1096d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov frames_to_process = ((freq_multiple) / (num_blocks * num_subbands)) + 1; 1097d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov 1098d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov return frames_to_process; 10997aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov} 11007aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov 1101b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovbool A2D_GetPacketTimestampSbc(const uint8_t *p_codec_info, 1102b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov const uint8_t *p_data, uint32_t *p_timestamp) 1103b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov{ 1104b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov *p_timestamp = *(const uint32_t *)p_data; 1105b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov return true; 1106b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov} 1107b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov 1108b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovbool A2D_BuildCodecHeaderSbc(UNUSED_ATTR const uint8_t *p_codec_info, 1109b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov BT_HDR *p_buf, uint16_t frames_per_packet) 1110b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov{ 1111b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov uint8_t *p; 1112b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov 1113b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov p_buf->offset -= A2D_SBC_MPL_HDR_LEN; 1114b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov p = (uint8_t *) (p_buf + 1) + p_buf->offset; 1115b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov p_buf->len += A2D_SBC_MPL_HDR_LEN; 1116b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov A2D_BldSbcMplHdr(p, false, false, false, (uint8_t) frames_per_packet); 1117b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov 1118b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov return true; 1119b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov} 1120b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov 1121d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavovvoid A2D_DumpCodecInfoSbc(const uint8_t *p_codec_info) 11227aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov{ 11237aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov tA2D_STATUS a2d_status; 11247aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov tA2D_SBC_CIE sbc_cie; 11257aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov 112679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "%s", __func__); 11277aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov 1128d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec_info, false); 11297aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov if (a2d_status != A2D_SUCCESS) { 113079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_ERROR(LOG_TAG, "%s: A2D_ParsSbcInfo fail:%d", 113179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov __func__, a2d_status); 11327aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov return; 11337aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov } 11347aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov 113579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_16) { 113679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tsamp_freq:%d (16000)", sbc_cie.samp_freq); 113779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_32) { 113879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tsamp_freq:%d (32000)", sbc_cie.samp_freq); 113979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_44) { 114079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tsamp_freq:%d (44.100)", sbc_cie.samp_freq); 114179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_48) { 114279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tsamp_freq:%d (48000)", sbc_cie.samp_freq); 114379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else { 114479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tBAD samp_freq:%d", sbc_cie.samp_freq); 114579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 11467aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov 114779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_MONO) { 114879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tch_mode:%d (Mono)", sbc_cie.ch_mode); 114979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_DUAL) { 115079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tch_mode:%d (Dual)", sbc_cie.ch_mode); 115179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_STEREO) { 115279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tch_mode:%d (Stereo)", sbc_cie.ch_mode); 115379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_JOINT) { 115479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tch_mode:%d (Joint)", sbc_cie.ch_mode); 115579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else { 115679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tBAD ch_mode:%d", sbc_cie.ch_mode); 115779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 11587aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov 115979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_4) { 116079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tblock_len:%d (4)", sbc_cie.block_len); 116179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_8) { 116279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tblock_len:%d (8)", sbc_cie.block_len); 116379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_12) { 116479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tblock_len:%d (12)", sbc_cie.block_len); 116579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_16) { 116679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tblock_len:%d (16)", sbc_cie.block_len); 116779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else { 116879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tBAD block_len:%d", sbc_cie.block_len); 116979506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 117079506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 117179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_4) { 117279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tnum_subbands:%d (4)", sbc_cie.num_subbands); 117379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_8) { 117479506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tnum_subbands:%d (8)", sbc_cie.num_subbands); 117579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else { 117679506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tBAD num_subbands:%d", sbc_cie.num_subbands); 117779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 117879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 1179d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov if (sbc_cie.alloc_method == A2D_SBC_IE_ALLOC_MD_S) { 1180d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "\talloc_method:%d (SNR)", sbc_cie.alloc_method); 1181d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov } else if (sbc_cie.alloc_method == A2D_SBC_IE_ALLOC_MD_L) { 1182d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "\talloc_method:%d (Loundess)", sbc_cie.alloc_method); 118379506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } else { 1184d7ff47cc64838ecd9d5a8366b75815aab97b6f7dPavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tBAD alloc_method:%d", sbc_cie.alloc_method); 118579506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov } 11867aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov 118779506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov LOG_DEBUG(LOG_TAG, "\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, 118879506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov sbc_cie.max_bitpool); 11897aaf7c6c42a06e174ce305000ab7a223dc99cbdfPavlin Radoslavov} 1190