Index: webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java |
diff --git a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java |
index 8e27f5537191737b1463ec37a0c3249c1208ef96..df54fa28ba711f203ab264b9badb9a26febcb242 100644 |
--- a/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java |
+++ b/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java |
@@ -21,6 +21,7 @@ import android.media.MediaRecorder.AudioSource; |
import android.os.Process; |
import org.webrtc.Logging; |
+import org.webrtc.ThreadUtils; |
public class WebRtcAudioRecord { |
private static final boolean DEBUG = false; |
@@ -42,6 +43,10 @@ public class WebRtcAudioRecord { |
// high load. |
private static final int BUFFER_SIZE_FACTOR = 2; |
+ // The AudioRecordJavaThread is allowed to wait for successful call to join() |
+ // but the wait times out afther this amount of time. |
+ private static final long AUDIO_RECORD_THREAD_JOIN_TIMEOUT_MS = 2000; |
+ |
private final long nativeAudioRecord; |
private final Context context; |
@@ -102,19 +107,15 @@ public class WebRtcAudioRecord { |
try { |
audioRecord.stop(); |
} catch (IllegalStateException e) { |
- Logging.e(TAG,"AudioRecord.stop failed: " + e.getMessage()); |
+ Logging.e(TAG, "AudioRecord.stop failed: " + e.getMessage()); |
} |
} |
- public void joinThread() { |
+ // Stops the inner thread loop and also calls AudioRecord.stop(). |
+ // Does not block the calling thread. |
+ public void stopThread() { |
+ Logging.d(TAG, "stopThread"); |
keepAlive = false; |
- while (isAlive()) { |
- try { |
- join(); |
- } catch (InterruptedException e) { |
- // Ignore. |
- } |
- } |
} |
} |
@@ -131,7 +132,7 @@ public class WebRtcAudioRecord { |
private boolean enableBuiltInAEC(boolean enable) { |
Logging.d(TAG, "enableBuiltInAEC(" + enable + ')'); |
if (effects == null) { |
- Logging.e(TAG,"Built-in AEC is not supported on this platform"); |
+ Logging.e(TAG, "Built-in AEC is not supported on this platform"); |
return false; |
} |
return effects.setAEC(enable); |
@@ -140,7 +141,7 @@ public class WebRtcAudioRecord { |
private boolean enableBuiltInAGC(boolean enable) { |
Logging.d(TAG, "enableBuiltInAGC(" + enable + ')'); |
if (effects == null) { |
- Logging.e(TAG,"Built-in AGC is not supported on this platform"); |
+ Logging.e(TAG, "Built-in AGC is not supported on this platform"); |
return false; |
} |
return effects.setAGC(enable); |
@@ -149,7 +150,7 @@ public class WebRtcAudioRecord { |
private boolean enableBuiltInNS(boolean enable) { |
Logging.d(TAG, "enableBuiltInNS(" + enable + ')'); |
if (effects == null) { |
- Logging.e(TAG,"Built-in NS is not supported on this platform"); |
+ Logging.e(TAG, "Built-in NS is not supported on this platform"); |
return false; |
} |
return effects.setNS(enable); |
@@ -160,11 +161,11 @@ public class WebRtcAudioRecord { |
channels + ")"); |
if (!WebRtcAudioUtils.hasPermission( |
context, android.Manifest.permission.RECORD_AUDIO)) { |
- Logging.e(TAG,"RECORD_AUDIO permission is missing"); |
+ Logging.e(TAG, "RECORD_AUDIO permission is missing"); |
return -1; |
} |
if (audioRecord != null) { |
- Logging.e(TAG,"InitRecording() called twice without StopRecording()"); |
+ Logging.e(TAG, "InitRecording() called twice without StopRecording()"); |
return -1; |
} |
final int bytesPerFrame = channels * (BITS_PER_SAMPLE / 8); |
@@ -209,7 +210,7 @@ public class WebRtcAudioRecord { |
} |
if (audioRecord == null || |
audioRecord.getState() != AudioRecord.STATE_INITIALIZED) { |
- Logging.e(TAG,"Failed to create a new AudioRecord instance"); |
+ Logging.e(TAG, "Failed to create a new AudioRecord instance"); |
return -1; |
} |
Logging.d(TAG, "AudioRecord " |
@@ -242,11 +243,11 @@ public class WebRtcAudioRecord { |
try { |
audioRecord.startRecording(); |
} catch (IllegalStateException e) { |
- Logging.e(TAG,"AudioRecord.startRecording failed: " + e.getMessage()); |
+ Logging.e(TAG, "AudioRecord.startRecording failed: " + e.getMessage()); |
return false; |
} |
if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) { |
- Logging.e(TAG,"AudioRecord.startRecording failed"); |
+ Logging.e(TAG, "AudioRecord.startRecording failed"); |
return false; |
} |
audioThread = new AudioRecordThread("AudioRecordJavaThread"); |
@@ -257,7 +258,11 @@ public class WebRtcAudioRecord { |
private boolean stopRecording() { |
Logging.d(TAG, "stopRecording"); |
assertTrue(audioThread != null); |
- audioThread.joinThread(); |
+ audioThread.stopThread(); |
+ if (!ThreadUtils.joinUninterruptibly( |
+ audioThread, AUDIO_RECORD_THREAD_JOIN_TIMEOUT_MS)) { |
+ Logging.e(TAG, "Join of AudioRecordJavaThread timed out"); |
+ } |
audioThread = null; |
if (effects != null) { |
effects.release(); |
@@ -281,7 +286,7 @@ public class WebRtcAudioRecord { |
// TODO(glaznev): remove this API once SW mic mute can use AudioTrack.setEnabled(). |
public static void setMicrophoneMute(boolean mute) { |
- Logging.w(TAG,"setMicrophoneMute API will be deprecated soon."); |
+ Logging.w(TAG, "setMicrophoneMute API will be deprecated soon."); |
microphoneMute = mute; |
} |
} |