Send Peer device MTU value in case of AAC codec to MM.
When MM does get_codec_config, we need to send peer MTU as well
bitrate to MM when AAC codec has been selected, which would get
filled in BT Host stack.
CRs-Fixed: 2402346
Change-Id: Ib97a518795706f96f332742b265199e1d13ca37c
diff --git a/bthost_ipc/bthost_ipc.c b/bthost_ipc/bthost_ipc.c
index bec3a56..865956f 100644
--- a/bthost_ipc/bthost_ipc.c
+++ b/bthost_ipc/bthost_ipc.c
@@ -103,6 +103,7 @@
bool resp_received = false;
uint8_t tws_channelmode = 0;
static char a2dp_hal_imp[PROPERTY_VALUE_MAX] = "false";
+static char AAC_frame_ctrl_val[PROPERTY_VALUE_MAX] = "false";
/*****************************************************************************
** Static functions
******************************************************************************/
@@ -112,6 +113,7 @@
audio_aptx_adaptive_encoder_config_t aptx_adaptive_codec;
audio_aptx_tws_encoder_config_t aptx_tws_codec;
audio_aac_encoder_config_t aac_codec;
+audio_aac_encoder_config_v2_t aac_codec_v2;
audio_ldac_encoder_config_t ldac_codec;
audio_celt_encoder_config_t celt_codec;
/*****************************************************************************
@@ -179,7 +181,6 @@
{
char byte,len;
uint8_t *p_cfg = codec_cfg;
- ALOGW("%s",__func__);
ALOGW("%s: codec_type = %x",__func__, codec_cfg[CODEC_OFFSET]);
if (codec_cfg[CODEC_OFFSET] == CODEC_TYPE_PCM)
{
@@ -296,103 +297,228 @@
return ((void *)(&sbc_codec));
} else if (codec_cfg[CODEC_OFFSET] == CODEC_TYPE_AAC)
{
- uint16_t aac_samp_freq = 0;
- uint32_t aac_bit_rate = 0;
- memset(&aac_codec,0,sizeof(audio_aac_encoder_config_t));
- p_cfg++;//skip dev idx
- len = *p_cfg++;
- p_cfg++;//skip media type
- len--;
- p_cfg++;//skip codec type
- len--;
- byte = *p_cfg++;
- len--;
- switch (byte & A2D_AAC_IE_OBJ_TYPE_MSK)
- {
- case A2D_AAC_IE_OBJ_TYPE_MPEG_2_AAC_LC:
- aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LC;
- break;
- case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LC:
- aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LC;
- break;
- case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LTP:
- aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LTP;
- break;
- case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_SCA:
- aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_SCALABLE;
- break;
- default:
- ALOGE("AAC:Unknown encoder mode");
+ bool is_AAC_frame_ctrl_enable = false;
+ property_get("persist.vendor.bt.aac_frm_ctl.enabled", AAC_frame_ctrl_val, "false");
+ if (!strcmp(AAC_frame_ctrl_val, "true"))
+ is_AAC_frame_ctrl_enable = true;
+ ALOGW("%s: AAC frame control enabled: %d", __func__, is_AAC_frame_ctrl_enable);
+ if (is_AAC_frame_ctrl_enable) {
+ uint16_t aac_samp_freq = 0;
+ uint32_t aac_bit_rate = 0;
+ memset(&aac_codec_v2,0,sizeof(audio_aac_encoder_config_v2_t));
+ p_cfg++;//skip dev idx
+ len = *p_cfg++;
+ p_cfg++;//skip media type
+ len--;
+ p_cfg++;//skip codec type
+ len--;
+ byte = *p_cfg++;
+ len--;
+ switch (byte & A2D_AAC_IE_OBJ_TYPE_MSK)
+ {
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_2_AAC_LC:
+ aac_codec_v2.enc_mode = AUDIO_FORMAT_AAC_SUB_LC;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LC:
+ aac_codec_v2.enc_mode = AUDIO_FORMAT_AAC_SUB_LC;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LTP:
+ aac_codec_v2.enc_mode = AUDIO_FORMAT_AAC_SUB_LTP;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_SCA:
+ aac_codec_v2.enc_mode = AUDIO_FORMAT_AAC_SUB_SCALABLE;
+ break;
+ default:
+ ALOGE("AAC:Unknown encoder mode");
+ }
+ //USE 0 (AAC_LC) as hardcoded value till Audio
+ //define constants
+ aac_codec_v2.enc_mode = 0;
+ //USE LOAS(1) or LATM(4) hardcoded values till
+ //Audio define proper constants
+ aac_codec_v2.format_flag = 4;
+ byte = *p_cfg++;
+ len--;
+ aac_samp_freq = byte << 8; //1st byte of sample_freq
+ byte = *p_cfg++;
+ len--;
+ aac_samp_freq |= byte & 0x00F0; //1st nibble of second byte of samp_freq
+
+ switch (aac_samp_freq) {
+ case 0x8000: aac_codec_v2.sampling_rate = 8000; break;
+ case 0x4000: aac_codec_v2.sampling_rate = 11025; break;
+ case 0x2000: aac_codec_v2.sampling_rate = 12000; break;
+ case 0x1000: aac_codec_v2.sampling_rate = 16000; break;
+ case 0x0800: aac_codec_v2.sampling_rate = 22050; break;
+ case 0x0400: aac_codec_v2.sampling_rate = 24000; break;
+ case 0x0200: aac_codec_v2.sampling_rate = 32000; break;
+ case 0x0100: aac_codec_v2.sampling_rate = 44100; break;
+ case 0x0080: aac_codec_v2.sampling_rate = 48000; break;
+ case 0x0040: aac_codec_v2.sampling_rate = 64000; break;
+ case 0x0020: aac_codec_v2.sampling_rate = 88200; break;
+ case 0x0010: aac_codec_v2.sampling_rate = 96000; break;
+ default:
+ ALOGE("Invalid sample_freq: %x", aac_samp_freq);
+ }
+
+ switch (byte & A2D_AAC_IE_CHANNELS_MSK)
+ {
+ case A2D_AAC_IE_CHANNELS_1:
+ aac_codec_v2.channels = 1;
+ break;
+ case A2D_AAC_IE_CHANNELS_2:
+ aac_codec_v2.channels = 2;
+ break;
+ default:
+ ALOGE("AAC:Unknown channel mode");
+ }
+ byte = *p_cfg++; //Move to VBR byte
+ len--;
+ switch (byte & A2D_AAC_IE_VBR_MSK)
+ {
+ case A2D_AAC_IE_VBR:
+ break;
+ default:
+ ALOGE("AAC:VBR not supported");
+ }
+ aac_bit_rate = 0x7F&byte;
+ //Move it 2nd byte of 32 bit word. leaving the VBR bit
+ aac_bit_rate = aac_bit_rate << 16;
+ byte = *p_cfg++; //Move to 2nd byteof bitrate
+ len--;
+
+ //Move it to 3rd byte of 32bit word
+ aac_bit_rate |= 0x0000FF00 & (((uint32_t)byte)<<8);
+ byte = *p_cfg++; //Move to 3rd byte of bitrate
+ len--;
+
+ aac_bit_rate |= 0x000000FF & (((uint32_t)byte));
+ aac_codec_v2.bitrate = aac_bit_rate;
+ ALOGW("%s: Final AAC bitrate: %d",__func__, aac_bit_rate);
+
+ aac_codec_v2.frame_ctl.ctl_type = A2D_AAC_FRAME_PEAK_MTU;
+ aac_codec_v2.frame_ctl.ctl_value = *(uint16_t *)p_cfg;
+ //(p_cfg(+2 is because of mtu filled in stack is of 2bytes)
+ p_cfg = p_cfg + 2;
+
+ aac_codec_v2.bitrate = *(uint32_t *)p_cfg;
+ //p_cfg(+4 is because of bitrate filled in stack is occupying 4 bytes.
+ p_cfg = p_cfg + 4;
+ ALOGW("%s: AAC bitrate overwritten with actual value fetched from stack: %d",
+ __func__, aac_codec_v2.bitrate);
+
+ aac_codec_v2.bits_per_sample = *(uint32_t *)p_cfg;
+ *codec_type = AUDIO_FORMAT_AAC;
+
+ if(sample_freq) *sample_freq = aac_codec_v2.sampling_rate;
+ ALOGW("%s: Copied full codec config bits_per_sample : %d, ctl_type : %d, ctl_value : %d",
+ __func__, aac_codec_v2.bits_per_sample, aac_codec_v2.frame_ctl.ctl_type,
+ aac_codec_v2.frame_ctl.ctl_value );
+ return ((void *)(&aac_codec_v2));
+ } else {
+ uint16_t aac_samp_freq = 0;
+ uint32_t aac_bit_rate = 0;
+ memset(&aac_codec,0,sizeof(audio_aac_encoder_config_t));
+ p_cfg++;//skip dev idx
+ len = *p_cfg++;
+ p_cfg++;//skip media type
+ len--;
+ p_cfg++;//skip codec type
+ len--;
+ byte = *p_cfg++;
+ len--;
+ switch (byte & A2D_AAC_IE_OBJ_TYPE_MSK)
+ {
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_2_AAC_LC:
+ aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LC;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LC:
+ aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LC;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LTP:
+ aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LTP;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_SCA:
+ aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_SCALABLE;
+ break;
+ default:
+ ALOGE("AAC:Unknown encoder mode");
+ }
+ //USE 0 (AAC_LC) as hardcoded value till Audio
+ //define constants
+ aac_codec.enc_mode = 0;
+ //USE LOAS(1) or LATM(4) hardcoded values till
+ //Audio define proper constants
+ aac_codec.format_flag = 4;
+ byte = *p_cfg++;
+ len--;
+ aac_samp_freq = byte << 8; //1st byte of sample_freq
+ byte = *p_cfg++;
+ len--;
+ aac_samp_freq |= byte & 0x00F0; //1st nibble of second byte of samp_freq
+
+ switch (aac_samp_freq) {
+ case 0x8000: aac_codec.sampling_rate = 8000; break;
+ case 0x4000: aac_codec.sampling_rate = 11025; break;
+ case 0x2000: aac_codec.sampling_rate = 12000; break;
+ case 0x1000: aac_codec.sampling_rate = 16000; break;
+ case 0x0800: aac_codec.sampling_rate = 22050; break;
+ case 0x0400: aac_codec.sampling_rate = 24000; break;
+ case 0x0200: aac_codec.sampling_rate = 32000; break;
+ case 0x0100: aac_codec.sampling_rate = 44100; break;
+ case 0x0080: aac_codec.sampling_rate = 48000; break;
+ case 0x0040: aac_codec.sampling_rate = 64000; break;
+ case 0x0020: aac_codec.sampling_rate = 88200; break;
+ case 0x0010: aac_codec.sampling_rate = 96000; break;
+ default:
+ ALOGE("Invalid sample_freq: %x", aac_samp_freq);
+ }
+
+ switch (byte & A2D_AAC_IE_CHANNELS_MSK)
+ {
+ case A2D_AAC_IE_CHANNELS_1:
+ aac_codec.channels = 1;
+ break;
+ case A2D_AAC_IE_CHANNELS_2:
+ aac_codec.channels = 2;
+ break;
+ default:
+ ALOGE("AAC:Unknown channel mode");
+ }
+ byte = *p_cfg++; //Move to VBR byte
+ len--;
+ switch (byte & A2D_AAC_IE_VBR_MSK)
+ {
+ case A2D_AAC_IE_VBR:
+ break;
+ default:
+ ALOGE("AAC:VBR not supported");
+ }
+ aac_bit_rate = 0x7F&byte;
+ //Move it 2nd byte of 32 bit word. leaving the VBR bit
+ aac_bit_rate = aac_bit_rate << 16;
+ byte = *p_cfg++; //Move to 2nd byteof bitrate
+ len--;
+
+ //Move it to 3rd byte of 32bit word
+ aac_bit_rate |= 0x0000FF00 & (((uint32_t)byte)<<8);
+ byte = *p_cfg++; //Move to 3rd byte of bitrate
+ len--;
+
+ aac_bit_rate |= 0x000000FF & (((uint32_t)byte));
+ aac_codec.bitrate = aac_bit_rate;
+ ALOGW("%s: Final AAC bitrate: %d",__func__, aac_bit_rate);
+ //+2 because 2 bytes occupying by MTU
+ //+4 because 4 bytes occupying by bitrate
+ p_cfg = p_cfg + 2 + 4;
+ aac_codec.bits_per_sample = *(uint32_t *)p_cfg;
+ *codec_type = AUDIO_FORMAT_AAC;
+
+ if(sample_freq) *sample_freq = aac_codec.sampling_rate;
+ ALOGW("%s: AAC: Done copying full codec config bits_per_sample : %d",
+ __func__, aac_codec.bits_per_sample );
+ return ((void *)(&aac_codec));
}
- //USE 0 (AAC_LC) as hardcoded value till Audio
- //define constants
- aac_codec.enc_mode = 0;
- //USE LOAS(1) or LATM(4) hardcoded values till
- //Audio define proper constants
- aac_codec.format_flag = 4;
- byte = *p_cfg++;
- len--;
- aac_samp_freq = byte << 8; //1st byte of sample_freq
- byte = *p_cfg++;
- len--;
- aac_samp_freq |= byte & 0x00F0; //1st nibble of second byte of samp_freq
-
- switch (aac_samp_freq) {
- case 0x8000: aac_codec.sampling_rate = 8000; break;
- case 0x4000: aac_codec.sampling_rate = 11025; break;
- case 0x2000: aac_codec.sampling_rate = 12000; break;
- case 0x1000: aac_codec.sampling_rate = 16000; break;
- case 0x0800: aac_codec.sampling_rate = 22050; break;
- case 0x0400: aac_codec.sampling_rate = 24000; break;
- case 0x0200: aac_codec.sampling_rate = 32000; break;
- case 0x0100: aac_codec.sampling_rate = 44100; break;
- case 0x0080: aac_codec.sampling_rate = 48000; break;
- case 0x0040: aac_codec.sampling_rate = 64000; break;
- case 0x0020: aac_codec.sampling_rate = 88200; break;
- case 0x0010: aac_codec.sampling_rate = 96000; break;
- default:
- ALOGE("Invalid sample_freq: %x", aac_samp_freq);
- }
-
- switch (byte & A2D_AAC_IE_CHANNELS_MSK)
- {
- case A2D_AAC_IE_CHANNELS_1:
- aac_codec.channels = 1;
- break;
- case A2D_AAC_IE_CHANNELS_2:
- aac_codec.channels = 2;
- break;
- default:
- ALOGE("AAC:Unknown channel mode");
- }
- byte = *p_cfg++; //Move to VBR byte
- len--;
- switch (byte & A2D_AAC_IE_VBR_MSK)
- {
- case A2D_AAC_IE_VBR:
- break;
- default:
- ALOGE("AAC:VBR not supported");
- }
- aac_bit_rate = 0x7F&byte;
- //Move it 2nd byte of 32 bit word. leaving the VBR bit
- aac_bit_rate = aac_bit_rate << 16;
- byte = *p_cfg++; //Move to 2nd byteof bitrate
- len--;
-
- //Move it to 3rd byte of 32bit word
- aac_bit_rate |= 0x0000FF00 & (((uint32_t)byte)<<8);
- byte = *p_cfg++; //Move to 3rd byte of bitrate
- len--;
-
- aac_bit_rate |= 0x000000FF & (((uint32_t)byte));
- aac_codec.bitrate = aac_bit_rate;
- aac_codec.bits_per_sample = *(uint32_t *)p_cfg;
- *codec_type = AUDIO_FORMAT_AAC;
-
- if(sample_freq) *sample_freq = aac_codec.sampling_rate;
- ALOGW("AAC: Done copying full codec config bits_per_sample : %d", aac_codec.bits_per_sample);
- return ((void *)(&aac_codec));
}
else if (codec_cfg[CODEC_OFFSET] == NON_A2DP_CODEC_TYPE)
{
diff --git a/bthost_ipc/bthost_ipc.h b/bthost_ipc/bthost_ipc.h
index 50e7abe..b72f0a3 100644
--- a/bthost_ipc/bthost_ipc.h
+++ b/bthost_ipc/bthost_ipc.h
@@ -244,6 +244,9 @@
#define A2D_AAC_IE_VBR_MSK 0x80
#define A2D_AAC_IE_VBR 0x80 /* supported */
+#define A2D_AAC_FRAME_PEAK_MTU 0 /* Configure peak MTU */
+#define A2D_AAC_FRAME_PEAK_BITRATE 1 /* Configure peak bitrate */
+
#define A2DP_DEFAULT_SINK_LATENCY 0
@@ -355,6 +358,17 @@
uint32_t bits_per_sample;
} audio_ldac_encoder_config_t;
+/* Structure to control frame size of AAC encoded frames. */
+struct aac_frame_size_control_t {
+ /* Type of frame size control: MTU_SIZE / PEAK_BIT_RATE */
+ uint32_t ctl_type;
+ /* Control value
+ * MTU_SIZE: MTU size in bytes
+ * PEAK_BIT_RATE: Peak bitrate in bits per second.
+ */
+ uint32_t ctl_value;
+};
+
/* Information about BT AAC encoder configuration
* This data is used between audio HAL module and
* BT IPC library to configure DSP encoder
@@ -368,6 +382,20 @@
uint32_t bits_per_sample;
} audio_aac_encoder_config_t;
+/* Information about BT AAC encoder configuration
+ * This data is used between audio HAL module and
+ * BT IPC library to configure DSP encoder with frame control
+ */
+typedef struct {
+ uint32_t enc_mode; /* LC, SBR, PS */
+ uint16_t format_flag; /* RAW, ADTS */
+ uint16_t channels; /* 1-Mono, 2-Stereo */
+ uint32_t sampling_rate;
+ uint32_t bitrate;
+ uint32_t bits_per_sample;
+ struct aac_frame_size_control_t frame_ctl;
+} audio_aac_encoder_config_v2_t;
+
typedef struct {
uint32_t sampling_rate; /* 32000 - 48000, 48000 */
uint16_t channels; /* 1-Mono, 2-Stereo, 2*/