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

Commit 44dd7704 authored by Siddartha Shaik's avatar Siddartha Shaik Committed by Shiv Maliyappanahalli
Browse files

audio: hal: changes to support compressed input for transcode loopback



- Support compressed input format in transcode loopback extension
- Support compressed input format in target platform
- Test application changes to support pcm and compressed input formats

CRs-Fixed: 2061945
Change-Id: I693594164e05c09ffece8fa705149c7b45c2e5d3
Signed-off-by: default avatarSiddartha Shaik <sshaik@codeaurora.org>
parent a9d11687
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -906,8 +906,8 @@ int audio_extn_hw_loopback_set_audio_port_config(struct audio_hw_device *dev,
                                    const struct audio_port_config *config);
int audio_extn_hw_loopback_get_audio_port(struct audio_hw_device *dev,
                                    struct audio_port *port_in);
int audio_extn_loopback_init(struct audio_device *adev);
void audio_extn_loopback_deinit(struct audio_device *adev);
int audio_extn_hw_loopback_init(struct audio_device *adev);
void audio_extn_hw_loopback_deinit(struct audio_device *adev);
#else
static int __unused audio_extn_hw_loopback_create_audio_patch(struct audio_hw_device *dev __unused,
                                     unsigned int num_sources __unused,
@@ -933,11 +933,11 @@ static int __unused audio_extn_hw_loopback_get_audio_port(struct audio_hw_device
{
    return -ENOSYS;
}
static int __unused audio_extn_loopback_init(struct audio_device *adev __unused)
static int __unused audio_extn_hw_loopback_init(struct audio_device *adev __unused)
{
    return -ENOSYS;
}
static void __unused audio_extn_loopback_deinit(struct audio_device *adev __unused)
static void __unused audio_extn_hw_loopback_deinit(struct audio_device *adev __unused)
{
}
#endif
+21 −3
Original line number Diff line number Diff line
@@ -251,9 +251,14 @@ int32_t release_loopback_session(loopback_patch_t *active_loopback_patch)
    disable_snd_device(adev, uc_info->out_snd_device);
    disable_snd_device(adev, uc_info->in_snd_device);

    /* 4. Reset backend device to default state */
    platform_invalidate_backend_config(adev->platform,uc_info->in_snd_device);

    list_remove(&uc_info->list);
    free(uc_info);

    adev->active_input = get_next_active_input(adev);

    if (audio_extn_ip_hdlr_intf_supported(source_patch_config->format) && inout->ip_hdlr_handle) {
        ret = audio_extn_ip_hdlr_intf_close(inout->ip_hdlr_handle, true, inout);
        if (ret < 0)
@@ -284,6 +289,7 @@ int loopback_stream_cb(stream_callback_event_t event, void *param, void *cookie)
    if (event == AUDIO_EXTN_STREAM_CBK_EVENT_ERROR) {
        pthread_mutex_lock(&audio_loopback_mod->lock);
        release_loopback_session(cookie);
        audio_loopback_mod->patch_db.num_patches--;
        pthread_mutex_unlock(&audio_loopback_mod->lock);
    }
    return 0;
@@ -305,6 +311,7 @@ int create_loopback_session(loopback_patch_t *active_loopback_patch)
                                                    loopback_sink;
    struct stream_inout *inout =  &active_loopback_patch->patch_stream;
    struct adsp_hdlr_stream_cfg hdlr_stream_cfg;
    struct stream_in loopback_source_stream;

    ALOGD("%s: Create loopback session begin", __func__);

@@ -324,6 +331,16 @@ int create_loopback_session(loopback_patch_t *active_loopback_patch)

    list_add_tail(&adev->usecase_list, &uc_info->list);

    loopback_source_stream.source = AUDIO_SOURCE_UNPROCESSED;
    loopback_source_stream.device = inout->in_config.devices;
    loopback_source_stream.channel_mask = inout->in_config.channel_mask;
    loopback_source_stream.bit_width = inout->in_config.bit_width;
    loopback_source_stream.sample_rate = inout->in_config.sample_rate;
    loopback_source_stream.format = inout->in_config.format;

    memcpy(&loopback_source_stream.usecase, uc_info,
           sizeof(struct audio_usecase));
    adev->active_input = &loopback_source_stream;
    select_devices(adev, uc_info->id);

    pcm_dev_asm_rx_id = platform_get_pcm_device_id(uc_info->id, PCM_PLAYBACK);
@@ -579,10 +596,11 @@ int audio_extn_hw_loopback_release_audio_patch(struct audio_hw_device *dev,
        }
    }

    if (patch_found) {
    if (patch_found && (audio_loopback_mod->patch_db.num_patches > 0)) {
        active_loopback_patch = &(audio_loopback_mod->patch_db.loopback_patch[
                                patch_index]);
        status = release_loopback_session(active_loopback_patch);
        audio_loopback_mod->patch_db.num_patches--;
    } else {
        ALOGE("%s, Requested Patch handle does not exist", __func__);
        status = -1;
@@ -715,7 +733,7 @@ int audio_extn_hw_loopback_set_audio_port_config(struct audio_hw_device *dev,
}

/* Loopback extension initialization, part of hal init sequence */
int audio_extn_loopback_init(struct audio_device *adev)
int audio_extn_hw_loopback_init(struct audio_device *adev)
{
    ALOGV("%s Audio loopback extension initializing", __func__);
    int ret = 0, size = 0;
@@ -764,7 +782,7 @@ loopback_done:
    return ret;
}

void audio_extn_loopback_deinit(struct audio_device *adev)
void audio_extn_hw_loopback_deinit(struct audio_device *adev)
{
    ALOGV("%s Audio loopback extension de-initializing", __func__);

+10 −4
Original line number Diff line number Diff line
@@ -1562,6 +1562,7 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
    struct audio_usecase *vc_usecase = NULL;
    struct audio_usecase *voip_usecase = NULL;
    struct audio_usecase *hfp_usecase = NULL;
    struct stream_out stream_out;
    audio_usecase_t hfp_ucid;
    int status = 0;

@@ -1589,8 +1590,13 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
            ALOGE("%s: stream.inout is NULL", __func__);
            return -EINVAL;
        }
        out_snd_device = usecase->stream.inout->out_config.devices;
        in_snd_device = usecase->stream.inout->in_config.devices;
        stream_out.devices = usecase->stream.inout->out_config.devices;
        stream_out.sample_rate = usecase->stream.inout->out_config.sample_rate;
        stream_out.format = usecase->stream.inout->out_config.format;
        stream_out.channel_mask = usecase->stream.inout->out_config.channel_mask;
        out_snd_device = platform_get_output_snd_device(adev->platform,
                                                        &stream_out);
        in_snd_device = platform_get_input_snd_device(adev->platform, AUDIO_DEVICE_NONE);
        usecase->devices = (out_snd_device | in_snd_device);
    } else {
        /*
@@ -5546,7 +5552,7 @@ static int adev_close(hw_device_t *device)
        qahwi_deinit(device);
        audio_extn_adsp_hdlr_deinit();
        audio_extn_snd_mon_deinit();
        audio_extn_loopback_deinit(adev);
        audio_extn_hw_loopback_deinit(adev);
        if (adev->device_cfg_params) {
            free(adev->device_cfg_params);
            adev->device_cfg_params = NULL;
@@ -5733,7 +5739,7 @@ static int adev_open(const hw_module_t *module, const char *name,
    audio_extn_init(adev);
    audio_extn_listen_init(adev, adev->snd_card);
    audio_extn_gef_init(adev);
    audio_extn_loopback_init(adev);
    audio_extn_hw_loopback_init(adev);

    if (access(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, R_OK) == 0) {
        adev->offload_effects_lib = dlopen(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, RTLD_NOW);
+67 −7
Original line number Diff line number Diff line
@@ -223,6 +223,7 @@ typedef struct codec_backend_cfg {
    uint32_t sample_rate;
    uint32_t bit_width;
    uint32_t channels;
    uint32_t format;
    char     *bitwidth_mixer_ctl;
    char     *samplerate_mixer_ctl;
    char     *channels_mixer_ctl;
@@ -1421,6 +1422,7 @@ static void set_platform_defaults(struct platform_data * my_data)
    backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
    backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
    backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
    backend_tag_table[SND_DEVICE_IN_HDMI_MIC] = strdup("hdmi-mic");
    backend_tag_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
    backend_tag_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
    backend_tag_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
@@ -2419,6 +2421,7 @@ acdb_init_fail:
        my_data->current_backend_cfg[idx].channels = CODEC_BACKEND_DEFAULT_CHANNELS;
        if (idx > MAX_RX_CODEC_BACKENDS)
            my_data->current_backend_cfg[idx].channels = CODEC_BACKEND_DEFAULT_TX_CHANNELS;
        my_data->current_backend_cfg[idx].format = AUDIO_FORMAT_PCM;
        my_data->current_backend_cfg[idx].bitwidth_mixer_ctl = NULL;
        my_data->current_backend_cfg[idx].samplerate_mixer_ctl = NULL;
        my_data->current_backend_cfg[idx].channels_mixer_ctl = NULL;
@@ -2515,6 +2518,13 @@ acdb_init_fail:
    my_data->current_backend_cfg[DISP_PORT_RX_BACKEND].channels_mixer_ctl =
        strdup("Display Port RX Channels");

    my_data->current_backend_cfg[HDMI_TX_BACKEND].bitwidth_mixer_ctl =
        strdup("QUAT_MI2S_TX Format");
    my_data->current_backend_cfg[HDMI_TX_BACKEND].samplerate_mixer_ctl =
        strdup("QUAT_MI2S_TX SampleRate");
    my_data->current_backend_cfg[HDMI_TX_BACKEND].channels_mixer_ctl =
        strdup("QUAT_MI2S_TX Channels");

    ret = audio_extn_utils_get_codec_version(snd_card_name,
                                             my_data->adev->snd_card,
                                             my_data->codec_version);
@@ -3137,6 +3147,8 @@ int platform_get_backend_index(snd_device_t snd_device)
                        port = USB_AUDIO_TX_BACKEND;
                else if (strstr(backend_tag_table[snd_device], "bt-sco") != NULL)
                        port = BT_SCO_TX_BACKEND;
                else if (strcmp(backend_tag_table[snd_device], "hdmi-mic") == 0)
                        port = HDMI_TX_BACKEND;
        }
    } else {
        ALOGW("%s:napb: Invalid device - %d ", __func__, snd_device);
@@ -5423,7 +5435,7 @@ static int platform_set_codec_backend_cfg(struct audio_device* adev,
        ret = 0;
    }

    bool set_ext_disp_format = false;
    bool set_ext_disp_format = false, set_mi2s_tx_data_format = false;
    char *ext_disp_format = NULL;

    if (backend_idx == HDMI_RX_BACKEND) {
@@ -5432,10 +5444,32 @@ static int platform_set_codec_backend_cfg(struct audio_device* adev,
    } else if (backend_idx == DISP_PORT_RX_BACKEND) {
        ext_disp_format = "Display Port RX Format";
        set_ext_disp_format = true;
    } else if (backend_idx == HDMI_TX_BACKEND) {
        ext_disp_format = "QUAT MI2S TX Format";
        set_mi2s_tx_data_format = true;
    } else {
        ALOGV("%s: Format doesnt have to be set", __func__);
    }

    format = format & AUDIO_FORMAT_MAIN_MASK;
    /* Set data format only if there is a change from PCM to compressed
       and vice versa */
    if (set_mi2s_tx_data_format && (format ^ my_data->current_backend_cfg[backend_idx].format)) {
        struct mixer_ctl *ctl = mixer_get_ctl_by_name(adev->mixer, ext_disp_format);
        if (!ctl) {
            ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
                  __func__, ext_disp_format);
            return -EINVAL;
        }
        if (format == AUDIO_FORMAT_PCM) {
            ALOGE("%s:MI2S data format LPCM", __func__);
            mixer_ctl_set_enum_by_string(ctl, "LPCM");
        } else {
            ALOGE("%s:MI2S data format Compr", __func__);
            mixer_ctl_set_enum_by_string(ctl, "Compr");
        }
        my_data->current_backend_cfg[backend_idx].format = format;
    }
    if (set_ext_disp_format) {
        struct mixer_ctl *ctl = mixer_get_ctl_by_name(adev->mixer, ext_disp_format);
        if (!ctl) {
@@ -5878,15 +5912,17 @@ static bool platform_check_capture_codec_backend_cfg(struct audio_device* adev,
    unsigned int bit_width;
    unsigned int sample_rate;
    unsigned int channels;
    unsigned int format;
    struct platform_data *my_data = (struct platform_data *)adev->platform;

    bit_width = backend_cfg->bit_width;
    sample_rate = backend_cfg->sample_rate;
    channels = backend_cfg->channels;
    format = backend_cfg->format;

    ALOGI("%s:txbecf: afe: Codec selected backend: %d current bit width: %d and "
          "sample rate: %d, channels %d",__func__,backend_idx, bit_width,
          sample_rate, channels);
          "sample rate: %d, channels %d format %d",__func__,backend_idx, bit_width,
          sample_rate, channels,format);

    // For voice calls use default configuration i.e. 16b/48K, only applicable to
    // default backend
@@ -5937,15 +5973,17 @@ static bool platform_check_capture_codec_backend_cfg(struct audio_device* adev,
    // is not same as current backend comfiguration
    if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
        (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate) ||
        (channels != my_data->current_backend_cfg[backend_idx].channels)) {
        (channels != my_data->current_backend_cfg[backend_idx].channels) ||
        ((format & AUDIO_FORMAT_MAIN_MASK) != my_data->current_backend_cfg[backend_idx].format)) {
        backend_cfg->bit_width = bit_width;
        backend_cfg->sample_rate= sample_rate;
        backend_cfg->channels = channels;
        backend_cfg->format = format & AUDIO_FORMAT_MAIN_MASK;
        backend_change = true;
        ALOGI("%s:txbecf: afe: Codec backend needs to be updated. new bit width: %d "
              "new sample rate: %d new channel: %d",
              "new sample rate: %d new channel: %d new format: %d",
              __func__, backend_cfg->bit_width,
              backend_cfg->sample_rate, backend_cfg->channels);
              backend_cfg->sample_rate, backend_cfg->channels, backend_cfg->format);
    }

    return backend_change;
@@ -5978,11 +6016,12 @@ bool platform_check_and_set_capture_codec_backend_cfg(struct audio_device* adev,
        backend_cfg.channels = 1;
    }

    ALOGI("%s:txbecf: afe: bitwidth %d, samplerate %d, channel %d"
    ALOGI("%s:txbecf: afe: bitwidth %d, samplerate %d, channel %d format %d"
          ", backend_idx %d usecase = %d device (%s)", __func__,
          backend_cfg.bit_width,
          backend_cfg.sample_rate,
          backend_cfg.channels,
          backend_cfg.format,
          backend_idx, usecase->id,
          platform_get_snd_device_name(snd_device));
    if (platform_check_capture_codec_backend_cfg(adev, backend_idx,
@@ -6583,6 +6622,27 @@ void platform_cache_edid(void * platform)
    platform_get_edid_info(platform);
}

void platform_invalidate_backend_config(void * platform,snd_device_t snd_device)
{
    struct platform_data *my_data = (struct platform_data *)platform;
    struct audio_device *adev = my_data->adev;
    struct audio_backend_cfg backend_cfg;
    int backend_idx;

    backend_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
    backend_cfg.channels = CODEC_BACKEND_DEFAULT_CHANNELS;
    backend_cfg.bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
    backend_cfg.format = AUDIO_FORMAT_PCM_16_BIT;
    backend_cfg.passthrough_enabled = false;

    backend_idx = platform_get_backend_index(snd_device);
    platform_set_codec_backend_cfg(adev, snd_device, backend_cfg);
    my_data->current_backend_cfg[backend_idx].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
    my_data->current_backend_cfg[backend_idx].channels = CODEC_BACKEND_DEFAULT_CHANNELS;
    my_data->current_backend_cfg[backend_idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
    my_data->current_backend_cfg[backend_idx].format = AUDIO_FORMAT_PCM_16_BIT;
}

void platform_invalidate_hdmi_config(void * platform)
{
    //reset ext display EDID info
+1 −0
Original line number Diff line number Diff line
@@ -252,6 +252,7 @@ enum {
    DEFAULT_CODEC_TX_BACKEND = SLIMBUS_0_TX,
    USB_AUDIO_TX_BACKEND,
    BT_SCO_TX_BACKEND,
    HDMI_TX_BACKEND,
    MAX_CODEC_BACKENDS
};

Loading