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

Commit 2ccd7bab authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Implement HAL API get_presentation_position

This does _not_ address bug 10551158 (to include DSP buffering)

Change-Id: Ifbc5ca21c46eced3f93a891200c763a062625dd9
parent 6e895240
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -841,7 +841,7 @@ int start_output_stream(struct stream_out *out)
          __func__, 0, out->pcm_device_id);
    if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
        out->pcm = pcm_open(SOUND_CARD, out->pcm_device_id,
                               PCM_OUT, &out->config);
                               PCM_OUT | PCM_MONOTONIC, &out->config);
        if (out->pcm && !pcm_is_ready(out->pcm)) {
            ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
            pcm_close(out->pcm);
@@ -946,7 +946,7 @@ static int start_voice_call(struct audio_device *adev)
          __func__, SOUND_CARD, pcm_dev_rx_id);
    adev->voice_call_rx = pcm_open(SOUND_CARD,
                                  pcm_dev_rx_id,
                                  PCM_OUT, &pcm_config_voice_call);
                                  PCM_OUT | PCM_MONOTONIC, &pcm_config_voice_call);
    if (adev->voice_call_rx && !pcm_is_ready(adev->voice_call_rx)) {
        ALOGE("%s: %s", __func__, pcm_get_error(adev->voice_call_rx));
        ret = -EIO;
@@ -1305,6 +1305,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
                memset((void *)buffer, 0, bytes);
            ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
            ret = pcm_write(out->pcm, (void *)buffer, bytes);
            if (ret == 0)
                out->written += bytes / (out->config.channels * sizeof(short));
        }
    }

@@ -1356,6 +1358,33 @@ static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
    return -EINVAL;
}

static int out_get_presentation_position(const struct audio_stream_out *stream,
                                   uint64_t *frames, struct timespec *timestamp)
{
    struct stream_out *out = (struct stream_out *)stream;
    int ret = -1;

    pthread_mutex_lock(&out->lock);

    if (out->pcm) {
        size_t avail;
        if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
            size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
            // FIXME This calculation is incorrect if there is buffering after app processor
            int64_t signed_frames = out->written - kernel_buffer_size + avail;
            // It would be unusual for this value to be negative, but check just in case ...
            if (signed_frames >= 0) {
                *frames = signed_frames;
                ret = 0;
            }
        }
    }

    pthread_mutex_unlock(&out->lock);

    return ret;
}

static int out_set_callback(struct audio_stream_out *stream,
            stream_callback_t callback, void *cookie)
{
@@ -1784,9 +1813,11 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
    out->stream.write = out_write;
    out->stream.get_render_position = out_get_render_position;
    out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
    out->stream.get_presentation_position = out_get_presentation_position;

    out->standby = 1;
    /* out->muted = false; by calloc() */
    /* out->written = 0; by calloc() */

    pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
    pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ struct stream_out {
    /* Array of supported channel mask configurations. +1 so that the last entry is always 0 */
    audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
    bool muted;
    uint64_t written; /* total frames written, not cleared when entering standby */

    int non_blocking;
    int playback_started;