Commit 15dc87b0 by Oliver Woodman

Add flag to force spurious audio timestamps to fail playback.

For enabling during device test runs.
parent e8fd3025
...@@ -55,7 +55,7 @@ public final class AudioTrack { ...@@ -55,7 +55,7 @@ public final class AudioTrack {
/** /**
* Thrown when a failure occurs instantiating an {@link android.media.AudioTrack}. * Thrown when a failure occurs instantiating an {@link android.media.AudioTrack}.
*/ */
public static class InitializationException extends Exception { public static final class InitializationException extends Exception {
/** The state as reported by {@link android.media.AudioTrack#getState()}. */ /** The state as reported by {@link android.media.AudioTrack#getState()}. */
public final int audioTrackState; public final int audioTrackState;
...@@ -72,7 +72,7 @@ public final class AudioTrack { ...@@ -72,7 +72,7 @@ public final class AudioTrack {
/** /**
* Thrown when a failure occurs writing to an {@link android.media.AudioTrack}. * Thrown when a failure occurs writing to an {@link android.media.AudioTrack}.
*/ */
public static class WriteException extends Exception { public static final class WriteException extends Exception {
/** The value returned from {@link android.media.AudioTrack#write(byte[], int, int)}. */ /** The value returned from {@link android.media.AudioTrack#write(byte[], int, int)}. */
public final int errorCode; public final int errorCode;
...@@ -84,6 +84,18 @@ public final class AudioTrack { ...@@ -84,6 +84,18 @@ public final class AudioTrack {
} }
/**
* Thrown when {@link android.media.AudioTrack#getTimestamp} returns a spurious timestamp, if
* {@code AudioTrack#failOnSpuriousAudioTimestamp} is set.
*/
private static final class InvalidAudioTrackTimestampException extends RuntimeException {
public InvalidAudioTrackTimestampException(String message) {
super(message);
}
}
/** Returned in the result of {@link #handleBuffer} if the buffer was discontinuous. */ /** Returned in the result of {@link #handleBuffer} if the buffer was discontinuous. */
public static final int RESULT_POSITION_DISCONTINUITY = 1; public static final int RESULT_POSITION_DISCONTINUITY = 1;
/** Returned in the result of {@link #handleBuffer} if the buffer can be released. */ /** Returned in the result of {@link #handleBuffer} if the buffer can be released. */
...@@ -134,12 +146,22 @@ public final class AudioTrack { ...@@ -134,12 +146,22 @@ public final class AudioTrack {
private static final int MIN_TIMESTAMP_SAMPLE_INTERVAL_US = 500000; private static final int MIN_TIMESTAMP_SAMPLE_INTERVAL_US = 500000;
/** /**
* Set to {@code true} to enable a workaround for an issue where an audio effect does not keep its * Whether to enable a workaround for an issue where an audio effect does not keep its session
* session active across releasing/initializing a new audio track, on platform API version < 21. * active across releasing/initializing a new audio track, on platform API version < 21.
* The flag must be set before creating the player. * <p>
* The flag must be set before creating a player.
*/ */
public static boolean enablePreV21AudioSessionWorkaround = false; public static boolean enablePreV21AudioSessionWorkaround = false;
/**
* Whether to throw an {@link InvalidAudioTrackTimestampException} when a spurious timestamp is
* reported from {@link android.media.AudioTrack#getTimestamp}.
* <p>
* The flag must be set before creating a player. Should be set to {@code true} for testing and
* debugging purposes only.
*/
public static boolean failOnSpuriousAudioTimestamp = false;
private final ConditionVariable releasingConditionVariable; private final ConditionVariable releasingConditionVariable;
private final long[] playheadOffsets; private final long[] playheadOffsets;
private final AudioTrackUtil audioTrackUtil; private final AudioTrackUtil audioTrackUtil;
...@@ -626,7 +648,9 @@ public final class AudioTrack { ...@@ -626,7 +648,9 @@ public final class AudioTrack {
return isInitialized() && startMediaTimeState != START_NOT_SET; return isInitialized() && startMediaTimeState != START_NOT_SET;
} }
/** Updates the audio track latency and playback position parameters. */ /**
* Updates the audio track latency and playback position parameters.
*/
private void maybeSampleSyncParams() { private void maybeSampleSyncParams() {
long playbackPositionUs = audioTrackUtil.getPlaybackHeadPositionUs(); long playbackPositionUs = audioTrackUtil.getPlaybackHeadPositionUs();
if (playbackPositionUs == 0) { if (playbackPositionUs == 0) {
...@@ -661,17 +685,25 @@ public final class AudioTrack { ...@@ -661,17 +685,25 @@ public final class AudioTrack {
audioTimestampSet = false; audioTimestampSet = false;
} else if (Math.abs(audioTimestampUs - systemClockUs) > MAX_AUDIO_TIMESTAMP_OFFSET_US) { } else if (Math.abs(audioTimestampUs - systemClockUs) > MAX_AUDIO_TIMESTAMP_OFFSET_US) {
// The timestamp time base is probably wrong. // The timestamp time base is probably wrong.
audioTimestampSet = false; String message = "Spurious audio timestamp (system clock mismatch): "
Log.w(TAG, "Spurious audio timestamp (system clock mismatch): "
+ audioTimestampFramePosition + ", " + audioTimestampUs + ", " + systemClockUs + ", " + audioTimestampFramePosition + ", " + audioTimestampUs + ", " + systemClockUs + ", "
+ playbackPositionUs); + playbackPositionUs;
if (failOnSpuriousAudioTimestamp) {
throw new InvalidAudioTrackTimestampException(message);
}
Log.w(TAG, message);
audioTimestampSet = false;
} else if (Math.abs(framesToDurationUs(audioTimestampFramePosition) - playbackPositionUs) } else if (Math.abs(framesToDurationUs(audioTimestampFramePosition) - playbackPositionUs)
> MAX_AUDIO_TIMESTAMP_OFFSET_US) { > MAX_AUDIO_TIMESTAMP_OFFSET_US) {
// The timestamp frame position is probably wrong. // The timestamp frame position is probably wrong.
audioTimestampSet = false; String message = "Spurious audio timestamp (frame position mismatch): "
Log.w(TAG, "Spurious audio timestamp (frame position mismatch): "
+ audioTimestampFramePosition + ", " + audioTimestampUs + ", " + systemClockUs + ", " + audioTimestampFramePosition + ", " + audioTimestampUs + ", " + systemClockUs + ", "
+ playbackPositionUs); + playbackPositionUs;
if (failOnSpuriousAudioTimestamp) {
throw new InvalidAudioTrackTimestampException(message);
}
Log.w(TAG, message);
audioTimestampSet = false;
} }
} }
if (getLatencyMethod != null) { if (getLatencyMethod != null) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment