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
This commit is contained in:
parent
2d15e305c8
commit
8065983e75
137
hal/audio_hw.c
137
hal/audio_hw.c
|
@ -237,6 +237,32 @@ static int get_snd_codec_id(audio_format_t format)
|
|||
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 start_input_stream(struct stream_in *in)
|
|||
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 @@ int start_output_stream(struct stream_out *out)
|
|||
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 @@ 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;
|
||||
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 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
|
|||
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 @@ exit:
|
|||
/* 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 @@ static int out_get_render_position(const struct audio_stream_out *stream,
|
|||
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 @@ static int out_pause(struct audio_stream_out* stream)
|
|||
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 @@ static int out_resume(struct audio_stream_out* stream)
|
|||
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 @@ 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;
|
||||
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 @@ exit:
|
|||
/* 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 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
|
|||
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 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *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")) {
|
||||
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 @@ static char* adev_get_parameters(const struct audio_hw_device *dev,
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue