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

Commit 65ddcddb authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hal: Add support for low latency compress capture"

parents 094ca30d 14230921
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ void cin_close_input_stream(struct stream_in *in);
void cin_free_input_stream_resources(struct stream_in *in);
int cin_read(struct stream_in *in, void *buffer,
                        size_t bytes, size_t *bytes_read);
int cin_configure_input_stream(struct stream_in *in);
int cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config);

void audio_extn_set_snd_card_split(const char* in_snd_card_name)
{
@@ -5086,9 +5086,9 @@ int audio_extn_cin_read(struct stream_in *in, void *buffer,
    return (audio_extn_compress_in_enabled?
                            cin_read(in, buffer, bytes, bytes_read): -1);
}
int audio_extn_cin_configure_input_stream(struct stream_in *in)
int audio_extn_cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config)
{
    return (audio_extn_compress_in_enabled? cin_configure_input_stream(in): -1);
    return (audio_extn_compress_in_enabled? cin_configure_input_stream(in, in_config): -1);
}
// END: COMPRESS_IN ====================================================

+5 −1
Original line number Diff line number Diff line
@@ -216,6 +216,9 @@ bool audio_extn_qdsp_supported_usb();

//END: EXTN_QDSP_PLUGIN      ===========================================

#define MIN_OFFLOAD_BUFFER_DURATION_MS 5 /* 5ms */
#define MAX_OFFLOAD_BUFFER_DURATION_MS (100 * 1000) /* 100s */

void audio_extn_set_parameters(struct audio_device *adev,
                               struct str_parms *parms);

@@ -1072,7 +1075,7 @@ void audio_extn_cin_close_input_stream(struct stream_in *in);
void audio_extn_cin_free_input_stream_resources(struct stream_in *in);
int audio_extn_cin_read(struct stream_in *in, void *buffer,
                        size_t bytes, size_t *bytes_read);
int audio_extn_cin_configure_input_stream(struct stream_in *in);
int audio_extn_cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config);
// END: COMPRESS_INPUT_ENABLED ===============================

//START: SOURCE_TRACKING_FEATURE ==============================================
@@ -1147,6 +1150,7 @@ int audio_extn_utils_compress_get_dsp_presentation_pos(struct stream_out *out,
            uint64_t *frames, struct timespec *timestamp, int32_t clock_id);
int audio_extn_utils_pcm_get_dsp_presentation_pos(struct stream_out *out,
            uint64_t *frames, struct timespec *timestamp, int32_t clock_id);
size_t audio_extn_utils_get_input_buffer_size(uint32_t, audio_format_t, int, int64_t, bool);
#ifdef AUDIO_HW_LOOPBACK_ENABLED
/* API to create audio patch */
int audio_extn_hw_loopback_create_audio_patch(struct audio_hw_device *dev,
+4 −4
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ bool cin_applicable_stream(struct stream_in *in)
 * only after validating that input against cin_attached_usecase
 * except below calls
 * 1. cin_applicable_stream(in)
 * 2. cin_configure_input_stream(in)
 * 2. cin_configure_input_stream(in, in_config)
 */

bool cin_attached_usecase(audio_usecase_t uc_id)
@@ -276,9 +276,8 @@ int cin_read(struct stream_in *in, void *buffer,
    return ret;
}

int cin_configure_input_stream(struct stream_in *in)
int cin_configure_input_stream(struct stream_in *in, struct audio_config *in_config)
{
    struct audio_device *adev = in->dev;
    struct audio_config config = {.format = 0};
    int ret = 0, buffer_size = 0, meta_size = sizeof(struct snd_codec_metadata);
    cin_private_data_t *cin_data = NULL;
@@ -315,7 +314,8 @@ int cin_configure_input_stream(struct stream_in *in)
    config.channel_mask = in->channel_mask;
    config.format = in->format;
    in->config.channels = audio_channel_count_from_in_mask(in->channel_mask);
    buffer_size = adev->device.get_input_buffer_size(&adev->device, &config);
    buffer_size = audio_extn_utils_get_input_buffer_size(config.sample_rate, config.format,
                    in->config.channels, in_config->offload_info.duration_us / 1000, false);

    cin_data->compr_config.fragment_size = buffer_size;
    cin_data->compr_config.codec->id = get_snd_codec_id(in->format);
+122 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "platform.h"
#include "platform_api.h"
#include "audio_extn.h"
#include "voice_extn.h"
#include "voice.h"
#include <sound/compress_params.h>
#include <sound/compress_offload.h>
@@ -1249,6 +1250,88 @@ exit_send_app_type_cfg:
    return rc;
}

static int audio_extn_utils_check_input_parameters(uint32_t sample_rate,
                                  audio_format_t format,
                                  int channel_count)
{
    int ret = 0;

    if (((format != AUDIO_FORMAT_PCM_16_BIT) && (format != AUDIO_FORMAT_PCM_8_24_BIT) &&
        (format != AUDIO_FORMAT_PCM_24_BIT_PACKED) && (format != AUDIO_FORMAT_PCM_32_BIT) &&
        (format != AUDIO_FORMAT_PCM_FLOAT)) &&
        !voice_extn_compress_voip_is_format_supported(format) &&
        !audio_extn_compr_cap_format_supported(format) &&
        !audio_extn_cin_format_supported(format))
            ret = -EINVAL;

    switch (channel_count) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 6:
    case 8:
        break;
    default:
        ret = -EINVAL;
    }

    switch (sample_rate) {
    case 8000:
    case 11025:
    case 12000:
    case 16000:
    case 22050:
    case 24000:
    case 32000:
    case 44100:
    case 48000:
    case 88200:
    case 96000:
    case 176400:
    case 192000:
        break;
    default:
        ret = -EINVAL;
    }

    return ret;
}

static inline uint32_t audio_extn_utils_nearest_multiple(uint32_t num, uint32_t multiplier)
{
    uint32_t remainder = 0;

    if (!multiplier)
        return num;

    remainder = num % multiplier;
    if (remainder)
        num += (multiplier - remainder);

    return num;
}

static inline uint32_t audio_extn_utils_lcm(uint32_t num1, uint32_t num2)
{
    uint32_t high = num1, low = num2, temp = 0;

    if (!num1 || !num2)
        return 0;

    if (num1 < num2) {
         high = num2;
         low = num1;
    }

    while (low != 0) {
        temp = low;
        low = high % low;
        high = temp;
    }
    return (num1 * num2)/high;
}

int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
                                       struct audio_usecase *usecase)
{
@@ -2860,3 +2943,42 @@ int audio_extn_utils_is_vendor_enhanced_fwk()

    return is_running_with_enhanced_fwk;
}

size_t audio_extn_utils_get_input_buffer_size(uint32_t sample_rate,
                                            audio_format_t format,
                                            int channel_count,
                                            int64_t duration_ms,
                                            bool is_low_latency)
{
    size_t size = 0;
    size_t capture_duration = AUDIO_CAPTURE_PERIOD_DURATION_MSEC;
    uint32_t bytes_per_period_sample = 0;


    if (audio_extn_utils_check_input_parameters(sample_rate, format, channel_count) != 0)
        return 0;

    if (duration_ms >= MIN_OFFLOAD_BUFFER_DURATION_MS && duration_ms <= MAX_OFFLOAD_BUFFER_DURATION_MS)
        capture_duration = duration_ms;

    size = (sample_rate * capture_duration) / 1000;
    if (is_low_latency)
        size = LOW_LATENCY_CAPTURE_PERIOD_SIZE;


    bytes_per_period_sample = audio_bytes_per_sample(format) * channel_count;
    size *= bytes_per_period_sample;

    /* make sure the size is multiple of 32 bytes and additionally multiple of
     * the frame_size (required for 24bit samples and non-power-of-2 channel counts)
     * At 48 kHz mono 16-bit PCM:
     *  5.000 ms = 240 frames = 15*16*1*2 = 480, a whole multiple of 32 (15)
     *  3.333 ms = 160 frames = 10*16*1*2 = 320, a whole multiple of 32 (10)
     *
     *  The loop reaches result within 32 iterations, as initial size is
     *  already a multiple of frame_size
     */
    size = audio_extn_utils_nearest_multiple(size, audio_extn_utils_lcm(32, bytes_per_period_sample));

    return size;
}
+2 −2
Original line number Diff line number Diff line
@@ -8845,7 +8845,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
                   (in->dev->mode != AUDIO_MODE_IN_COMMUNICATION)) {
            audio_extn_compr_cap_init(in);
        } else if (audio_extn_cin_applicable_stream(in)) {
            ret = audio_extn_cin_configure_input_stream(in);
            ret = audio_extn_cin_configure_input_stream(in, config);
            if (ret)
                goto err_open;
        } else {
@@ -8896,7 +8896,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
                    ALOGV("%s: overriding usecase with USECASE_AUDIO_RECORD_COMPRESS2 and appending compress flag", __func__);
                    if (audio_extn_cin_applicable_stream(in)) {
                        in->sample_rate = config->sample_rate;
                        ret = audio_extn_cin_configure_input_stream(in);
                        ret = audio_extn_cin_configure_input_stream(in, config);
                        if (ret)
                            goto err_open;
                    }