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

Commit 4ab3ba9a authored by Haynes Mathew George's avatar Haynes Mathew George
Browse files

audio: Fix out_get_presentation_position for ULL/MMAP streams

Fix the implementation of out_get_presentation_position
for ULL and MMAP streams taking into account their
data flow model

CRs-Fixed: 2108310
Change-Id: I9123178e000ac33304d9a93e617798471f8a95cd
parent bba1bee2
Loading
Loading
Loading
Loading
+36 −19
Original line number Original line Diff line number Diff line
@@ -2992,7 +2992,7 @@ int start_output_stream(struct stream_out *out)
            flags |= PCM_MMAP | PCM_NOIRQ;
            flags |= PCM_MMAP | PCM_NOIRQ;
            pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT;
            pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT;
        } else if (out->realtime) {
        } else if (out->realtime) {
            flags |= PCM_MMAP | PCM_NOIRQ;
            flags |= PCM_MMAP | PCM_NOIRQ | PCM_MONOTONIC;
        } else
        } else
            flags |= PCM_MONOTONIC;
            flags |= PCM_MONOTONIC;


@@ -4584,14 +4584,31 @@ static int out_get_presentation_position(const struct audio_stream_out *stream,
        clock_gettime(CLOCK_MONOTONIC, timestamp);
        clock_gettime(CLOCK_MONOTONIC, timestamp);
    } else {
    } else {
        if (out->pcm) {
        if (out->pcm) {
            int64_t signed_frames = -1;
            // XXX it might be better to identify these
            // as realtime usecases?
            if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP ||
                out->usecase == USECASE_AUDIO_PLAYBACK_ULL) {
                unsigned int hw_ptr;
                if (pcm_mmap_get_hw_ptr(out->pcm, &hw_ptr, timestamp) == 0) {
                    signed_frames = hw_ptr;
                }
                ALOGV("%s frames %lld", __func__, (long long)signed_frames);
            } else {
                unsigned int avail;
                unsigned int avail;
                if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
                if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
                size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
                    size_t kernel_buffer_size =
                int64_t signed_frames = out->written - kernel_buffer_size + avail;
                            out->config.period_size * out->config.period_count;
                     signed_frames =
                            out->written - kernel_buffer_size + avail;
                }
            }

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


            // Adjustment accounts for A2dp encoder latency with non offload usecases
            // Adjustment accounts for A2dp encoder latency with non offload usecases
            // Note: Encoder latency is returned in ms, while platform_render_latency in us.
            // Note: Encoder latency is returned in ms, while platform_render_latency in us.
@@ -4605,7 +4622,6 @@ static int out_get_presentation_position(const struct audio_stream_out *stream,
                *frames = signed_frames;
                *frames = signed_frames;
                ret = 0;
                ret = 0;
            }
            }
            }
        } else if (out->card_status == CARD_STATUS_OFFLINE) {
        } else if (out->card_status == CARD_STATUS_OFFLINE) {
            *frames = out->written;
            *frames = out->written;
            clock_gettime(CLOCK_MONOTONIC, timestamp);
            clock_gettime(CLOCK_MONOTONIC, timestamp);
@@ -4883,6 +4899,7 @@ static int out_get_mmap_position(const struct audio_stream_out *stream,
        return -EINVAL;
        return -EINVAL;
    }
    }
    if (out->usecase != USECASE_AUDIO_PLAYBACK_MMAP) {
    if (out->usecase != USECASE_AUDIO_PLAYBACK_MMAP) {
        ALOGE("%s: called on %s", __func__, use_case_table[out->usecase]);
        return -ENOSYS;
        return -ENOSYS;
    }
    }
    if (out->pcm == NULL) {
    if (out->pcm == NULL) {