From c7635c9dbd4f89fc469819955bf776d780c225cb Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Fri, 26 Jun 2015 14:29:45 +0100 Subject: [PATCH] Add some audio hooks. This makes it easier to add an extension for adjusting audio playback rate. --- .../exoplayer/MediaCodecAudioTrackRenderer.java | 9 +++++++-- .../android/exoplayer/audio/AudioTrack.java | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java index a28240477d..c9b44b7d43 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java @@ -68,7 +68,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem private static final String RAW_DECODER_NAME = "OMX.google.raw.decoder"; private final EventListener eventListener; - private final AudioTrack audioTrack; + protected final AudioTrack audioTrack; private int audioSessionId; private long currentPositionUs; @@ -294,6 +294,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem // If we are out of sync, allow currentPositionUs to jump backwards. if ((handleBufferResult & AudioTrack.RESULT_POSITION_DISCONTINUITY) != 0) { + handleDiscontinuity(); allowPositionDiscontinuity = true; } @@ -307,6 +308,10 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem return false; } + protected void handleDiscontinuity() { + // Do nothing + } + @Override public void handleMessage(int messageType, Object message) throws ExoPlaybackException { if (messageType == MSG_SET_VOLUME) { @@ -318,7 +323,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem private void notifyAudioTrackInitializationError(final AudioTrack.InitializationException e) { if (eventHandler != null && eventListener != null) { - eventHandler.post(new Runnable() { + eventHandler.post(new Runnable() { @Override public void run() { eventListener.onAudioTrackInitializationError(e); diff --git a/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java b/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java index 1931e34e01..29d3d0c876 100644 --- a/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java +++ b/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java @@ -145,6 +145,8 @@ public final class AudioTrack { private static final int MIN_PLAYHEAD_OFFSET_SAMPLE_INTERVAL_US = 30000; private static final int MIN_TIMESTAMP_SAMPLE_INTERVAL_US = 500000; + private static final int DEFAULT_TIMESCALE_PERCENT = 100; + /** * Whether to enable a workaround for an issue where an audio effect does not keep its session * active across releasing/initializing a new audio track, on platform API version < 21. @@ -191,6 +193,7 @@ public final class AudioTrack { private long resumeSystemTimeUs; private long latencyUs; private float volume; + private int timeScalePercent; private byte[] temporaryBuffer; private int temporaryBufferOffset; @@ -218,6 +221,7 @@ public final class AudioTrack { } playheadOffsets = new long[MAX_PLAYHEAD_OFFSET_COUNT]; volume = 1.0f; + timeScalePercent = DEFAULT_TIMESCALE_PERCENT; startMediaTimeState = START_NOT_SET; } @@ -477,7 +481,7 @@ public final class AudioTrack { } else { // Sanity check that bufferStartTime is consistent with the expected value. long expectedBufferStartTime = startMediaTimeUs - + framesToDurationUs(bytesToFrames(submittedBytes)); + + (framesToDurationUs(bytesToFrames(submittedBytes)) * timeScalePercent) / 100; if (startMediaTimeState == START_IN_SYNC && Math.abs(expectedBufferStartTime - bufferStartTime) > 200000) { Log.e(TAG, "Discontinuity detected [expected " + expectedBufferStartTime + ", got " @@ -586,6 +590,15 @@ public final class AudioTrack { } } + /** + * Updates the timescale percent for reporting current time + * + * @param timeScalePercent The new percent multiplier + */ + public void setTimeScalePercent(int timeScalePercent) { + this.timeScalePercent = timeScalePercent; + } + /** * Releases the underlying audio track asynchronously. Calling {@link #initialize} will block * until the audio track has been released, so it is safe to initialize immediately after