summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2017-02-08 16:58:22 +0100
committerAndreas Schneider <asn@cryptomilk.org>2017-02-11 14:20:24 +0100
commitd6359186eaa049305af685f4ed978ab2668a694d (patch)
treea0ab4fed9459819fbd9d8b843cb34c46f92e5650
parent696959dda1cd4437dd672a61d7a3266169ad3019 (diff)
downloadandroid_hardware_samsung-d6359186eaa049305af685f4ed978ab2668a694d.tar.gz
android_hardware_samsung-d6359186eaa049305af685f4ed978ab2668a694d.tar.bz2
android_hardware_samsung-d6359186eaa049305af685f4ed978ab2668a694d.zip
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
-rw-r--r--audio/audio_hw.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/audio/audio_hw.c b/audio/audio_hw.c
index c147acf..cc04a95 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;