mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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
This commit is contained in:
parent
b5480e0e97
commit
d909dc1863
1 changed files with 48 additions and 57 deletions
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
@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
|
||||||
|
|
||||||
@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
|
||||||
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
|
||||||
// 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
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
|
||||||
@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
|
||||||
|
|
||||||
@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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue