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

Commit 4c63039c authored by Naresh Tanniru's avatar Naresh Tanniru
Browse files

hal: SSR support for pcm playback,pcm record usecases

- Added SSR event handling support in HAL

- Added support to drop incoming pcm data for pcm playback
  usecase during SSR

- Added support to send dummy input(mute/zero buffer) for
  record usecase during SSR

Change-Id: I158b62fa443bb523091128fe1308c9a9b1415502
parent e1be46f9
Loading
Loading
Loading
Loading
+103 −4
Original line number Diff line number Diff line
@@ -790,6 +790,15 @@ int start_input_stream(struct stream_in *in)
    ALOGD("%s: enter: stream(%p)usecase(%d: %s)",
          __func__, &in->stream, in->usecase, use_case_table[in->usecase]);

    pthread_mutex_lock(&adev->snd_card_status.lock);
    if (SND_CARD_STATE_OFFLINE == adev->snd_card_status.state) {
        ALOGE("%s: sound card is not active/SSR returning error", __func__);
        ret = -ENETRESET;
        pthread_mutex_unlock(&adev->snd_card_status.lock);
        goto error_config;
    }
    pthread_mutex_unlock(&adev->snd_card_status.lock);

    /* Check if source matches incall recording usecase criteria */
    ret = voice_check_and_set_incall_rec_usecase(adev, in);
    if (ret)
@@ -827,8 +836,11 @@ int start_input_stream(struct stream_in *in)
        pcm_close(in->pcm);
        in->pcm = NULL;
        ret = -EIO;
        in->pcm_error_type = PCM_ERROR_EIO;
        goto error_open;
    }

    in->pcm_error_type = PCM_ERROR_NONE;
    ALOGV("%s: exit", __func__);
    return ret;

@@ -1169,6 +1181,16 @@ int start_output_stream(struct stream_out *out)
    ALOGD("%s: enter: stream(%p)usecase(%d: %s) devices(%#x)",
          __func__, &out->stream, out->usecase, use_case_table[out->usecase],
          out->devices);

    pthread_mutex_lock(&adev->snd_card_status.lock);
    if (SND_CARD_STATE_OFFLINE == adev->snd_card_status.state) {
        ALOGE("%s: sound card is not active/SSR returning error", __func__);
        ret = -ENETRESET;
        pthread_mutex_unlock(&adev->snd_card_status.lock);
        goto error_config;
    }
    pthread_mutex_unlock(&adev->snd_card_status.lock);

    out->pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
    if (out->pcm_device_id < 0) {
        ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)",
@@ -1215,8 +1237,10 @@ int start_output_stream(struct stream_out *out)
            pcm_close(out->pcm);
            out->pcm = NULL;
            ret = -EIO;
            out->pcm_error_type = PCM_ERROR_EIO;
            goto error_open;
        }
        out->pcm_error_type = PCM_ERROR_NONE;
    } else {
        out->pcm = NULL;
        out->compr = compress_open(adev->snd_card,
@@ -1642,9 +1666,28 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
{
    struct stream_out *out = (struct stream_out *)stream;
    struct audio_device *adev = out->dev;
    int scard_state = SND_CARD_STATE_ONLINE;
    ssize_t ret = 0;

    pthread_mutex_lock(&out->lock);
    pthread_mutex_lock(&adev->snd_card_status.lock);
    scard_state = adev->snd_card_status.state;
    pthread_mutex_unlock(&adev->snd_card_status.lock);

    if (out->pcm) {
        if (SND_CARD_STATE_OFFLINE == scard_state) {
            ALOGD(" %s: sound card is not active/SSR state", __func__);
            ret= -ENETRESET;
            goto exit;
        } else if (PCM_ERROR_ENETRESET ==  out->pcm_error_type) {
            ALOGD(" %s restarting pcm session on post SSR", __func__);
            out->standby = false;
            pthread_mutex_unlock(&out->lock);
            out_standby(&out->stream.common);
            pthread_mutex_lock(&out->lock);
        }
    }

    if (out->standby) {
        out->standby = false;
        pthread_mutex_lock(&adev->lock);
@@ -1693,6 +1736,15 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
    }

exit:

    if (-ENETRESET == ret) {
        pthread_mutex_lock(&adev->snd_card_status.lock);
        adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
        out->pcm_error_type = PCM_ERROR_ENETRESET;
        out->standby = true; /*standby will be called on post SSR */
        pthread_mutex_unlock(&adev->snd_card_status.lock);
    }

    pthread_mutex_unlock(&out->lock);

    if (ret != 0) {
@@ -1701,6 +1753,7 @@ exit:
        out_standby(&out->stream.common);
        usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
                        out_get_sample_rate(&out->stream.common));

    }
    return bytes;
}
@@ -2032,8 +2085,27 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
    struct stream_in *in = (struct stream_in *)stream;
    struct audio_device *adev = in->dev;
    int i, ret = -1;
    int scard_state = SND_CARD_STATE_ONLINE;

    pthread_mutex_lock(&in->lock);
    pthread_mutex_lock(&adev->snd_card_status.lock);
    scard_state = adev->snd_card_status.state;
    pthread_mutex_unlock(&adev->snd_card_status.lock);

    if (in->pcm) {
        if(SND_CARD_STATE_OFFLINE == scard_state) {
            ALOGD(" %s: sound card is not active/SSR state", __func__);
            ret= -ENETRESET;
            goto exit;
        } else if (PCM_ERROR_ENETRESET ==  in->pcm_error_type) {
            ALOGD(" %s restarting pcm session on post SSR", __func__);
            in->standby = false;
            pthread_mutex_unlock(&in->lock);
            in_standby(&in->stream.common);
            pthread_mutex_lock(&in->lock);
        }
    }

    if (in->standby) {
        pthread_mutex_lock(&adev->lock);
        if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
@@ -2064,6 +2136,15 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
        memset(buffer, 0, bytes);

exit:

    if (-ENETRESET == ret) {
        pthread_mutex_lock(&adev->snd_card_status.lock);
        adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
        in->pcm_error_type = PCM_ERROR_ENETRESET;
        memset(buffer, 0, bytes);
        in->standby = true; /*standby will be called on post SSR */
        pthread_mutex_unlock(&adev->snd_card_status.lock);
    }
    pthread_mutex_unlock(&in->lock);

    if (ret != 0) {
@@ -2398,10 +2479,23 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
    int ret = 0, err;

    ALOGD("%s: enter: %s", __func__, kvpairs);

    pthread_mutex_lock(&adev->lock);
    parms = str_parms_create_str(kvpairs);

    err = str_parms_get_str(parms, "SND_CARD_STATUS", value, sizeof(value));
    if (err >= 0) {
        char *snd_card_status = value+2;
        pthread_mutex_lock(&adev->snd_card_status.lock);
        if (strstr(snd_card_status, "OFFLINE")) {
            ALOGD("Received sound card OFFLINE status");
            adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
        } else if (strstr(snd_card_status, "ONLINE")) {
            ALOGD("Received sound card ONLINE status");
            adev->snd_card_status.state = SND_CARD_STATE_ONLINE;
        }
        pthread_mutex_unlock(&adev->snd_card_status.lock);
    }

    pthread_mutex_lock(&adev->lock);
    ret = voice_set_parameters(adev, parms);
    if (ret != 0)
        goto done;
@@ -2762,6 +2856,9 @@ static int adev_open(const hw_module_t *module, const char *name,
    list_init(&adev->usecase_list);
    adev->cur_wfd_channels = 2;
    adev->offload_usecases_state = 0;

    pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL);
    adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
    /* Loads platform specific libraries dynamically */
    adev->platform = platform_init(adev);
    if (!adev->platform) {
@@ -2773,6 +2870,8 @@ static int adev_open(const hw_module_t *module, const char *name,
        return -EINVAL;
    }

    adev->snd_card_status.state = SND_CARD_STATE_ONLINE;

    if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) {
        adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW);
        if (adev->visualizer_lib == NULL) {
+17 −0
Original line number Diff line number Diff line
@@ -52,6 +52,8 @@
#define MAX_SUPPORTED_CHANNEL_MASKS 2
#define DEFAULT_HDMI_OUT_CHANNELS   2

#define SND_CARD_STATE_OFFLINE 0
#define SND_CARD_STATE_ONLINE 1
typedef int snd_device_t;

/* These are the supported use cases by the hardware.
@@ -138,6 +140,12 @@ enum {
    OFFLOAD_STATE_PAUSED,
};

enum {
    PCM_ERROR_NONE,
    PCM_ERROR_EIO,
    PCM_ERROR_ENETRESET,  /* For SSR */
};

struct offload_cmd {
    struct listnode node;
    int cmd;
@@ -178,6 +186,7 @@ struct stream_out {
    void *offload_cookie;
    struct compr_gapless_mdata gapless_mdata;
    int send_new_metadata;
    int pcm_error_type;

    struct audio_device *dev;
};
@@ -196,6 +205,7 @@ struct stream_in {
    bool enable_aec;
    bool enable_ns;
    audio_format_t format;
    int pcm_error_type;

    struct audio_device *dev;
};
@@ -223,6 +233,11 @@ struct audio_usecase {
    union stream_ptr stream;
};

struct sound_card_status {
    pthread_mutex_t lock;
    int state;
};

struct audio_device {
    struct audio_hw_device device;
    pthread_mutex_t lock; /* see note below on mutex acquisition order */
@@ -251,6 +266,8 @@ struct audio_device {
    void *offload_effects_lib;
    int (*offload_effects_start_output)(audio_io_handle_t, int);
    int (*offload_effects_stop_output)(audio_io_handle_t, int);

    struct sound_card_status snd_card_status;
};

int select_devices(struct audio_device *adev,