Loading hal/audio_extn/a2dp.c +25 −4 Original line number Diff line number Diff line Loading @@ -74,6 +74,14 @@ #define MIXER_ENC_FMT_APTX "APTX" #define MIXER_ENC_FMT_APTXHD "APTXHD" #define MIXER_ENC_FMT_NONE "NONE" #define ENCODER_LATENCY_SBC 10 #define ENCODER_LATENCY_APTX 40 #define ENCODER_LATENCY_APTX_HD 20 #define ENCODER_LATENCY_AAC 70 #define DEFAULT_SINK_LATENCY_SBC 140 #define DEFAULT_SINK_LATENCY_APTX 160 #define DEFAULT_SINK_LATENCY_APTX_HD 180 #define DEFAULT_SINK_LATENCY_AAC 180 typedef int (*audio_stream_open_t)(void); typedef int (*audio_stream_close_t)(void); Loading @@ -85,6 +93,7 @@ typedef void (*clear_a2dpsuspend_flag_t)(void); typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev, audio_format_t *codec_type); typedef int (*audio_check_a2dp_ready_t)(void); typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void); enum A2DP_STATE { A2DP_STATE_CONNECTED, Loading @@ -109,6 +118,7 @@ struct a2dp_data { clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag; audio_get_codec_config_t audio_get_codec_config; audio_check_a2dp_ready_t audio_check_a2dp_ready; audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency; enum A2DP_STATE bt_state; audio_format_t bt_encoder_format; uint32_t enc_sampling_rate; Loading Loading @@ -293,6 +303,8 @@ static void open_a2dp_output() dlsym(a2dp.bt_lib_handle, "audio_stream_close"); a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t) dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready"); a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t) dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency"); } } Loading Loading @@ -901,18 +913,27 @@ uint32_t audio_extn_a2dp_get_encoder_latency() } } uint32_t slatency = 0; if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) { slatency = a2dp.audio_get_a2dp_sink_latency(); } switch(a2dp.bt_encoder_format) { case AUDIO_FORMAT_SBC: latency = (avsync_runtime_prop > 0) ? sbc_offset : 150; latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC; latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency; break; case AUDIO_FORMAT_APTX: latency = (avsync_runtime_prop > 0) ? aptx_offset : 200; latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX; latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency; break; case AUDIO_FORMAT_APTX_HD: latency = (avsync_runtime_prop > 0) ? aptxhd_offset : 200; latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD; latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency; break; case AUDIO_FORMAT_AAC: latency = (avsync_runtime_prop > 0) ? aac_offset : 250; latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC; latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency; break; default: latency = 200; Loading hal/audio_hw.c +8 −2 Original line number Diff line number Diff line Loading @@ -3269,8 +3269,7 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream) (out->config.rate); } if ((AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) && !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) latency += audio_extn_a2dp_get_encoder_latency(); ALOGV("%s: Latency %d", __func__, latency); Loading Loading @@ -3708,6 +3707,13 @@ static int out_get_presentation_position(const struct audio_stream_out *stream, if (is_offload_usecase(out->usecase) && out->compr != NULL && out->non_blocking) { ret = compress_get_tstamp(out->compr, &dsp_frames, &out->sample_rate); // Adjustment accounts for A2dp encoder latency with offload usecases // Note: Encoder latency is returned in ms. if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) { unsigned long offset = (audio_extn_a2dp_get_encoder_latency() * out->sample_rate / 1000); dsp_frames = (dsp_frames > offset) ? (dsp_frames - offset) : 0; } ALOGVV("%s rendered frames %ld sample_rate %d", __func__, dsp_frames, out->sample_rate); *frames = dsp_frames; Loading Loading
hal/audio_extn/a2dp.c +25 −4 Original line number Diff line number Diff line Loading @@ -74,6 +74,14 @@ #define MIXER_ENC_FMT_APTX "APTX" #define MIXER_ENC_FMT_APTXHD "APTXHD" #define MIXER_ENC_FMT_NONE "NONE" #define ENCODER_LATENCY_SBC 10 #define ENCODER_LATENCY_APTX 40 #define ENCODER_LATENCY_APTX_HD 20 #define ENCODER_LATENCY_AAC 70 #define DEFAULT_SINK_LATENCY_SBC 140 #define DEFAULT_SINK_LATENCY_APTX 160 #define DEFAULT_SINK_LATENCY_APTX_HD 180 #define DEFAULT_SINK_LATENCY_AAC 180 typedef int (*audio_stream_open_t)(void); typedef int (*audio_stream_close_t)(void); Loading @@ -85,6 +93,7 @@ typedef void (*clear_a2dpsuspend_flag_t)(void); typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev, audio_format_t *codec_type); typedef int (*audio_check_a2dp_ready_t)(void); typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void); enum A2DP_STATE { A2DP_STATE_CONNECTED, Loading @@ -109,6 +118,7 @@ struct a2dp_data { clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag; audio_get_codec_config_t audio_get_codec_config; audio_check_a2dp_ready_t audio_check_a2dp_ready; audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency; enum A2DP_STATE bt_state; audio_format_t bt_encoder_format; uint32_t enc_sampling_rate; Loading Loading @@ -293,6 +303,8 @@ static void open_a2dp_output() dlsym(a2dp.bt_lib_handle, "audio_stream_close"); a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t) dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready"); a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t) dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency"); } } Loading Loading @@ -901,18 +913,27 @@ uint32_t audio_extn_a2dp_get_encoder_latency() } } uint32_t slatency = 0; if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) { slatency = a2dp.audio_get_a2dp_sink_latency(); } switch(a2dp.bt_encoder_format) { case AUDIO_FORMAT_SBC: latency = (avsync_runtime_prop > 0) ? sbc_offset : 150; latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC; latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency; break; case AUDIO_FORMAT_APTX: latency = (avsync_runtime_prop > 0) ? aptx_offset : 200; latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX; latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency; break; case AUDIO_FORMAT_APTX_HD: latency = (avsync_runtime_prop > 0) ? aptxhd_offset : 200; latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD; latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency; break; case AUDIO_FORMAT_AAC: latency = (avsync_runtime_prop > 0) ? aac_offset : 250; latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC; latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency; break; default: latency = 200; Loading
hal/audio_hw.c +8 −2 Original line number Diff line number Diff line Loading @@ -3269,8 +3269,7 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream) (out->config.rate); } if ((AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) && !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) latency += audio_extn_a2dp_get_encoder_latency(); ALOGV("%s: Latency %d", __func__, latency); Loading Loading @@ -3708,6 +3707,13 @@ static int out_get_presentation_position(const struct audio_stream_out *stream, if (is_offload_usecase(out->usecase) && out->compr != NULL && out->non_blocking) { ret = compress_get_tstamp(out->compr, &dsp_frames, &out->sample_rate); // Adjustment accounts for A2dp encoder latency with offload usecases // Note: Encoder latency is returned in ms. if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) { unsigned long offset = (audio_extn_a2dp_get_encoder_latency() * out->sample_rate / 1000); dsp_frames = (dsp_frames > offset) ? (dsp_frames - offset) : 0; } ALOGVV("%s rendered frames %ld sample_rate %d", __func__, dsp_frames, out->sample_rate); *frames = dsp_frames; Loading