From d6359186eaa049305af685f4ed978ab2668a694d Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 8 Feb 2017 16:58:22 +0100 Subject: [PATCH] audio: Do not segfault in out_get_presentation_position() When a voice call is stopped we switch back to the default primary output (speaker). Then this function gets executed and as ther was no active PCM because voice_session is handling that it segfaults because the PCM is NULL. Change-Id: I927504b7962b096c0d4c3642b48aee55c85ec013 --- audio/audio_hw.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/audio/audio_hw.c b/audio/audio_hw.c index c147acf6..cc04a95c 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -3086,27 +3086,38 @@ static int out_get_presentation_position(const struct audio_stream_out *stream, } else { /* FIXME: which device to read from? */ if (!list_empty(&out->pcm_dev_list)) { + struct pcm_device *pcm_device; + struct listnode *node; unsigned int avail; - struct pcm_device *pcm_device = node_to_item(list_head(&out->pcm_dev_list), - struct pcm_device, stream_list_node); - - if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) { - size_t kernel_buffer_size = out->config.period_size * out->config.period_count; - int64_t signed_frames = out->written - kernel_buffer_size + avail; - /* This adjustment accounts for buffering after app processor. - It is based on estimated DSP latency per use case, rather than exact. */ - signed_frames -= - (render_latency(out->usecase) * out->sample_rate / 1000000LL); - - /* It would be unusual for this value to be negative, but check just in case ... */ - if (signed_frames >= 0) { - *frames = signed_frames; - ret = 0; + + list_for_each(node, &out->pcm_dev_list) { + pcm_device = node_to_item(node, + struct pcm_device, + stream_list_node); + + if (pcm_device->pcm != NULL) { + if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) { + size_t kernel_buffer_size = out->config.period_size * out->config.period_count; + int64_t signed_frames = out->written - kernel_buffer_size + avail; + /* This adjustment accounts for buffering after app processor. + It is based on estimated DSP latency per use case, rather than exact. */ + signed_frames -= + (render_latency(out->usecase) * out->sample_rate / 1000000LL); + + /* It would be unusual for this value to be negative, but check just in case ... */ + if (signed_frames >= 0) { + *frames = signed_frames; + ret = 0; + goto done; + } + ret = -1; + } } } } } +done: pthread_mutex_unlock(&out->lock); return ret;