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
This commit is contained in:
parent
e1be46f950
commit
4c63039cfa
107
hal/audio_hw.c
107
hal/audio_hw.c
|
@ -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) {
|
||||
|
@ -1700,7 +1752,8 @@ exit:
|
|||
ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(out->pcm));
|
||||
out_standby(&out->stream.common);
|
||||
usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
|
||||
out_get_sample_rate(&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,13 +2136,22 @@ 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_frame_size(&in->stream.common) /
|
||||
in_get_sample_rate(&in->stream.common));
|
||||
in_get_sample_rate(&in->stream.common));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue