summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-03-02 18:38:06 -0800
committerEric Laurent <elaurent@google.com>2010-03-05 11:54:23 -0800
commitba8811f5528404527b0cbad584a836f0b1807d26 (patch)
treefdb7b5e747307bcfdecfed42cefb75b66c03a9be /media/libmedia
parentff846009ecb6df669feeb5d5feecf4b304b8b9a5 (diff)
downloadframeworks_base-ba8811f5528404527b0cbad584a836f0b1807d26.zip
frameworks_base-ba8811f5528404527b0cbad584a836f0b1807d26.tar.gz
frameworks_base-ba8811f5528404527b0cbad584a836f0b1807d26.tar.bz2
Fix issue 2428563: Camera rendered inoperable by voice call interruption.
The problem is that AudioRecord never exits read() when a timeout occurs while trying to get new PCM data from audio hardware input buffer: it just keeps waiting and retrying until stop() is called. In the same time, opencore AndroidAudioInput::audin_thread_func() loop cannot be exited when stuck in AudioRecord::read() because the iExitAudioThread flag can only be sampled when AudioRecord::read() returns. We remain stuck with the audio input thread running. The fix consists in modifying AudioRecord behavior in case of timeout when getting new PCM samples. We now wait only one timeout period and try to restart audio record, in case the problem is due to a media_server process crash. If this fails, we exit read() with a number of bytes read equals to 0 so that AndroidAudioInput::audin_thread_func() loop can exit. Also modified Audioflinger::RecordThread() loop so that we attempt to recover from HAL read errors. In case of read error, the input stream is forced to standby so that next read attempt does a reconfiguration and restart of the audio input device.
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/AudioRecord.cpp10
1 files changed, 7 insertions, 3 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index bce3371..ad037d6 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -552,13 +552,17 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize)
audioBuffer.frameCount = userSize/frameSize();
- // Calling obtainBuffer() with a negative wait count causes
- // an (almost) infinite wait time.
- status_t err = obtainBuffer(&audioBuffer, -1);
+ // By using a wait count corresponding to twice the timeout period in
+ // obtainBuffer() we give a chance to recover once for a read timeout
+ // (if media_server crashed for instance) before returning a length of
+ // 0 bytes read to the client
+ status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS));
if (err < 0) {
// out of buffers, return #bytes written
if (err == status_t(NO_MORE_BUFFERS))
break;
+ if (err == status_t(TIMED_OUT))
+ err = 0;
return ssize_t(err);
}