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

Commit 4813da14 authored by Weiyin Jiang's avatar Weiyin Jiang
Browse files

hal: refine frames rendered calculation for pcm offload

For PCM format, hal input format and alsa format might differ.
Refine frames rendered calculation.

Change-Id: I3ab266648541e6040e13ee4249736000c42382a0
CRs-Fixed: 2694810
parent cd57e18e
Loading
Loading
Loading
Loading
+17 −14
Original line number Diff line number Diff line
@@ -4305,28 +4305,34 @@ size_t get_output_period_size(uint32_t sample_rate,
static uint64_t get_actual_pcm_frames_rendered(struct stream_out *out, struct timespec *timestamp)
{
    uint64_t actual_frames_rendered = 0;
    size_t kernel_buffer_size = out->compr_config.fragment_size * out->compr_config.fragments;
    uint64_t written_frames = 0;
    uint64_t kernel_frames = 0;
    uint64_t dsp_frames = 0;
    uint64_t signed_frames = 0;
    size_t kernel_buffer_size = 0;

    /* 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);
    int64_t platform_latency =  platform_render_latency(out->dev, out->usecase) *
    dsp_frames = platform_render_latency(out->dev, out->usecase) *
        out->sample_rate / 1000000LL;
    pthread_mutex_unlock(&adev->lock);

    pthread_mutex_lock(&out->position_query_lock);
    written_frames = out->written /
        (audio_bytes_per_sample(out->hal_ip_format) * popcount(out->channel_mask));

    /* not querying actual state of buffering in kernel as it would involve an ioctl call
     * which then needs protection, this causes delay in TS query for pcm_offload usecase
     * hence only estimate.
     */
    uint64_t signed_frames = 0;
    if (out->written >= kernel_buffer_size)
        signed_frames = out->written - kernel_buffer_size;
    kernel_buffer_size = out->compr_config.fragment_size * out->compr_config.fragments;
    kernel_frames = kernel_buffer_size /
        (audio_bytes_per_sample(out->hal_op_format) * popcount(out->channel_mask));

    signed_frames = signed_frames / (audio_bytes_per_sample(out->format) * popcount(out->channel_mask));
    if (signed_frames >= platform_latency)
        signed_frames = signed_frames - platform_latency;
    if (written_frames >= (kernel_frames + dsp_frames))
        signed_frames = written_frames - kernel_frames - dsp_frames;

    if (signed_frames > 0) {
        actual_frames_rendered = signed_frames;
@@ -4337,11 +4343,8 @@ static uint64_t get_actual_pcm_frames_rendered(struct stream_out *out, struct ti
    }
    pthread_mutex_unlock(&out->position_query_lock);

    ALOGVV("%s signed frames %lld out_written %lld kernel_buffer_size %d"
            "bytes/sample %zu channel count %d", __func__, signed_frames,
             (long long int)out->written, (int)kernel_buffer_size,
             audio_bytes_per_sample(out->compr_config.codec->format),
             popcount(out->channel_mask));
    ALOGVV("%s signed frames %lld written frames %lld kernel frames %lld dsp frames %lld",
            __func__, signed_frames, written_frames, kernel_frames, dsp_frames);

    return actual_frames_rendered;
}