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

Commit 2d19ab43 authored by Naresh Tanniru's avatar Naresh Tanniru Committed by Divya Narayanan Poojary
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 6f461b96
Loading
Loading
Loading
Loading
+103 −6
Original line number Diff line number Diff line
@@ -819,6 +819,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)
@@ -875,6 +884,8 @@ int start_input_stream(struct stream_in *in)
        }
        break;
    }
    in->pcm_error_type = PCM_ERROR_NONE;

    ALOGV("%s: exit", __func__);
    return ret;

@@ -1164,6 +1175,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)",
@@ -1228,6 +1249,7 @@ int start_output_stream(struct stream_out *out)
            }
            break;
        }
        out->pcm_error_type = PCM_ERROR_NONE;
    } else {
        out->pcm = NULL;
        out->compr = compress_open(adev->snd_card,
@@ -1663,9 +1685,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);
@@ -1716,14 +1757,24 @@ 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) {
        if (out->pcm)
            ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(out->pcm));
        out_standby(&out->stream.common);
        usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
        usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
                        out_get_sample_rate(&out->stream.common));

    }
    return bytes;
}
@@ -2058,8 +2109,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)
@@ -2093,12 +2163,21 @@ 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) {
        in_standby(&in->stream.common);
        ALOGV("%s: read failed - sleeping for buffer duration", __func__);
        usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
        usleep(bytes * 1000000 / audio_stream_frame_size(&in->stream.common) /
                                   in_get_sample_rate(&in->stream.common));
    }
    return bytes;
@@ -2466,10 +2545,23 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
    int status = 0;

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

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

    ret = str_parms_get_str(parms, "SND_CARD_STATUS", value, sizeof(value));
    if (ret >= 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);
    status = voice_set_parameters(adev, parms);
    if (status != 0)
        goto done;
@@ -2860,6 +2952,9 @@ static int adev_open(const hw_module_t *module, const char *name,
    list_init(&adev->usecase_list);
    adev->cur_wfd_channels = 2;

    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) {
@@ -2871,6 +2966,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) {
+18 −0
Original line number Diff line number Diff line
@@ -49,6 +49,9 @@
#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.
@@ -129,6 +132,12 @@ enum {
    OFFLOAD_STATE_PAUSED,
};

enum {
    PCM_ERROR_NONE,
    PCM_ERROR_EIO,
    PCM_ERROR_ENETRESET,  //Send from pcm driver during SSR
};

struct offload_cmd {
    struct listnode node;
    int cmd;
@@ -169,6 +178,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;
};
@@ -187,6 +197,7 @@ struct stream_in {
    bool enable_aec;
    bool enable_ns;
    audio_format_t format;
    int pcm_error_type;

    struct audio_device *dev;
};
@@ -214,6 +225,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 */
@@ -244,6 +260,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,