Commit d909dc18 by olly Committed by Oliver Woodman

Report correct discontinuity from ClippingMediaPeriod

It currently always reports 0, but it should report the position
passed through selectTracks. Reporting should also be disabled if
there's a seekToUs call.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=176644228
parent b5480e0e
...@@ -36,10 +36,10 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -36,10 +36,10 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
public final MediaPeriod mediaPeriod; public final MediaPeriod mediaPeriod;
private MediaPeriod.Callback callback; private MediaPeriod.Callback callback;
private long startUs;
private long endUs;
private ClippingSampleStream[] sampleStreams; private ClippingSampleStream[] sampleStreams;
private boolean pendingInitialDiscontinuity; private long pendingInitialDiscontinuityPositionUs;
/* package */ long startUs;
/* package */ long endUs;
/** /**
* Creates a new clipping media period that provides a clipped view of the specified * Creates a new clipping media period that provides a clipped view of the specified
...@@ -57,10 +57,10 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -57,10 +57,10 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
*/ */
public ClippingMediaPeriod(MediaPeriod mediaPeriod, boolean enableInitialDiscontinuity) { public ClippingMediaPeriod(MediaPeriod mediaPeriod, boolean enableInitialDiscontinuity) {
this.mediaPeriod = mediaPeriod; this.mediaPeriod = mediaPeriod;
sampleStreams = new ClippingSampleStream[0];
pendingInitialDiscontinuityPositionUs = enableInitialDiscontinuity ? 0 : C.TIME_UNSET;
startUs = C.TIME_UNSET; startUs = C.TIME_UNSET;
endUs = C.TIME_UNSET; endUs = C.TIME_UNSET;
sampleStreams = new ClippingSampleStream[0];
pendingInitialDiscontinuity = enableInitialDiscontinuity;
} }
/** /**
...@@ -95,29 +95,27 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -95,29 +95,27 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags, public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) { SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
sampleStreams = new ClippingSampleStream[streams.length]; sampleStreams = new ClippingSampleStream[streams.length];
SampleStream[] internalStreams = new SampleStream[streams.length]; SampleStream[] childStreams = new SampleStream[streams.length];
for (int i = 0; i < streams.length; i++) { for (int i = 0; i < streams.length; i++) {
sampleStreams[i] = (ClippingSampleStream) streams[i]; sampleStreams[i] = (ClippingSampleStream) streams[i];
internalStreams[i] = sampleStreams[i] != null ? sampleStreams[i].stream : null; childStreams[i] = sampleStreams[i] != null ? sampleStreams[i].childStream : null;
} }
long enablePositionUs = mediaPeriod.selectTracks(selections, mayRetainStreamFlags, long enablePositionUs = mediaPeriod.selectTracks(selections, mayRetainStreamFlags,
internalStreams, streamResetFlags, positionUs + startUs); childStreams, streamResetFlags, positionUs + startUs) - startUs;
if (pendingInitialDiscontinuity) { pendingInitialDiscontinuityPositionUs = isPendingInitialDiscontinuity() && positionUs == 0
pendingInitialDiscontinuity = startUs != 0 && shouldKeepInitialDiscontinuity(selections); && shouldKeepInitialDiscontinuity(startUs, selections) ? enablePositionUs : C.TIME_UNSET;
} Assertions.checkState(enablePositionUs == positionUs
Assertions.checkState(enablePositionUs == positionUs + startUs || (enablePositionUs >= 0
|| (enablePositionUs >= startUs && (endUs == C.TIME_END_OF_SOURCE || startUs + enablePositionUs <= endUs)));
&& (endUs == C.TIME_END_OF_SOURCE || enablePositionUs <= endUs)));
for (int i = 0; i < streams.length; i++) { for (int i = 0; i < streams.length; i++) {
if (internalStreams[i] == null) { if (childStreams[i] == null) {
sampleStreams[i] = null; sampleStreams[i] = null;
} else if (streams[i] == null || sampleStreams[i].stream != internalStreams[i]) { } else if (streams[i] == null || sampleStreams[i].childStream != childStreams[i]) {
sampleStreams[i] = new ClippingSampleStream(this, internalStreams[i], startUs, endUs, sampleStreams[i] = new ClippingSampleStream(childStreams[i]);
pendingInitialDiscontinuity);
} }
streams[i] = sampleStreams[i]; streams[i] = sampleStreams[i];
} }
return enablePositionUs - startUs; return enablePositionUs;
} }
@Override @Override
...@@ -127,16 +125,12 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -127,16 +125,12 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
@Override @Override
public long readDiscontinuity() { public long readDiscontinuity() {
if (pendingInitialDiscontinuity) { if (isPendingInitialDiscontinuity()) {
for (ClippingSampleStream sampleStream : sampleStreams) { long initialDiscontinuityUs = pendingInitialDiscontinuityPositionUs;
if (sampleStream != null) { pendingInitialDiscontinuityPositionUs = C.TIME_UNSET;
sampleStream.clearPendingDiscontinuity(); // Always read an initial discontinuity from the child, and use it if set.
} long childDiscontinuityUs = readDiscontinuity();
} return childDiscontinuityUs != C.TIME_UNSET ? childDiscontinuityUs : initialDiscontinuityUs;
pendingInitialDiscontinuity = false;
// Always read an initial discontinuity, using mediaPeriod's discontinuity if set.
long discontinuityUs = readDiscontinuity();
return discontinuityUs != C.TIME_UNSET ? discontinuityUs : 0;
} }
long discontinuityUs = mediaPeriod.readDiscontinuity(); long discontinuityUs = mediaPeriod.readDiscontinuity();
if (discontinuityUs == C.TIME_UNSET) { if (discontinuityUs == C.TIME_UNSET) {
...@@ -159,6 +153,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -159,6 +153,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
@Override @Override
public long seekToUs(long positionUs) { public long seekToUs(long positionUs) {
pendingInitialDiscontinuityPositionUs = C.TIME_UNSET;
for (ClippingSampleStream sampleStream : sampleStreams) { for (ClippingSampleStream sampleStream : sampleStreams) {
if (sampleStream != null) { if (sampleStream != null) {
sampleStream.clearSentEos(); sampleStream.clearSentEos();
...@@ -198,7 +193,11 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -198,7 +193,11 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
callback.onContinueLoadingRequested(this); callback.onContinueLoadingRequested(this);
} }
private static boolean shouldKeepInitialDiscontinuity(TrackSelection[] selections) { /* package */ boolean isPendingInitialDiscontinuity() {
return pendingInitialDiscontinuityPositionUs != C.TIME_UNSET;
}
private static boolean shouldKeepInitialDiscontinuity(long startUs, TrackSelection[] selections) {
// If the clipping start position is non-zero, the clipping sample streams will adjust // If the clipping start position is non-zero, the clipping sample streams will adjust
// timestamps on buffers they read from the unclipped sample streams. These adjusted buffer // timestamps on buffers they read from the unclipped sample streams. These adjusted buffer
// timestamps can be negative, because sample streams provide buffers starting at a key-frame, // timestamps can be negative, because sample streams provide buffers starting at a key-frame,
...@@ -208,11 +207,13 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -208,11 +207,13 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
// discontinuity which resets the renderers before they read the clipping sample stream. // discontinuity which resets the renderers before they read the clipping sample stream.
// However, for audio-only track selections we assume to have random access seek behaviour and // However, for audio-only track selections we assume to have random access seek behaviour and
// do not need an initial discontinuity to reset the renderer. // do not need an initial discontinuity to reset the renderer.
for (TrackSelection trackSelection : selections) { if (startUs != 0) {
if (trackSelection != null) { for (TrackSelection trackSelection : selections) {
Format selectedFormat = trackSelection.getSelectedFormat(); if (trackSelection != null) {
if (!MimeTypes.isAudio(selectedFormat.sampleMimeType)) { Format selectedFormat = trackSelection.getSelectedFormat();
return true; if (!MimeTypes.isAudio(selectedFormat.sampleMimeType)) {
return true;
}
} }
} }
} }
...@@ -222,27 +223,14 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -222,27 +223,14 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
/** /**
* Wraps a {@link SampleStream} and clips its samples. * Wraps a {@link SampleStream} and clips its samples.
*/ */
private static final class ClippingSampleStream implements SampleStream { private final class ClippingSampleStream implements SampleStream {
private final MediaPeriod mediaPeriod; public final SampleStream childStream;
private final SampleStream stream;
private final long startUs;
private final long endUs;
private boolean pendingDiscontinuity;
private boolean sentEos; private boolean sentEos;
public ClippingSampleStream(MediaPeriod mediaPeriod, SampleStream stream, long startUs, public ClippingSampleStream(SampleStream childStream) {
long endUs, boolean pendingDiscontinuity) { this.childStream = childStream;
this.mediaPeriod = mediaPeriod;
this.stream = stream;
this.startUs = startUs;
this.endUs = endUs;
this.pendingDiscontinuity = pendingDiscontinuity;
}
public void clearPendingDiscontinuity() {
pendingDiscontinuity = false;
} }
public void clearSentEos() { public void clearSentEos() {
...@@ -251,25 +239,25 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -251,25 +239,25 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
@Override @Override
public boolean isReady() { public boolean isReady() {
return stream.isReady(); return !isPendingInitialDiscontinuity() && childStream.isReady();
} }
@Override @Override
public void maybeThrowError() throws IOException { public void maybeThrowError() throws IOException {
stream.maybeThrowError(); childStream.maybeThrowError();
} }
@Override @Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
boolean requireFormat) { boolean requireFormat) {
if (pendingDiscontinuity) { if (isPendingInitialDiscontinuity()) {
return C.RESULT_NOTHING_READ; return C.RESULT_NOTHING_READ;
} }
if (sentEos) { if (sentEos) {
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM); buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
return C.RESULT_BUFFER_READ; return C.RESULT_BUFFER_READ;
} }
int result = stream.readData(formatHolder, buffer, requireFormat); int result = childStream.readData(formatHolder, buffer, requireFormat);
if (result == C.RESULT_FORMAT_READ) { if (result == C.RESULT_FORMAT_READ) {
// Clear gapless playback metadata if the start/end points don't match the media. // Clear gapless playback metadata if the start/end points don't match the media.
Format format = formatHolder.format; Format format = formatHolder.format;
...@@ -294,7 +282,10 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -294,7 +282,10 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
@Override @Override
public int skipData(long positionUs) { public int skipData(long positionUs) {
return stream.skipData(startUs + positionUs); if (isPendingInitialDiscontinuity()) {
return C.RESULT_NOTHING_READ;
}
return childStream.skipData(startUs + positionUs);
} }
} }
......
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