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

Commit 0515e043 authored by yidongh's avatar yidongh Committed by Shiv Maliyappanahalli
Browse files

hal: Add support for acquiring inital sink latency

Split a2dp get initial sink latency from BT host ipc.

Change-Id: Ia97f4379f6bd8ae925bc79f7e458383eaabc2bd2
parent d1f56eb8
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -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);
@@ -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,
@@ -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;
@@ -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");
        }
    }

@@ -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;
+8 −2
Original line number Diff line number Diff line
@@ -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);
@@ -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;