| Index: webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java
|
| diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java
|
| index ac6c8772660b7cf2405708b0bae313baf7fd1f27..6800a7c0232719c7d63b5fda817f7538b7797d7c 100644
|
| --- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java
|
| +++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioTrack.java
|
| @@ -152,8 +152,10 @@ public class WebRtcAudioTrack {
|
| bytesWritten = writePreLollipop(audioTrack, byteBuffer, sizeInBytes);
|
| }
|
| if (bytesWritten != sizeInBytes) {
|
| - Logging.e(TAG, "AudioTrack.write failed: " + bytesWritten);
|
| - if (bytesWritten == AudioTrack.ERROR_INVALID_OPERATION) {
|
| + Logging.e(TAG, "AudioTrack.write played invalid number of bytes: " + bytesWritten);
|
| + // If a write() returns a negative value, an error has occurred.
|
| + // Stop playing and report an error in this case.
|
| + if (bytesWritten < 0) {
|
| keepAlive = false;
|
| reportWebRtcAudioTrackError("AudioTrack.write failed: " + bytesWritten);
|
| }
|
| @@ -168,15 +170,16 @@ public class WebRtcAudioTrack {
|
| // audioTrack.getPlaybackHeadPosition().
|
| }
|
|
|
| - try {
|
| - if (audioTrack != null) {
|
| - audioTrack.stop();
|
| - }
|
| - } catch (IllegalStateException e) {
|
| - Logging.e(TAG, "AudioTrack.stop failed: " + e.getMessage());
|
| + // Stops playing the audio data. Since the instance was created in
|
| + // MODE_STREAM mode, audio will stop playing after the last buffer that
|
| + // was written has been played.
|
| + final AudioTrack at = audioTrack;
|
| + if (at != null) {
|
| + Logging.d(TAG, "Stopping the audio track...");
|
| + at.stop();
|
| + Logging.d(TAG, "The audio track has now been stopped.");
|
| + at.flush();
|
| }
|
| - assertTrue(audioTrack.getPlayState() == AudioTrack.PLAYSTATE_STOPPED);
|
| - audioTrack.flush();
|
| }
|
|
|
| @TargetApi(21)
|
| @@ -188,7 +191,7 @@ public class WebRtcAudioTrack {
|
| return audioTrack.write(byteBuffer.array(), byteBuffer.arrayOffset(), sizeInBytes);
|
| }
|
|
|
| - // Stops the inner thread loop and also calls AudioTrack.stop().
|
| + // Stops the inner thread loop and also calls AudioTrack.pause() and flush().
|
| // Does not block the calling thread.
|
| public void stopThread() {
|
| Logging.d(TAG, "stopThread");
|
| @@ -296,10 +299,18 @@ public class WebRtcAudioTrack {
|
| assertTrue(audioThread != null);
|
| logUnderrunCount();
|
| audioThread.stopThread();
|
| - if (!ThreadUtils.joinUninterruptibly(audioThread, AUDIO_TRACK_THREAD_JOIN_TIMEOUT_MS)) {
|
| - Logging.e(TAG, "Join of AudioTrackThread timed out");
|
| - }
|
| +
|
| + final Thread aThread = audioThread;
|
| audioThread = null;
|
| + if (aThread != null) {
|
| + Logging.d(TAG, "Stopping the AudioTrackThread...");
|
| + aThread.interrupt();
|
| + if (!ThreadUtils.joinUninterruptibly(aThread, AUDIO_TRACK_THREAD_JOIN_TIMEOUT_MS)) {
|
| + Logging.e(TAG, "Join of AudioTrackThread timed out.");
|
| + }
|
| + Logging.d(TAG, "AudioTrackThread has now been stopped.");
|
| + }
|
| +
|
| releaseAudioResources();
|
| return true;
|
| }
|
| @@ -430,6 +441,7 @@ public class WebRtcAudioTrack {
|
|
|
| // Releases the native AudioTrack resources.
|
| private void releaseAudioResources() {
|
| + Logging.d(TAG, "releaseAudioResources");
|
| if (audioTrack != null) {
|
| audioTrack.release();
|
| audioTrack = null;
|
|
|