Skip to content

Commit

Permalink
Add missing AudioSink discontinuity for stream changes.
Browse files Browse the repository at this point in the history
When the stream is changed in the audio renderer, the timestamps of the
samples can no longer be expected to match the calculations in the AudioSink.

This change tracks the samples at which the stream is changed and notifies the
AudioSink of the discontinuity.

Issue:#4559
Issue:#3829

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=212435859
  • Loading branch information
tonihei authored and ojw28 committed Sep 12, 2018
1 parent a083c29 commit 21c5b0b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 5 deletions.
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@
([#4661](https://github.com/google/ExoPlayer/issues/4661)).
* Allow edit lists which do not start with a sync sample.
([#4774](https://github.com/google/ExoPlayer/issues/4774)).
* Fix issue with audio discontinuities at period transitions, e.g. when
looping ([#3829](https://github.com/google/ExoPlayer/issues/3829)).
* IMA extension:
* Refine the previous fix for empty ad groups to avoid discarding ad breaks
unnecessarily ([#4030](https://github.com/google/ExoPlayer/issues/4030)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,7 @@ void configure(
*/
void play();

/**
* Signals to the sink that the next buffer is discontinuous with the previous buffer.
*/
/** Signals to the sink that the next buffer may be discontinuous with the previous buffer. */
void handleDiscontinuity();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -642,9 +642,10 @@ public boolean handleBuffer(ByteBuffer buffer, long presentationTimeUs)
if (startMediaTimeState == START_NEED_SYNC) {
// Adjust startMediaTimeUs to be consistent with the current buffer's start time and the
// number of bytes submitted.
startMediaTimeUs += (presentationTimeUs - expectedPresentationTimeUs);
long adjustmentUs = presentationTimeUs - expectedPresentationTimeUs;
startMediaTimeUs += adjustmentUs;
startMediaTimeState = START_IN_SYNC;
if (listener != null) {
if (listener != null && adjustmentUs != 0) {
listener.onPositionDiscontinuity();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import android.media.audiofx.Virtualizer;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.Log;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
Expand Down Expand Up @@ -68,9 +69,19 @@
@TargetApi(16)
public class MediaCodecAudioRenderer extends MediaCodecRenderer implements MediaClock {

/**
* Maximum number of tracked pending stream change times. Generally there is zero or one pending
* stream change. We track more to allow for pending changes that have fewer samples than the
* codec latency.
*/
private static final int MAX_PENDING_STREAM_CHANGE_COUNT = 10;

private static final String TAG = "MediaCodecAudioRenderer";

private final Context context;
private final EventDispatcher eventDispatcher;
private final AudioSink audioSink;
private final long[] pendingStreamChangeTimesUs;

private int codecMaxInputSize;
private boolean passthroughEnabled;
Expand All @@ -83,6 +94,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
private long currentPositionUs;
private boolean allowFirstBufferPositionDiscontinuity;
private boolean allowPositionDiscontinuity;
private long lastInputTimeUs;
private int pendingStreamChangeCount;

/**
* @param context A context.
Expand Down Expand Up @@ -241,6 +254,8 @@ public MediaCodecAudioRenderer(
/* assumedMinimumCodecOperatingRate= */ 44100);
this.context = context.getApplicationContext();
this.audioSink = audioSink;
lastInputTimeUs = C.TIME_UNSET;
pendingStreamChangeTimesUs = new long[MAX_PENDING_STREAM_CHANGE_COUNT];
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
audioSink.setListener(new AudioSinkListener());
}
Expand Down Expand Up @@ -469,13 +484,31 @@ protected void onEnabled(boolean joining) throws ExoPlaybackException {
}
}

@Override
protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException {
super.onStreamChanged(formats, offsetUs);
if (lastInputTimeUs != C.TIME_UNSET) {
if (pendingStreamChangeCount == pendingStreamChangeTimesUs.length) {
Log.w(
TAG,
"Too many stream changes, so dropping change at "
+ pendingStreamChangeTimesUs[pendingStreamChangeCount - 1]);
} else {
pendingStreamChangeCount++;
}
pendingStreamChangeTimesUs[pendingStreamChangeCount - 1] = lastInputTimeUs;
}
}

@Override
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
super.onPositionReset(positionUs, joining);
audioSink.reset();
currentPositionUs = positionUs;
allowFirstBufferPositionDiscontinuity = true;
allowPositionDiscontinuity = true;
lastInputTimeUs = C.TIME_UNSET;
pendingStreamChangeCount = 0;
}

@Override
Expand All @@ -494,6 +527,8 @@ protected void onStopped() {
@Override
protected void onDisabled() {
try {
lastInputTimeUs = C.TIME_UNSET;
pendingStreamChangeCount = 0;
audioSink.release();
} finally {
try {
Expand Down Expand Up @@ -544,6 +579,22 @@ protected void onQueueInputBuffer(DecoderInputBuffer buffer) {
}
allowFirstBufferPositionDiscontinuity = false;
}
lastInputTimeUs = Math.max(buffer.timeUs, lastInputTimeUs);
}

@Override
protected void onProcessedOutputBuffer(long presentationTimeUs) {
super.onProcessedOutputBuffer(presentationTimeUs);
while (pendingStreamChangeCount != 0 && presentationTimeUs >= pendingStreamChangeTimesUs[0]) {
audioSink.handleDiscontinuity();
pendingStreamChangeCount--;
System.arraycopy(
pendingStreamChangeTimesUs,
/* srcPos= */ 1,
pendingStreamChangeTimesUs,
/* destPos= */ 0,
pendingStreamChangeCount);
}
}

@Override
Expand Down

0 comments on commit 21c5b0b

Please sign in to comment.