mirror of
https://github.com/androidx/media.git
synced 2025-05-04 06:00:37 +08:00
Add missing AudioSink discontinuity for stream changes.
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
This commit is contained in:
parent
a083c29f7e
commit
21c5b0bf67
@ -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)),
|
||||
|
@ -215,9 +215,7 @@ public interface AudioSink {
|
||||
*/
|
||||
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();
|
||||
|
||||
/**
|
||||
|
@ -642,9 +642,10 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import android.media.MediaFormat;
|
||||
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;
|
||||
@ -68,9 +69,19 @@ import java.util.List;
|
||||
@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;
|
||||
@ -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.
|
||||
@ -241,6 +254,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
/* 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());
|
||||
}
|
||||
@ -469,6 +484,22 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
@ -476,6 +507,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
currentPositionUs = positionUs;
|
||||
allowFirstBufferPositionDiscontinuity = true;
|
||||
allowPositionDiscontinuity = true;
|
||||
lastInputTimeUs = C.TIME_UNSET;
|
||||
pendingStreamChangeCount = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -494,6 +527,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
@Override
|
||||
protected void onDisabled() {
|
||||
try {
|
||||
lastInputTimeUs = C.TIME_UNSET;
|
||||
pendingStreamChangeCount = 0;
|
||||
audioSink.release();
|
||||
} finally {
|
||||
try {
|
||||
@ -544,6 +579,22 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
}
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user