Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3591fc39 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Localize the usage of tA2D_SBC_CIE only within the SBC codec

* Added new A2DP API and use it as appropriate
 - A2D_IsValidCodec()
 - A2D_CodecTypeEquals()
 - A2D_GetMinBitpool()
 - A2D_GetMaxBitpool()
* Removed A2D_GetDefaultConfigSbc(), because it is not needed anymore.
* Removed bta_av_co_audio_get_sbc_config() and replaced it
  with code that is not SBC codec-specific:
  bta_av_co_audio_encoder_init() and bta_av_co_audio_encoder_update()
* Removed bta_av_co_get_remote_bitpool_pref() because it is
  not used/needed anymore.
* Moved the following declarations the a2d_sbc.h header file to
  the a2d_sbc.c codec-specific implementation, because they don't need
  to be exposed anymore.
  - struct tA2D_SBC_CIE
  - function A2D_BldSbcInfo()
  - function A2D_ParsSbcInfo()
* Added corresponding unit tests for the new API

Bug: 30958229
Test: A2DP tested manually. Unit tests included in the CL.
Change-Id: Ib242956c303f0ca3c5f70ebc00416a7a45e70228
parent 27b7af10
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@
#ifndef BTA_AV_SBC_H
#define BTA_AV_SBC_H

#include "stack/include/a2d_sbc.h"

/*****************************************************************************
**  constants
*****************************************************************************/
+102 −86
Original line number Diff line number Diff line
@@ -23,9 +23,8 @@
 *
 ******************************************************************************/

#include "string.h"
#include <string.h>
#include "a2d_api.h"
#include "a2d_sbc.h"
#include "bt_target.h"
#include "bta_sys.h"
#include "bta_av_api.h"
@@ -237,6 +236,8 @@ bool bta_av_co_audio_init(tA2D_CODEC_SEP_INDEX codec_sep_index,
                          tAVDT_CFG *p_cfg)
{
    /* reset remote preference through setconfig */
    memset(bta_av_co_cb.codec_cfg_setconfig.info, 0,
           sizeof(bta_av_co_cb.codec_cfg_setconfig.info));
    bta_av_co_cb.codec_cfg_setconfig.id = tA2D_AV_CODEC_NONE;

    return A2D_InitCodecConfig(codec_sep_index, p_cfg);
@@ -817,6 +818,8 @@ void bta_av_co_audio_close(tBTA_AV_HNDL hndl, tA2D_CODEC_TYPE codec_type,
    }

    /* reset remote preference through setconfig */
    memset(bta_av_co_cb.codec_cfg_setconfig.info, 0,
           sizeof(bta_av_co_cb.codec_cfg_setconfig.info));
    bta_av_co_cb.codec_cfg_setconfig.id = tA2D_AV_CODEC_NONE;
}

@@ -1373,75 +1376,113 @@ bool bta_av_co_audio_set_codec(const tA2D_AV_MEDIA_FEEDINGS *p_feeding)
    return bta_av_co_audio_codec_supported();
}

/*******************************************************************************
 **
 ** Function         bta_av_co_audio_get_sbc_config
 **
 ** Description      Retrieves the SBC codec configuration.  If the codec in use
 **                  is not SBC, return the default SBC codec configuration.
 **
 ** Returns          true if codec is SBC, false otherwise
 **
 *******************************************************************************/
bool bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, uint16_t *p_minmtu)
void bta_av_co_audio_encoder_init(tBTIF_MEDIA_INIT_AUDIO *msg)
{
    bool result = false;
    uint8_t index, jndex;
    tBTA_AV_CO_PEER *p_peer;
    tBTA_AV_CO_SINK *p_sink;

    APPL_TRACE_EVENT("%s: bta_av_co_cb.codec_cfg.id : codec 0x%x",
                     __func__, bta_av_co_cb.codec_cfg.id);
    uint16_t min_mtu = 0xFFFF;

    /* Minimum MTU is by default very large */
    *p_minmtu = 0xFFFF;
    APPL_TRACE_DEBUG("%s", __func__);

    /* Protect access to bta_av_co_cb.codec_cfg */
    mutex_global_lock();
    if (bta_av_co_cb.codec_cfg.id == A2D_MEDIA_CT_SBC) {
        if (A2D_ParsSbcInfo(p_sbc_config, bta_av_co_cb.codec_cfg.info, false) == A2D_SUCCESS)
        {
            for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++)
            {
                p_peer = &bta_av_co_cb.peers[index];
                if (p_peer->opened)
                {
                    if (p_peer->mtu < *p_minmtu)
                    {
                        *p_minmtu = p_peer->mtu;

    /* Compute the MTU */
    for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) {
        const tBTA_AV_CO_PEER *p_peer = &bta_av_co_cb.peers[i];
        if (!p_peer->opened)
            continue;
        if (p_peer->mtu < min_mtu)
            min_mtu = p_peer->mtu;
    }
                    for (jndex = 0; jndex < p_peer->num_sup_snks; jndex++)
                    {
                        p_sink = &p_peer->snks[jndex];
                        if (p_sink->codec_type == A2D_MEDIA_CT_SBC)

    const uint8_t *p_codec_info = bta_av_co_cb.codec_cfg.info;
    msg->NumOfSubBands = A2D_GetNumberOfSubbands(p_codec_info);
    msg->NumOfBlocks = A2D_GetNumberOfBlocks(p_codec_info);
    msg->AllocationMethod = A2D_GetAllocationMethodCode(p_codec_info);
    msg->ChannelMode = A2D_GetChannelModeCode(p_codec_info);
    msg->SamplingFreq = A2D_GetSamplingFrequencyCode(p_codec_info);
    msg->MtuSize = min_mtu;

    /* Protect access to bta_av_co_cb.codec_cfg */
    mutex_global_unlock();
}

void bta_av_co_audio_encoder_update(tBTIF_MEDIA_UPDATE_AUDIO *msg)
{
    uint16_t min_mtu = 0xFFFF;

    APPL_TRACE_DEBUG("%s", __func__);

    /* Protect access to bta_av_co_cb.codec_cfg */
    mutex_global_lock();

    const uint8_t *p_codec_info = bta_av_co_cb.codec_cfg.info;
    int min_bitpool = A2D_GetMinBitpool(p_codec_info);
    int max_bitpool = A2D_GetMaxBitpool(p_codec_info);

    if ((min_bitpool < 0) || (max_bitpool < 0)) {
        APPL_TRACE_ERROR("%s: Invalid min/max bitpool: [%d, %d]",
                         __func__, min_bitpool, max_bitpool);
        mutex_global_unlock();
        return;
    }

    for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) {
        const tBTA_AV_CO_PEER *p_peer = &bta_av_co_cb.peers[i];
        if (!p_peer->opened)
            continue;

        if (p_peer->mtu < min_mtu)
            min_mtu = p_peer->mtu;

        for (int j = 0; j < p_peer->num_sup_snks; j++) {
            const tBTA_AV_CO_SINK *p_sink = &p_peer->snks[j];
            if (!A2D_CodecTypeEquals(p_codec_info, p_sink->codec_caps))
                continue;
            /* Update the bitpool boundaries of the current config */
                            p_sbc_config->min_bitpool =
                               BTA_AV_CO_MAX(p_sink->codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
                                             p_sbc_config->min_bitpool);
                            p_sbc_config->max_bitpool =
                               BTA_AV_CO_MIN(p_sink->codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF],
                                             p_sbc_config->max_bitpool);
            int peer_min_bitpool = A2D_GetMinBitpool(p_sink->codec_caps);
            int peer_max_bitpool = A2D_GetMaxBitpool(p_sink->codec_caps);
            if (peer_min_bitpool >= 0)
                min_bitpool = BTA_AV_CO_MAX(min_bitpool, peer_min_bitpool);
            if (peer_max_bitpool >= 0)
                max_bitpool = BTA_AV_CO_MIN(max_bitpool, peer_max_bitpool);
            APPL_TRACE_EVENT("%s: sink bitpool min %d, max %d",
                                             __func__,
                                             p_sbc_config->min_bitpool,
                                             p_sbc_config->max_bitpool);
                             __func__, min_bitpool, max_bitpool);
            break;
        }
    }
                }
            }
            result = true;
        }
    }

    if (!result)
    {
        /* Not SBC, still return the default values */
        *p_sbc_config = *A2D_GetDefaultConfigSbc();
    /*
     * Check if the remote Sink has a preferred bitpool range.
     * Adjust our preferred bitpool with the remote preference if within
     * our capable range.
     */
    if (A2D_IsValidCodec(bta_av_co_cb.codec_cfg_setconfig.info) &&
        A2D_CodecTypeEquals(p_codec_info,
                            bta_av_co_cb.codec_cfg_setconfig.info)) {
        int setconfig_min_bitpool =
            A2D_GetMinBitpool(bta_av_co_cb.codec_cfg_setconfig.info);
        int setconfig_max_bitpool =
            A2D_GetMaxBitpool(bta_av_co_cb.codec_cfg_setconfig.info);
        if (setconfig_min_bitpool >= 0)
            min_bitpool = BTA_AV_CO_MAX(min_bitpool, setconfig_min_bitpool);
        if (setconfig_max_bitpool >= 0)
            max_bitpool = BTA_AV_CO_MIN(max_bitpool, setconfig_max_bitpool);
        APPL_TRACE_EVENT("%s: sink adjusted bitpool min %d, max %d",
                         __func__, min_bitpool, max_bitpool);
    }

    /* Protect access to bta_av_co_cb.codec_cfg */
    mutex_global_unlock();

    return result;
    if (min_bitpool > max_bitpool) {
        APPL_TRACE_ERROR("%s: Irrational min/max bitpool: [%d, %d]",
                         __func__, min_bitpool, max_bitpool);
        return;
    }

    msg->MinMtuSize = min_mtu;
    msg->MinBitPool = min_bitpool;
    msg->MaxBitPool = max_bitpool;
}

/*******************************************************************************
@@ -1536,28 +1577,3 @@ bool bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl)
    APPL_TRACE_ERROR("%s: did not find SBC sink", __func__);
    return false;
}


/*******************************************************************************
 **
 ** Function         bta_av_co_get_remote_bitpool_pref
 **
 ** Description      Check if remote side did a setconfig within the limits
 **                  of our exported bitpool range. If set we will set the
 **                  remote preference.
 **
 ** Returns          true if config set, false otherwize
 **
 *******************************************************************************/

bool bta_av_co_get_remote_bitpool_pref(uint8_t *min, uint8_t *max)
{
    /* check if remote peer did a set config */
    if (bta_av_co_cb.codec_cfg_setconfig.id == tA2D_AV_CODEC_NONE)
        return false;

    *min = bta_av_co_cb.codec_cfg_setconfig.info[BTA_AV_CO_SBC_MIN_BITPOOL_OFF];
    *max = bta_av_co_cb.codec_cfg_setconfig.info[BTA_AV_CO_SBC_MAX_BITPOOL_OFF];

    return true;
}
+0 −1
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@

#include "btif_media.h"
#include "a2d_api.h"
#include "a2d_sbc.h"


/*****************************************************************************
+7 −24
Original line number Diff line number Diff line
@@ -107,17 +107,13 @@ bool bta_av_co_audio_codec_supported(void);
 *******************************************************************************/
bool bta_av_co_audio_set_codec(const tA2D_AV_MEDIA_FEEDINGS *p_feeding);

/*******************************************************************************
 **
 ** Function         bta_av_co_audio_get_sbc_config
 **
 ** Description      Retrieves the SBC codec configuration.  If the codec in use
 **                  is not SBC, return the default SBC codec configuration.
 **
 ** Returns          true if codec is SBC, false otherwise
 **
 *******************************************************************************/
bool bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, uint16_t *p_minmtu);
// Prepares a message to initialize the encoder. The prepared message is
// stored in |msg|.
void bta_av_co_audio_encoder_init(tBTIF_MEDIA_INIT_AUDIO *msg);

// Prepares a message to update the encoder. The prepared message is
// stored in |msg|.
void bta_av_co_audio_encoder_update(tBTIF_MEDIA_UPDATE_AUDIO *msg);

/*******************************************************************************
 **
@@ -153,17 +149,4 @@ void bta_av_co_init(void);
 *******************************************************************************/
bool bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl);

/*******************************************************************************
 **
 ** Function         bta_av_co_get_remote_bitpool_pref
 **
 ** Description      Check if remote side did a setconfig within the limits
 **                  of our exported bitpool range. If set we will set the
 **                  remote preference.
 **
 ** Returns          true if config set, false otherwize
 **
 *******************************************************************************/
bool bta_av_co_get_remote_bitpool_pref(uint8_t *min, uint8_t *max);

#endif
+5 −60
Original line number Diff line number Diff line
@@ -792,80 +792,25 @@ static uint16_t btif_media_task_get_sbc_rate(void)

static void btif_a2dp_encoder_init(void)
{
    uint16_t minmtu;
    tBTIF_MEDIA_INIT_AUDIO msg;
    tA2D_SBC_CIE sbc_config;

    APPL_TRACE_DEBUG("%s", __func__);

    /* Retrieve the current SBC configuration (default if currently not used) */
    bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
    const uint8_t *p_codec_info = bta_av_co_get_codec_info();
    msg.NumOfSubBands = A2D_GetNumberOfSubbands(p_codec_info);
    msg.NumOfBlocks = A2D_GetNumberOfBlocks(p_codec_info);
    msg.AllocationMethod = A2D_GetAllocationMethodCode(p_codec_info);
    msg.ChannelMode = A2D_GetChannelModeCode(p_codec_info);
    msg.SamplingFreq = A2D_GetSamplingFrequencyCode(p_codec_info);
    msg.MtuSize = minmtu;
    bta_av_co_audio_encoder_init(&msg);

    APPL_TRACE_EVENT("%s: msg.ChannelMode 0x%x", __func__, msg.ChannelMode);

    /* Init the media task to encode SBC properly */
    /* Init the media task to encode audio properly */
    btif_media_task_enc_init_req(&msg);
}

static void btif_a2dp_encoder_update(void)
{
    uint16_t minmtu;
    tA2D_SBC_CIE sbc_config;
    tBTIF_MEDIA_UPDATE_AUDIO msg;
    uint8_t pref_min;
    uint8_t pref_max;

    APPL_TRACE_DEBUG("btif_a2dp_encoder_update");

    /* Retrieve the current SBC configuration (default if currently not used) */
    bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);

    APPL_TRACE_DEBUG("btif_a2dp_encoder_update: Common min_bitpool:%d(0x%x) max_bitpool:%d(0x%x)",
            sbc_config.min_bitpool, sbc_config.min_bitpool,
            sbc_config.max_bitpool, sbc_config.max_bitpool);

    if (sbc_config.min_bitpool > sbc_config.max_bitpool)
    {
        APPL_TRACE_ERROR("btif_a2dp_encoder_update: ERROR btif_a2dp_encoder_update min_bitpool > max_bitpool");
    }

    /* check if remote sink has a preferred bitpool range */
    if (bta_av_co_get_remote_bitpool_pref(&pref_min, &pref_max) == true)
    {
        /* adjust our preferred bitpool with the remote preference if within
           our capable range */

        if (pref_min < sbc_config.min_bitpool)
            pref_min = sbc_config.min_bitpool;

        if (pref_max > sbc_config.max_bitpool)
            pref_max = sbc_config.max_bitpool;

        msg.MinBitPool = pref_min;
        msg.MaxBitPool = pref_max;

        if ((pref_min != sbc_config.min_bitpool) || (pref_max != sbc_config.max_bitpool))
        {
            APPL_TRACE_EVENT("## adjusted our bitpool range to peer pref [%d:%d] ##",
                pref_min, pref_max);
        }
    }
    else
    {
        msg.MinBitPool = sbc_config.min_bitpool;
        msg.MaxBitPool = sbc_config.max_bitpool;
    }
    APPL_TRACE_DEBUG("%s", __func__);

    msg.MinMtuSize = minmtu;
    bta_av_co_audio_encoder_update(&msg);

    /* Update the media task to encode SBC properly */
    /* Update the media task to encode audio properly */
    btif_media_task_enc_update_req(&msg);
}

Loading