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

Commit 9ba8a149 authored by George Gao's avatar George Gao Committed by Gerrit - the friendly Code Review server
Browse files

audio-hal: Use audio stream to get delay latency

An incremental change on top of Change-Id: Icb9babf7e6a63c1f3d1af73c42ef21fb8b7d211b
This resolved the perf issue of audio playback.

Change-Id: I7f50813147c4568d9e12dd16c486adc3fc4abe90
parent c168d610
Loading
Loading
Loading
Loading
+4 −12
Original line number Diff line number Diff line
@@ -4418,10 +4418,8 @@ static uint64_t get_actual_pcm_frames_rendered(struct stream_out *out, struct ti
    /* This adjustment accounts for buffering after app processor.
     * It is based on estimated DSP latency per use case, rather than exact.
     */
    pthread_mutex_lock(&adev->lock);
    dsp_frames = platform_render_latency(out->dev, out->usecase) *
    dsp_frames = platform_render_latency(out) *
        out->sample_rate / 1000000LL;
    pthread_mutex_unlock(&adev->lock);

    pthread_mutex_lock(&out->position_query_lock);
    written_frames = out->written /
@@ -5386,9 +5384,7 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream)
                         1000) / (out->config.rate);
        else
            period_ms = 0;
        pthread_mutex_lock(&adev->lock);
        latency = period_ms + platform_render_latency(out->dev, out->usecase)/1000;
        pthread_mutex_unlock(&adev->lock);
        latency = period_ms + platform_render_latency(out) / 1000;
    } else {
        latency = (out->config.period_count * out->config.period_size * 1000) /
           (out->config.rate);
@@ -6324,10 +6320,8 @@ static int out_get_presentation_position(const struct audio_stream_out *stream,

                // This adjustment accounts for buffering after app processor.
                // It is based on estimated DSP latency per use case, rather than exact.
                pthread_mutex_lock(&adev->lock);
                frames_temp = platform_render_latency(out->dev, out->usecase) *
                frames_temp = platform_render_latency(out) *
                              out->sample_rate / 1000000LL;
                pthread_mutex_unlock(&adev->lock);
                if (signed_frames >= frames_temp)
                    signed_frames -= frames_temp;

@@ -7225,10 +7219,8 @@ static int in_get_capture_position(const struct audio_stream_in *stream,
        unsigned int avail;
        if (pcm_get_htimestamp(in->pcm, &avail, &timestamp) == 0) {
            *frames = in->frames_read + avail;
            pthread_mutex_lock(&adev->lock);
            *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec
                    - platform_capture_latency(in->dev, in->usecase) * 1000LL;
            pthread_mutex_unlock(&adev->lock);
                    - platform_capture_latency(in) * 1000LL;
            ret = 0;
        }
    }
+5 −3
Original line number Diff line number Diff line
@@ -5821,12 +5821,14 @@ int64_t platform_capture_latency(struct audio_device *adev __unused,
}

/* Delay in Us, only to be used for PCM formats */
int64_t platform_render_latency(struct audio_device *adev __unused,
                                audio_usecase_t usecase)
int64_t platform_render_latency(struct stream_out *out)
{
    int64_t delay = 0LL;

    switch (usecase) {
    if (!out)
        return delay;

    switch (out->usecase) {
        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
            delay = DEEP_BUFFER_PLATFORM_DELAY;
            break;
+10 −45
Original line number Diff line number Diff line
@@ -1611,8 +1611,6 @@ static int msm_be_id_array_len =
    sizeof(msm_device_to_be_id) / sizeof(msm_device_to_be_id[0]);
#endif
static int snd_device_delay_ms[SND_DEVICE_MAX] = {0};
#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
#define PCM_OFFLOAD_PLATFORM_DELAY (30*1000LL)
#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
@@ -2259,7 +2257,6 @@ static void set_platform_defaults(struct platform_data * my_data)
        hw_interface_table[dev] = NULL;
        operator_specific_device_table[dev] = NULL;
        external_specific_device_table[dev] = NULL;
        snd_device_delay_ms[dev] = 0;
        /* Init island cfg and power mode */
        my_data->island_cfg[dev].mixer_ctl = NULL;
        my_data->power_mode_cfg[dev].mixer_ctl = NULL;
@@ -8874,26 +8871,6 @@ done:
    return NULL;
}
void platform_set_snd_device_delay(snd_device_t snd_device, int delay_ms)
{
    if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
        ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
        return;
    }
    snd_device_delay_ms[snd_device] = delay_ms;
}
/* return delay in Us */
int64_t platform_get_snd_device_delay(snd_device_t snd_device)
{
    if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
        ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
        return 0;
    }
    return 1000LL * (int64_t)snd_device_delay_ms[snd_device];
}
void platform_set_audio_source_delay(audio_source_t audio_source, int delay_ms)
{
    if ((audio_source < AUDIO_SOURCE_DEFAULT) ||
@@ -8917,14 +8894,14 @@ int64_t platform_get_audio_source_delay(audio_source_t audio_source)
    return 1000LL * audio_source_delay_ms[audio_source];
}
/* Delay in Us */
/* Delay in Us, only to be used for PCM formats */
int64_t platform_render_latency(struct audio_device *adev, audio_usecase_t usecase)
int64_t platform_render_latency(struct stream_out *out)
{
    int64_t delay = 0LL;
    struct audio_usecase *uc_info;
    switch (usecase) {
    if (!out)
        return delay;
    switch (out->usecase) {
        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
        case USECASE_AUDIO_PLAYBACK_MEDIA:
        case USECASE_AUDIO_PLAYBACK_NAV_GUIDANCE:
@@ -8952,32 +8929,20 @@ int64_t platform_render_latency(struct audio_device *adev, audio_usecase_t useca
            break;
    }
    uc_info = get_usecase_from_list(adev, usecase);
    if (uc_info != NULL) {
        if (uc_info->type == PCM_PLAYBACK)
            delay += platform_get_snd_device_delay(uc_info->out_snd_device);
        else
            ALOGE("%s: Invalid uc_info->type %d", __func__, uc_info->type);
    }
    /* out->device could be used to add delay time if it's necessary */
    return delay;
}
int64_t platform_capture_latency(struct audio_device *adev, audio_usecase_t usecase)
int64_t platform_capture_latency(struct stream_in *in)
{
    int64_t delay = 0LL;
    struct audio_usecase *uc_info;
    uc_info = get_usecase_from_list(adev, usecase);
    if (!in)
        return delay;
    if (uc_info != NULL) {
        if (uc_info->type == PCM_CAPTURE)
            delay += platform_get_snd_device_delay(uc_info->in_snd_device);
        else
            ALOGE("%s: Invalid uc_info->type %d", __func__, uc_info->type);
    }
    delay = platform_get_audio_source_delay(in->source);
    /* in->device could be used to add delay time if it's necessary */
    return delay;
}
+2 −3
Original line number Diff line number Diff line
@@ -236,8 +236,8 @@ int platform_stop_incall_music_usecase(void *platform);
int platform_update_lch(void *platform, struct voice_session *session,
                        enum voice_lch_mode lch_mode);
/* returns the latency for a usecase in Us */
int64_t platform_render_latency(struct audio_device* adev, audio_usecase_t usecase);
int64_t platform_capture_latency(struct audio_device* adev, audio_usecase_t usecase);
int64_t platform_render_latency(struct stream_out *out);
int64_t platform_capture_latency(struct stream_in *in);
int platform_update_usecase_from_source(int source, audio_usecase_t usecase);

bool platform_listen_device_needs_event(snd_device_t snd_device);
@@ -419,7 +419,6 @@ int platform_set_hdmi_channels_v2(void *platform, int channel_count,
                                  int controller, int stream);
int platform_get_display_port_ctl_index(int controller, int stream);
bool platform_is_call_proxy_snd_device(snd_device_t snd_device);
void platform_set_snd_device_delay(snd_device_t snd_device, int delay_ms);
void platform_set_audio_source_delay(audio_source_t audio_source, int delay_ms);

int platform_get_audio_source_index(const char *audio_source_name);
+1 −33
Original line number Diff line number Diff line
@@ -80,7 +80,6 @@ typedef enum {
    CUSTOM_MTMX_IN_PARAMS,
    CUSTOM_MTMX_PARAM_IN_CH_INFO,
    MMSECNS,
    SND_DEV_DELAY,
    AUDIO_SOURCE_DELAY,
} section_t;

@@ -118,7 +117,6 @@ static void process_external_dev(const XML_Char **attr);
static void process_custom_mtmx_in_params(const XML_Char **attr);
static void process_custom_mtmx_param_in_ch_info(const XML_Char **attr);
static void process_fluence_mmsecns(const XML_Char **attr);
static void process_snd_device_delay(const XML_Char **attr);
static void process_audio_source_delay(const XML_Char **attr);

static section_process_fn section_table[] = {
@@ -144,7 +142,6 @@ static section_process_fn section_table[] = {
    [CUSTOM_MTMX_IN_PARAMS] = process_custom_mtmx_in_params,
    [CUSTOM_MTMX_PARAM_IN_CH_INFO] = process_custom_mtmx_param_in_ch_info,
    [MMSECNS] = process_fluence_mmsecns,
    [SND_DEV_DELAY] = process_snd_device_delay,
    [AUDIO_SOURCE_DELAY] = process_audio_source_delay,
};

@@ -719,33 +716,6 @@ done:
    return;
}

static void process_snd_device_delay(const XML_Char **attr)
{
    snd_device_t snd_device = SND_DEVICE_NONE;

    if (strcmp(attr[0], "name") != 0) {
        ALOGE("%s: 'name' not found", __func__);
        goto done;
    }

    snd_device = platform_get_snd_device_index((char *)attr[1]);
    if (snd_device < 0) {
        ALOGE("%s: Device %s in %s not found, no ACDB ID set!",
              __func__, (char *)attr[3], get_platform_xml_path());
        goto done;
    }

    if (strcmp(attr[2], "delay") != 0) {
        ALOGE("%s: 'delay' not found", __func__);
        goto done;
    }

    platform_set_snd_device_delay(snd_device, atoi((char *)attr[3]));

done:
    return;
}

static void process_audio_source_delay(const XML_Char **attr)
{
    audio_source_t audio_source = -1;
@@ -754,6 +724,7 @@ static void process_audio_source_delay(const XML_Char **attr)
        ALOGE("%s: 'name' not found", __func__);
        goto done;
    }

    audio_source = platform_get_audio_source_index((const char *)attr[1]);

    if (audio_source < 0) {
@@ -1515,9 +1486,6 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name,
                return;
            }
            section = CUSTOM_MTMX_PARAM_IN_CH_INFO;
        } else if (strcmp(tag_name, "snd_device_delay") == 0) {
            section = SND_DEV_DELAY;
        } else if (strcmp(tag_name, "device_delay") == 0) {
        } else if (strcmp(tag_name, "audio_input_source_delay") == 0) {
            section = AUDIO_SOURCE_DELAY;
        } else if (strcmp(tag_name, "audio_source_delay") == 0) {