hal: SSR support for compress offload
- add support for time stamp error propagation
to frameworks on compress driver error
- close active compress session on SSR
Change-Id: I9cbd3a6c271097b81c9b79e71573fda8d78c7dbf
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index f0a5a97..a357e98 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -237,6 +237,32 @@
return id;
}
+static int get_snd_card_state(struct audio_device *adev)
+{
+ int snd_scard_state;
+
+ if (!adev)
+ return SND_CARD_STATE_OFFLINE;
+
+ pthread_mutex_lock(&adev->snd_card_status.lock);
+ snd_scard_state = adev->snd_card_status.state;
+ pthread_mutex_unlock(&adev->snd_card_status.lock);
+
+ return snd_scard_state;
+}
+
+static int set_snd_card_state(struct audio_device *adev, int snd_scard_state)
+{
+ if (!adev)
+ return -ENOSYS;
+
+ pthread_mutex_lock(&adev->snd_card_status.lock);
+ adev->snd_card_status.state = snd_scard_state;
+ pthread_mutex_unlock(&adev->snd_card_status.lock);
+
+ return 0;
+}
+
int enable_audio_route(struct audio_device *adev,
struct audio_usecase *usecase)
{
@@ -793,19 +819,18 @@
int ret = 0;
struct audio_usecase *uc_info;
struct audio_device *adev = in->dev;
+ int snd_card_status = get_snd_card_state(adev);
in->usecase = platform_update_usecase_from_source(in->source,in->usecase);
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) {
+
+ if (SND_CARD_STATE_OFFLINE == snd_card_status) {
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);
@@ -1183,19 +1208,17 @@
char prop_value[PROPERTY_VALUE_MAX] = {0};
struct audio_usecase *uc_info;
struct audio_device *adev = out->dev;
+ int snd_card_status = get_snd_card_state(adev);
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) {
+ if (SND_CARD_STATE_OFFLINE == snd_card_status) {
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) {
@@ -1669,19 +1692,21 @@
{
struct stream_out *out = (struct stream_out *)stream;
struct audio_device *adev = out->dev;
- int scard_state = SND_CARD_STATE_ONLINE;
+ int snd_scard_state = get_snd_card_state(adev);
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) {
+ if (SND_CARD_STATE_OFFLINE == snd_scard_state) {
+ if (out->pcm) {
ALOGD(" %s: sound card is not active/SSR state", __func__);
ret= -ENETRESET;
goto exit;
+ } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ //during SSR for compress usecase we should return error to flinger
+ ALOGD(" copl %s: sound card is not active/SSR state", __func__);
+ pthread_mutex_unlock(&out->lock);
+ return -ENETRESET;
}
}
@@ -1713,8 +1738,14 @@
if (ret >= 0 && ret < (ssize_t)bytes) {
ALOGD("No space available in compress driver, post msg to cb thread");
send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
+ } else if (-ENETRESET == ret) {
+ ALOGE("copl %s: received sound card offline state on compress write", __func__);
+ set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
+ pthread_mutex_unlock(&out->lock);
+ out_standby(&out->stream.common);
+ return ret;
}
- if (!out->playback_started) {
+ if (!out->playback_started && ret >= 0) {
compress_start(out->compr);
out->playback_started = 1;
out->offload_state = OFFLOAD_STATE_PLAYING;
@@ -1736,9 +1767,7 @@
/* ToDo: There may be a corner case when SSR happens back to back during
start/stop. Need to post different error to handle that. */
if (-ENETRESET == ret) {
- pthread_mutex_lock(&adev->snd_card_status.lock);
- adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
- pthread_mutex_unlock(&adev->snd_card_status.lock);
+ set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
}
pthread_mutex_unlock(&out->lock);
@@ -1760,15 +1789,25 @@
struct stream_out *out = (struct stream_out *)stream;
*dsp_frames = 0;
if (is_offload_usecase(out->usecase) && (dsp_frames != NULL)) {
+ ssize_t ret = -EINVAL;
pthread_mutex_lock(&out->lock);
if (out->compr != NULL) {
- compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
+ ret = compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
&out->sample_rate);
ALOGVV("%s rendered frames %d sample_rate %d",
__func__, *dsp_frames, out->sample_rate);
}
pthread_mutex_unlock(&out->lock);
- return 0;
+ if (-ENETRESET == ret) {
+ ALOGE(" ERROR: sound card not active Unable to get time stamp from compress driver");
+ set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
+ return -EINVAL;
+ } else if(ret < 0) {
+ ALOGE(" ERROR: Unable to get time stamp from compress driver");
+ return -EINVAL;
+ } else {
+ return 0;
+ }
} else
return -EINVAL;
}
@@ -1856,7 +1895,12 @@
ALOGD("copl(%p):pause compress driver", out);
pthread_mutex_lock(&out->lock);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
- status = compress_pause(out->compr);
+ struct audio_device *adev = out->dev;
+ int snd_scard_state = get_snd_card_state(adev);
+
+ if (SND_CARD_STATE_ONLINE == snd_scard_state)
+ status = compress_pause(out->compr);
+
out->offload_state = OFFLOAD_STATE_PAUSED;
}
pthread_mutex_unlock(&out->lock);
@@ -1874,7 +1918,12 @@
status = 0;
pthread_mutex_lock(&out->lock);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) {
- status = compress_resume(out->compr);
+ struct audio_device *adev = out->dev;
+ int snd_scard_state = get_snd_card_state(adev);
+
+ if (SND_CARD_STATE_ONLINE == snd_scard_state)
+ status = compress_resume(out->compr);
+
out->offload_state = OFFLOAD_STATE_PLAYING;
}
pthread_mutex_unlock(&out->lock);
@@ -2081,15 +2130,12 @@
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;
+ int snd_scard_state = get_snd_card_state(adev);
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) {
+ if(SND_CARD_STATE_OFFLINE == snd_scard_state) {
ALOGD(" %s: sound card is not active/SSR state", __func__);
ret= -ENETRESET;
goto exit;
@@ -2129,10 +2175,8 @@
/* ToDo: There may be a corner case when SSR happens back to back during
start/stop. Need to post different error to handle that. */
if (-ENETRESET == ret) {
- pthread_mutex_lock(&adev->snd_card_status.lock);
- adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
+ set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
memset(buffer, 0, bytes);
- pthread_mutex_unlock(&adev->snd_card_status.lock);
}
pthread_mutex_unlock(&in->lock);
@@ -2210,6 +2254,13 @@
audio_format_t format;
*stream_out = NULL;
+
+ if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
+ (SND_CARD_STATE_OFFLINE == get_snd_card_state(adev))) {
+ ALOGE(" sound card is not active rejecting compress output open request");
+ return -EINVAL;
+ }
+
out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
ALOGD("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)\
@@ -2479,15 +2530,29 @@
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")) {
+ struct listnode *node;
+ struct audio_usecase *usecase;
+
ALOGD("Received sound card OFFLINE status");
- adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
+ set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
+
+ pthread_mutex_lock(&adev->lock);
+ //close compress session on OFFLINE status
+ usecase = get_usecase_from_list(adev,USECASE_AUDIO_PLAYBACK_OFFLOAD);
+ if (usecase && usecase->stream.out) {
+ ALOGD(" %s closing compress session on OFFLINE state", __func__);
+
+ struct stream_out *out = usecase->stream.out;
+
+ pthread_mutex_unlock(&adev->lock);
+ out_standby(&out->stream.common);
+ } else
+ pthread_mutex_unlock(&adev->lock);
} else if (strstr(snd_card_status, "ONLINE")) {
ALOGD("Received sound card ONLINE status");
- adev->snd_card_status.state = SND_CARD_STATE_ONLINE;
+ set_snd_card_state(adev,SND_CARD_STATE_ONLINE);
}
- pthread_mutex_unlock(&adev->snd_card_status.lock);
}
pthread_mutex_lock(&adev->lock);
@@ -2568,15 +2633,15 @@
char *str;
pthread_mutex_lock(&adev->lock);
-
audio_extn_get_parameters(adev, query, reply);
voice_get_parameters(adev, query, reply);
platform_get_parameters(adev->platform, query, reply);
+ pthread_mutex_unlock(&adev->lock);
+
str = str_parms_to_str(reply);
str_parms_destroy(query);
str_parms_destroy(reply);
- pthread_mutex_unlock(&adev->lock);
ALOGV("%s: exit: returns - %s", __func__, str);
return str;
}