diff options
author | Eric Laurent <elaurent@google.com> | 2011-03-07 14:52:59 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2011-03-08 16:33:15 -0800 |
commit | 1703cdfee717b1b312bf8979816a9e2f16a82e5d (patch) | |
tree | eb9d3cfe8ffebe45679de91af6f9ffd676ca5067 /include/private | |
parent | fbb1909036ba7de3d9fb8738daba60b357881153 (diff) | |
download | frameworks_av-1703cdfee717b1b312bf8979816a9e2f16a82e5d.zip frameworks_av-1703cdfee717b1b312bf8979816a9e2f16a82e5d.tar.gz frameworks_av-1703cdfee717b1b312bf8979816a9e2f16a82e5d.tar.bz2 |
Fix issue 3439872: video chat and bluetooth SCO
This change fixes the stability problems experienced when using
a bluetooth headset supporting both A2DP and SCO. Problems occur
when starting the video chat at which time the A2DP output is being
stopped to start SCO. At that time, active AudioTracks are invalidated
by AudioFlinger so that a new AudioTrack binder interface can be
recreated by the client process on the new mixer thread with correct parameters.
The problem was that the process to restore the binder interface was not
protected against concurrent requests which caused 2 binder interfaces
to be created sometimes. This could lead to permanent client deadlock
if one of the client threads was waiting for a condition of the first
created binder interface while the second one was created (as the AudioFlinger
would only signal conditions on the last one created).
This concurrent request situation is more likely to happen when a client
uses the JAVA AudioTrack as the JNI implementation uses simultaneously the
native AudioTrack callback and write push mechanisms. By doing so, the code
that checks if the binder interface should be restored (in obtainBuffer()) is
much more likely to be called concurrently from two different threads.
The fix consists in protecting the critical binder interface restore phase
with a flag in the AudioTrack control block. The first thread acting upon the binder
interface restore request will raise the flag and the second thread will just wait for
a condition to be signaled when the restore process is complete.
Also protected all accesses to the AudioTrack control block by a mutex to prevent
access while the track is being destroyed and restored. If a mutex cannot be held
(e.g because we call a callback function), acquire a strong reference on the IAudioTrack
to prevent its destruction while the cblk is being accessed.
Modified AudioTrack JNI to use GetByteArrayElements() instead of
GetPrimitiveArrayCritical() when writing audio buffers. Entering a critical section would
cause the JNI to abort if a mediaserver crash occurs during a write due to the AudioSystem
callback being called during the critical section when media server process restarts.
Anyway with current JNI implementation, either versions do not copy data most of the times
and the criticial version does not guaranty no data copy.
The same modifications have been made to AudioRecord.
Change-Id: Idc5aa711a04c3eee180cdd03f44fe17f3c4dcb52
Diffstat (limited to 'include/private')
-rw-r--r-- | include/private/media/AudioTrackShared.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index c6990bf..4610135 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -31,6 +31,7 @@ namespace android { #define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP init time #define MAX_RUN_TIMEOUT_MS 1000 #define WAIT_PERIOD_MS 10 +#define RESTORE_TIMEOUT_MS 5000 // Maximum waiting time for a track to be restored #define CBLK_UNDERRUN_MSK 0x0001 #define CBLK_UNDERRUN_ON 0x0001 // underrun (out) or overrrun (in) indication @@ -47,6 +48,12 @@ namespace android { #define CBLK_DISABLED_MSK 0x0010 #define CBLK_DISABLED_ON 0x0010 // track disabled by AudioFlinger due to underrun: #define CBLK_DISABLED_OFF 0x0000 // must be re-started +#define CBLK_RESTORING_MSK 0x0020 +#define CBLK_RESTORING_ON 0x0020 // track is being restored after invalidation +#define CBLK_RESTORING_OFF 0x0000 // by AudioFlinger +#define CBLK_RESTORED_MSK 0x0040 +#define CBLK_RESTORED_ON 0x0040 // track has been restored after invalidation +#define CBLK_RESTORED_OFF 0x0040 // by AudioFlinger struct audio_track_cblk_t { |