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

Commit 098dcbdd authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hal: bug fixes for PCM offload"

parents 85dec15a aa54c87a
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -1980,14 +1980,25 @@ static char* out_get_parameters(const struct audio_stream *stream, const char *k
static uint32_t out_get_latency(const struct audio_stream_out *stream)
{
    struct stream_out *out = (struct stream_out *)stream;
    uint32_t latency = 0;

    if (is_offload_usecase(out->usecase))
        return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;

    return (out->config.period_count * out->config.period_size * 1000) /
    if (is_offload_usecase(out->usecase)) {
        if (out->use_small_bufs == true)
            latency = ((out->compr_config.fragments *
                   out->compr_config.fragment_size * 1000) /
                   (out->sample_rate * out->compr_config.codec->ch_in *
                   audio_bytes_per_sample(out->format)));
        else
            latency = COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
    } else {
        latency = (out->config.period_count * out->config.period_size * 1000) /
           (out->config.rate);
    }

    ALOGV("%s: Latency %d", latency);
    return latency;
}

static int out_set_volume(struct audio_stream_out *stream, float left,
                          float right)
{
@@ -2692,6 +2703,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
    out->handle = handle;
    out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
    out->non_blocking = 0;
    out->use_small_bufs = false;

    /* Init use case and pcm_config */
    if ((out->flags == AUDIO_OUTPUT_FLAG_DIRECT) &&
@@ -2826,6 +2839,15 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
        if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
            out->non_blocking = 1;

        if (config->offload_info.use_small_bufs) {
            //this flag is set from framework only if its for PCM formats
            //no need to check for PCM format again
            out->non_blocking = 0;
            out->use_small_bufs = true;
            ALOGI("Keep write blocking for small buff: non_blockling %d",
                  out->non_blocking);
        }

        out->send_new_metadata = 1;
        out->offload_state = OFFLOAD_STATE_IDLE;
        out->playback_started = 0;
+1 −0
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ struct stream_out {
    struct stream_app_type_cfg app_type_cfg;

    int non_blocking;
    bool use_small_bufs;
    int playback_started;
    int offload_state;
    pthread_cond_t offload_cond;
+23 −23
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@
/* Used in calculating fragment size for pcm offload */
#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 1000 /* 1 sec */
#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 80 /* 80 millisecs */
#define PCM_OFFLOAD_BUFFER_DURATION_FOR_SMALL_BUFFERS 20 /* 20 millisecs */
#define PCM_OFFLOAD_BUFFER_DURATION_MAX 1200  /* 1200 millisecs */

/* MAX PCM fragment size cannot be increased  further due
 * to flinger's cblk size of 1mb,and it has to be a multiple of
@@ -2898,35 +2900,33 @@ uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)

uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
{
    uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
    uint32_t fragment_size = 0;
    uint32_t bits_per_sample = 16;
    uint32_t pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_SMALL_BUFFERS;

    if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
        bits_per_sample = 32;
    }

    if (info->use_small_bufs) {
        pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_SMALL_BUFFERS;
    } else {
        if (!info->has_video) {
        fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;

            pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_MAX;
        } else if (info->has_video && info->is_streaming) {
        fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING
                                     * info->sample_rate
                                     * (bits_per_sample >> 3)
                                     * popcount(info->channel_mask))/1000;

            pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING;
        } else if (info->has_video) {
        fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
            pcm_offload_time = PCM_OFFLOAD_BUFFER_DURATION_FOR_AV;
        }
    }

    //duration is set to 20 ms worth of stereo data at 48Khz
    //with 16 bit per sample, modify this when the channel
    //configuration is different
    fragment_size = (pcm_offload_time
                     * info->sample_rate
                     * (bits_per_sample >> 3)
                     * popcount(info->channel_mask))/1000;
    }

    char value[PROPERTY_VALUE_MAX] = {0};
    if((property_get("audio.offload.pcm.buffer.size", value, "")) &&
            atoi(value)) {
        fragment_size =  atoi(value) * 1024;
        ALOGV("Using buffer size from sys prop %d", fragment_size);
    }

    fragment_size = ALIGN (fragment_size, 1024);

@@ -2935,7 +2935,7 @@ uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
    else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
        fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;

    ALOGV("%s: fragment_size %d", __func__, fragment_size);
    ALOGI("PCM offload Fragment size to %d bytes", fragment_size);
    return fragment_size;
}