Skip to content

Commit

Permalink
The onWebRtcAudioTrackStartError is changed in this CL which breaks t…
Browse files Browse the repository at this point in the history
…he internal projects.

Revert "Improves native Android audio implementations."

This reverts commit 92b1ffd.

Reason for revert: <INSERT REASONING HERE>

Original change's description:
> Improves native Android audio implementations.
> 
> Summary:
> 
> Adds AudioTrackStartErrorCode to separate different types of error
> codes in combination with StartPlayout.
> 
> Harmonizes WebRtcAudioRecord and WebRtcAudioTrack implementations
> to ensure that init/start/stop is performed identically.
> 
> Adds thread checking in WebRtcAudio track.
> 
> Bug: webrtc:8453
> Change-Id: Ic913e888ff9493c9cc748a7b4dae43eb6b37fa85
> Reviewed-on: https://webrtc-review.googlesource.com/15481
> Commit-Queue: Henrik Andreassson <[email protected]>
> Reviewed-by: Alex Glaznev <[email protected]>
> Cr-Commit-Position: refs/heads/master@{#20448}

[email protected],[email protected]

Change-Id: If1d1d9717387a4a8f6d9d6acf7e86ded4c655b5e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:8453
Reviewed-on: https://webrtc-review.googlesource.com/16321
Reviewed-by: Zhi Huang <[email protected]>
Commit-Queue: Zhi Huang <[email protected]>
Cr-Commit-Position: refs/heads/master@{#20452}
  • Loading branch information
zhihuang0718 authored and Commit Bot committed Oct 26, 2017
1 parent c2a0eb2 commit 0af34ad
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
import org.webrtc.voiceengine.WebRtcAudioRecord.AudioRecordStartErrorCode;
import org.webrtc.voiceengine.WebRtcAudioRecord.WebRtcAudioRecordErrorCallback;
import org.webrtc.voiceengine.WebRtcAudioTrack;
import org.webrtc.voiceengine.WebRtcAudioTrack.AudioTrackStartErrorCode;
import org.webrtc.voiceengine.WebRtcAudioTrack.WebRtcAudioTrackErrorCallback;
import org.webrtc.voiceengine.WebRtcAudioUtils;

Expand Down Expand Up @@ -496,20 +495,16 @@ public void onWebRtcAudioRecordError(String errorMessage) {
WebRtcAudioTrack.setErrorCallback(new WebRtcAudioTrackErrorCallback() {
@Override
public void onWebRtcAudioTrackInitError(String errorMessage) {
Log.e(TAG, "onWebRtcAudioTrackInitError: " + errorMessage);
reportError(errorMessage);
}

@Override
public void onWebRtcAudioTrackStartError(
AudioTrackStartErrorCode errorCode, String errorMessage) {
Log.e(TAG, "onWebRtcAudioTrackStartError: " + errorCode + ". " + errorMessage);
public void onWebRtcAudioTrackStartError(String errorMessage) {
reportError(errorMessage);
}

@Override
public void onWebRtcAudioTrackError(String errorMessage) {
Log.e(TAG, "onWebRtcAudioTrackError: " + errorMessage);
reportError(errorMessage);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,20 +128,16 @@ public void run() {
}
}

// Stops recording audio data.
if (audioRecord != null) {
Logging.d(TAG, "Calling AudioRecord.stop...");
try {
try {
if (audioRecord != null) {
audioRecord.stop();
Logging.d(TAG, "AudioRecord.stop is done.");
} catch (IllegalStateException e) {
Logging.e(TAG, "AudioRecord.stop failed: " + e.getMessage());
}
} catch (IllegalStateException e) {
Logging.e(TAG, "AudioRecord.stop failed: " + e.getMessage());
}

}

// Stops the inner thread loop which results in calling AudioRecord.stop().
// Stops the inner thread loop and also calls AudioRecord.stop().
// Does not block the calling thread.
public void stopThread() {
Logging.d(TAG, "stopThread");
Expand Down Expand Up @@ -259,7 +255,6 @@ private boolean startRecording() {
} catch (IllegalStateException e) {
reportWebRtcAudioRecordStartError(AudioRecordStartErrorCode.AUDIO_RECORD_START_EXCEPTION,
"AudioRecord.startRecording failed: " + e.getMessage());
releaseAudioResources();
return false;
}

Expand All @@ -275,7 +270,6 @@ private boolean startRecording() {
AudioRecordStartErrorCode.AUDIO_RECORD_START_STATE_MISMATCH,
"AudioRecord.startRecording failed - incorrect state :"
+ audioRecord.getRecordingState());
releaseAudioResources();
return false;
}

Expand All @@ -292,13 +286,9 @@ private boolean stopRecording() {
Logging.d(TAG, "stopRecording");
assertTrue(audioThread != null);
audioThread.stopThread();

Logging.d(TAG, "Stopping the AudioRecordThread...");
audioThread.interrupt();
if (!ThreadUtils.joinUninterruptibly(audioThread, AUDIO_RECORD_THREAD_JOIN_TIMEOUT_MS)) {
Logging.e(TAG, "Join of AudioRecordThread timed out.");
Logging.e(TAG, "Join of AudioRecordJavaThread timed out");
}
Logging.d(TAG, "AudioRecordThread has now been stopped.");
audioThread = null;
if (effects != null) {
effects.release();
Expand Down Expand Up @@ -363,7 +353,6 @@ public static void setMicrophoneMute(boolean mute) {

// Releases the native AudioRecord resources.
private void releaseAudioResources() {
Logging.d(TAG, "releaseAudioResources");
if (audioRecord != null) {
audioRecord.release();
audioRecord = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ private static int getDefaultUsageAttributeOnLollipopOrHigher() {

private final long nativeAudioTrack;
private final AudioManager audioManager;
private final ThreadUtils.ThreadChecker threadChecker = new ThreadUtils.ThreadChecker();

private ByteBuffer byteBuffer;

Expand All @@ -84,15 +83,9 @@ private static int getDefaultUsageAttributeOnLollipopOrHigher() {
private static volatile boolean speakerMute = false;
private byte[] emptyBytes;

// Audio playout/track error handler functions.
public enum AudioTrackStartErrorCode {
AUDIO_TRACK_START_EXCEPTION,
AUDIO_TRACK_START_STATE_MISMATCH,
}

public static interface WebRtcAudioTrackErrorCallback {
void onWebRtcAudioTrackInitError(String errorMessage);
void onWebRtcAudioTrackStartError(AudioTrackStartErrorCode errorCode, String errorMessage);
void onWebRtcAudioTrackStartError(String errorMessage);
void onWebRtcAudioTrackError(String errorMessage);
}

Expand Down Expand Up @@ -120,7 +113,26 @@ public AudioTrackThread(String name) {
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);
Logging.d(TAG, "AudioTrackThread" + WebRtcAudioUtils.getThreadInfo());
assertTrue(audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING);

try {
// In MODE_STREAM mode we can optionally prime the output buffer by
// writing up to bufferSizeInBytes (from constructor) before starting.
// This priming will avoid an immediate underrun, but is not required.
// TODO(henrika): initial tests have shown that priming is not required.
audioTrack.play();
} catch (IllegalStateException e) {
reportWebRtcAudioTrackStartError("AudioTrack.play failed: " + e.getMessage());
releaseAudioResources();
return;
}
// We have seen reports that AudioTrack.play() can sometimes start in a
// paued mode (e.g. when application is in background mode).
// TODO(henrika): consider calling reportWebRtcAudioTrackStartError()
// and release audio resources here as well. For now, let the thread start
// and hope that the audio session can be restored later.
if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
Logging.w(TAG, "AudioTrack failed to enter playing state.");
}

// Fixed size in bytes of each 10ms block of audio data that we ask for
// using callbacks to the native WebRTC client.
Expand Down Expand Up @@ -169,10 +181,10 @@ public void run() {
// MODE_STREAM mode, audio will stop playing after the last buffer that
// was written has been played.
if (audioTrack != null) {
Logging.d(TAG, "Calling AudioTrack.stop...");
Logging.d(TAG, "Stopping the audio track...");
try {
audioTrack.stop();
Logging.d(TAG, "AudioTrack.stop is done.");
Logging.d(TAG, "The audio track has now been stopped.");
} catch (IllegalStateException e) {
Logging.e(TAG, "AudioTrack.stop failed: " + e.getMessage());
}
Expand All @@ -188,7 +200,7 @@ private int writePreLollipop(AudioTrack audioTrack, ByteBuffer byteBuffer, int s
return audioTrack.write(byteBuffer.array(), byteBuffer.arrayOffset(), sizeInBytes);
}

// Stops the inner thread loop which results in calling 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");
Expand All @@ -197,7 +209,6 @@ public void stopThread() {
}

WebRtcAudioTrack(long nativeAudioTrack) {
threadChecker.checkIsOnValidThread();
Logging.d(TAG, "ctor" + WebRtcAudioUtils.getThreadInfo());
this.nativeAudioTrack = nativeAudioTrack;
audioManager =
Expand All @@ -208,7 +219,6 @@ public void stopThread() {
}

private boolean initPlayout(int sampleRate, int channels) {
threadChecker.checkIsOnValidThread();
Logging.d(TAG, "initPlayout(sampleRate=" + sampleRate + ", channels=" + channels + ")");
final int bytesPerFrame = channels * (BITS_PER_SAMPLE / 8);
byteBuffer = ByteBuffer.allocateDirect(bytesPerFrame * (sampleRate / BUFFERS_PER_SECOND));
Expand Down Expand Up @@ -280,74 +290,48 @@ private boolean initPlayout(int sampleRate, int channels) {
}

private boolean startPlayout() {
threadChecker.checkIsOnValidThread();
Logging.d(TAG, "startPlayout");
assertTrue(audioTrack != null);
assertTrue(audioThread == null);

// Starts playing an audio track.
try {
audioTrack.play();
} catch (IllegalStateException e) {
reportWebRtcAudioTrackStartError(AudioTrackStartErrorCode.AUDIO_TRACK_START_EXCEPTION,
"AudioTrack.play failed: " + e.getMessage());
releaseAudioResources();
if (audioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
reportWebRtcAudioTrackStartError("AudioTrack instance is not successfully initialized.");
return false;
}

// Verify the playout state up to two times (with a sleep in between)
// before returning false and reporting an error.
int numberOfStateChecks = 0;
while (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING &&
++numberOfStateChecks < 2) {
threadSleep(200);
}
if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
reportWebRtcAudioTrackStartError(
AudioTrackStartErrorCode.AUDIO_TRACK_START_STATE_MISMATCH,
"AudioTrack.play failed - incorrect state :"
+ audioTrack.getPlayState());
releaseAudioResources();
return false;
}

// Create and start new high-priority thread which calls AudioTrack.write()
// and where we also call the native nativeGetPlayoutData() callback to
// request decoded audio from WebRTC.
audioThread = new AudioTrackThread("AudioTrackJavaThread");
audioThread.start();
return true;
}

private boolean stopPlayout() {
threadChecker.checkIsOnValidThread();
Logging.d(TAG, "stopPlayout");
assertTrue(audioThread != null);
logUnderrunCount();
audioThread.stopThread();

Logging.d(TAG, "Stopping the AudioTrackThread...");
audioThread.interrupt();
if (!ThreadUtils.joinUninterruptibly(audioThread, AUDIO_TRACK_THREAD_JOIN_TIMEOUT_MS)) {
Logging.e(TAG, "Join of AudioTrackThread timed out.");
}
Logging.d(TAG, "AudioTrackThread has now been stopped.");
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;
}

// Get max possible volume index for a phone call audio stream.
private int getStreamMaxVolume() {
threadChecker.checkIsOnValidThread();
Logging.d(TAG, "getStreamMaxVolume");
assertTrue(audioManager != null);
return audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
}

// Set current volume level for a phone call audio stream.
private boolean setStreamVolume(int volume) {
threadChecker.checkIsOnValidThread();
Logging.d(TAG, "setStreamVolume(" + volume + ")");
assertTrue(audioManager != null);
if (isVolumeFixed()) {
Expand All @@ -366,7 +350,6 @@ private boolean isVolumeFixed() {

/** Get current volume level for a phone call audio stream. */
private int getStreamVolume() {
threadChecker.checkIsOnValidThread();
Logging.d(TAG, "getStreamVolume");
assertTrue(audioManager != null);
return audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
Expand Down Expand Up @@ -481,17 +464,16 @@ private void releaseAudioResources() {
}

private void reportWebRtcAudioTrackInitError(String errorMessage) {
Logging.e(TAG, "Init playout error: " + errorMessage);
Logging.e(TAG, "Init error: " + errorMessage);
if (errorCallback != null) {
errorCallback.onWebRtcAudioTrackInitError(errorMessage);
}
}

private void reportWebRtcAudioTrackStartError(
AudioTrackStartErrorCode errorCode, String errorMessage) {
Logging.e(TAG, "Start playout error: " + errorCode + ". " + errorMessage);
private void reportWebRtcAudioTrackStartError(String errorMessage) {
Logging.e(TAG, "Start error: " + errorMessage);
if (errorCallback != null) {
errorCallback.onWebRtcAudioTrackStartError(errorCode, errorMessage);
errorCallback.onWebRtcAudioTrackStartError(errorMessage);
}
}

Expand All @@ -502,13 +484,4 @@ private void reportWebRtcAudioTrackError(String errorMessage) {
}
}

// Causes the currently executing thread to sleep for the specified number
// of milliseconds.
private void threadSleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Logging.e(TAG, "Thread.sleep failed: " + e.getMessage());
}
}
}

0 comments on commit 0af34ad

Please sign in to comment.