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

Commit 9033c53e authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Audio-hal: Variable bit rate mode support for aac."

parents 3f2e3dc4 abb536a3
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -405,6 +405,10 @@ persist.vendor.bt.aac_frm_ctl.enabled=true
PRODUCT_PROPERTY_OVERRIDES += \
persist.vendor.bt.aac_frm_ctl.enabled=true

#enable VBR frame ctl
PRODUCT_PROPERTY_OVERRIDES += \
persist.vendor.bt.aac_vbr_frm_ctl.enabled=true

#add dynamic feature flags here
ifeq ($(GENERIC_ODM_IMAGE),true)
# Generic ODM varient related
+93 −3
Original line number Diff line number Diff line
@@ -250,6 +250,7 @@ typedef enum {
typedef enum {
    MTU_SIZE,
    PEAK_BIT_RATE,
    BIT_RATE_MODE,
} frame_control_type_t;

// --- external function dependency ---
@@ -390,6 +391,7 @@ struct aac_frame_size_control_t {
    /* Control value
     * MTU_SIZE: MTU size in bytes
     * PEAK_BIT_RATE: Peak bitrate in bits per second.
     * BIT_RATE_MODE: Variable bitrate
     */
    uint32_t ctl_value;
};
@@ -451,6 +453,12 @@ struct aac_enc_cfg_v2_t {
    struct aac_frame_size_control_t frame_ctl;
} __attribute__ ((packed));

struct aac_enc_cfg_v3_t {
    struct aac_enc_cfg_t aac_enc_cfg;
    struct aac_frame_size_control_t frame_ctl;
    struct aac_frame_size_control_t aac_key_value_ctl;
} __attribute__ ((packed));

typedef struct audio_aac_decoder_config_t audio_aac_decoder_config_t;
struct audio_aac_decoder_config_t {
    uint16_t      aac_fmt_flag; /* LATM*/
@@ -710,6 +718,13 @@ typedef struct {
    struct aac_frame_size_control_t frame_ctl;
} audio_aac_encoder_config_v2;

typedef struct {
    audio_aac_encoder_config audio_aac_enc_cfg;
    struct aac_frame_size_control_t frame_ctl;
    uint8_t size_control_struct;
    struct aac_frame_size_control_t* frame_ptr_ctl;
} audio_aac_encoder_config_v3;

/* Information about BT CELT encoder configuration
 * This data is used between audio HAL module and
 * BT IPC library to configure DSP encoder
@@ -2173,6 +2188,76 @@ fail:
    return is_configured;
}

bool configure_aac_enc_format_v3(audio_aac_encoder_config_v3 *aac_bt_cfg)
{
    struct mixer_ctl *ctl_enc_data = NULL;
    struct aac_enc_cfg_v3_t aac_dsp_cfg;
    struct aac_frame_size_control_t* frame_vbr_ctl = NULL;
    bool is_configured = false;
    int ret = 0;

    if (aac_bt_cfg == NULL)
        return false;

    ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
    if (!ctl_enc_data) {
        ALOGE(" ERROR  a2dp encoder CONFIG data mixer control not identifed");
        is_configured = false;
        goto fail;
    }
    memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_v3_t));
    aac_dsp_cfg.aac_enc_cfg.enc_format = MEDIA_FMT_AAC;
    aac_dsp_cfg.aac_enc_cfg.bit_rate = aac_bt_cfg->audio_aac_enc_cfg.bitrate;
    aac_dsp_cfg.aac_enc_cfg.sample_rate = aac_bt_cfg->audio_aac_enc_cfg.sampling_rate;
    switch (aac_bt_cfg->audio_aac_enc_cfg.enc_mode) {
        case 0:
            aac_dsp_cfg.aac_enc_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
            break;
        case 2:
            aac_dsp_cfg.aac_enc_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
            break;
        case 1:
        default:
            aac_dsp_cfg.aac_enc_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
            break;
    }
    aac_dsp_cfg.aac_enc_cfg.aac_fmt_flag = aac_bt_cfg->audio_aac_enc_cfg.format_flag;
    aac_dsp_cfg.aac_enc_cfg.channel_cfg = aac_bt_cfg->audio_aac_enc_cfg.channels;
    aac_dsp_cfg.frame_ctl.ctl_type = aac_bt_cfg->frame_ctl.ctl_type;
    aac_dsp_cfg.frame_ctl.ctl_value = aac_bt_cfg->frame_ctl.ctl_value;
    frame_vbr_ctl =  aac_bt_cfg->frame_ptr_ctl;

    if (frame_vbr_ctl != NULL) {
        aac_dsp_cfg.aac_key_value_ctl.ctl_type = frame_vbr_ctl->ctl_type;
        aac_dsp_cfg.aac_key_value_ctl.ctl_value = frame_vbr_ctl->ctl_value;
    } else {
        ALOGE("%s: VBR cannot be enabled, fall back to default",__func__);
        aac_dsp_cfg.aac_key_value_ctl.ctl_type = 0;
        aac_dsp_cfg.aac_key_value_ctl.ctl_value = 0;
    }

    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
                              sizeof(struct aac_enc_cfg_v3_t));
    if (ret != 0) {
        ALOGE("%s: Failed to set AAC encoder config", __func__);
        is_configured = false;
        goto fail;
    }
    ret = a2dp_set_bit_format(aac_bt_cfg->audio_aac_enc_cfg.bits_per_sample);
    if (ret != 0) {
        is_configured = false;
        goto fail;
    }
    is_configured = true;
    a2dp.bt_encoder_format = CODEC_TYPE_AAC;
    a2dp.enc_sampling_rate = aac_bt_cfg->audio_aac_enc_cfg.sampling_rate;
    a2dp.enc_channels = aac_bt_cfg->audio_aac_enc_cfg.channels;
    ALOGV("%s: Successfully updated AAC enc format with sampling rate: %d channels:%d",
           __func__, aac_dsp_cfg.aac_enc_cfg.sample_rate, aac_dsp_cfg.aac_enc_cfg.channel_cfg);
fail:
    return is_configured;
}

bool configure_celt_enc_format(audio_celt_encoder_config *celt_bt_cfg)
{
    struct mixer_ctl *ctl_enc_data = NULL;
@@ -2361,8 +2446,13 @@ bool configure_a2dp_encoder_format()
#endif
        case CODEC_TYPE_AAC:
            ALOGD(" Received AAC encoder supported BT device");
            bool is_aac_vbr_enabled =
                    property_get_bool("persist.vendor.bt.aac_vbr_frm_ctl.enabled", false);
            bool is_aac_frame_ctl_enabled =
                    property_get_bool("persist.vendor.bt.aac_frm_ctl.enabled", false);
            if (is_aac_vbr_enabled)
                is_configured = configure_aac_enc_format_v3((audio_aac_encoder_config_v3 *) codec_info);
            else
                is_configured = is_aac_frame_ctl_enabled ?
                                configure_aac_enc_format_v2((audio_aac_encoder_config_v2 *) codec_info) :
                                configure_aac_enc_format((audio_aac_encoder_config *) codec_info);