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

Commit ab929a80 authored by Andy Hung's avatar Andy Hung Committed by Android Git Automerger
Browse files

am 45bb20de: Merge "DO NOT MERGE - A2DP audio HAL: implement...

am 45bb20de: Merge "DO NOT MERGE - A2DP audio HAL: implement out_get_presentation_position()" into mnc-dr-dev

* commit '45bb20de':
  DO NOT MERGE - A2DP audio HAL: implement out_get_presentation_position()
parents ff71dc9d 45bb20de
Loading
Loading
Loading
Loading
+42 −5
Original line number Diff line number Diff line
@@ -107,6 +107,8 @@ struct a2dp_stream_common {
struct a2dp_stream_out {
    struct audio_stream_out stream;
    struct a2dp_stream_common common;
    uint64_t frames_presented; // frames written, never reset
    uint64_t frames_rendered;  // frames written, reset on standby
};

struct a2dp_stream_in {
@@ -591,14 +593,17 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
    pthread_mutex_unlock(&out->common.lock);
    sent = skt_write(out->common.audio_fd, buffer,  bytes);

    if (sent == -1)
    {
    if (sent == -1) {
        skt_disconnect(out->common.audio_fd);
        out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
        if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
            out->common.state = AUDIO_A2DP_STATE_STOPPED;
        else
            ERROR("write failed : stream suspended, avoid resetting state");
    } else {
        const size_t frames = bytes / audio_stream_out_frame_size(stream);
        out->frames_rendered += frames;
        out->frames_presented += frames;
    }

    DEBUG("wrote %d bytes out of %zu bytes", sent, bytes);
@@ -676,6 +681,7 @@ static int out_standby(struct audio_stream *stream)
    // Do nothing in SUSPENDED state.
    if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
        retVal = suspend_audio_datapath(&out->common, true);
    out->frames_rendered = 0; // rendered is reset, presented is not
    pthread_mutex_unlock (&out->common.lock);

    return retVal;
@@ -786,16 +792,45 @@ static int out_set_volume(struct audio_stream_out *stream, float left,
    return -ENOSYS;
}

static int out_get_presentation_position(const struct audio_stream_out *stream,
                                         uint64_t *frames, struct timespec *timestamp)
{
    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;

    FNLOG();
    if (stream == NULL || frames == NULL || timestamp == NULL)
        return -EINVAL;

    int ret = -EWOULDBLOCK;
    pthread_mutex_lock(&out->common.lock);
    uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
    if (out->frames_presented >= latency_frames) {
        *frames = out->frames_presented - latency_frames;
        clock_gettime(CLOCK_MONOTONIC, timestamp); // could also be associated with out_write().
        ret = 0;
    }
    pthread_mutex_unlock(&out->common.lock);
    return ret;
}

static int out_get_render_position(const struct audio_stream_out *stream,
                                   uint32_t *dsp_frames)
{
    UNUSED(stream);
    UNUSED(dsp_frames);
    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;

    FNLOG();
    if (stream == NULL || dsp_frames == NULL)
        return -EINVAL;

    pthread_mutex_lock(&out->common.lock);
    uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
    if (out->frames_rendered >= latency_frames) {
        *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
    } else {
        *dsp_frames = 0;
    }
    pthread_mutex_unlock(&out->common.lock);
    return 0;
}

static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
@@ -1048,6 +1083,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
    out->stream.set_volume = out_set_volume;
    out->stream.write = out_write;
    out->stream.get_render_position = out_get_render_position;
    out->stream.get_presentation_position = out_get_presentation_position;


    /* initialize a2dp specifics */
    a2dp_stream_common_init(&out->common);