mirror of
https://github.com/androidx/media.git
synced 2025-05-06 15:10:34 +08:00
Constant simplification.
- Use same constant for unknown/unset microsecond times/durations. - Change constant values to be nowhere near the "normal" range. - Misc cleanup. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=119944019
This commit is contained in:
parent
28e926602f
commit
c99250d9c5
@ -57,7 +57,7 @@ public final class XingSeekerTest extends InstrumentationTestCase {
|
|||||||
MpegAudioHeader xingFrameHeader = new MpegAudioHeader();
|
MpegAudioHeader xingFrameHeader = new MpegAudioHeader();
|
||||||
MpegAudioHeader.populateHeader(XING_FRAME_HEADER_DATA, xingFrameHeader);
|
MpegAudioHeader.populateHeader(XING_FRAME_HEADER_DATA, xingFrameHeader);
|
||||||
seeker = XingSeeker.create(xingFrameHeader, new ParsableByteArray(XING_FRAME_PAYLOAD),
|
seeker = XingSeeker.create(xingFrameHeader, new ParsableByteArray(XING_FRAME_PAYLOAD),
|
||||||
XING_FRAME_POSITION, C.UNKNOWN_TIME_US);
|
XING_FRAME_POSITION, C.LENGTH_UNBOUNDED);
|
||||||
seekerWithInputLength = XingSeeker.create(xingFrameHeader,
|
seekerWithInputLength = XingSeeker.create(xingFrameHeader,
|
||||||
new ParsableByteArray(XING_FRAME_PAYLOAD), XING_FRAME_POSITION, INPUT_LENGTH);
|
new ParsableByteArray(XING_FRAME_PAYLOAD), XING_FRAME_POSITION, INPUT_LENGTH);
|
||||||
xingFrameSize = xingFrameHeader.frameSize;
|
xingFrameSize = xingFrameHeader.frameSize;
|
||||||
|
@ -25,15 +25,15 @@ import android.media.MediaCodec;
|
|||||||
*/
|
*/
|
||||||
public final class C {
|
public final class C {
|
||||||
|
|
||||||
/**
|
|
||||||
* Special microsecond constant representing an unknown time or duration.
|
|
||||||
*/
|
|
||||||
public static final long UNKNOWN_TIME_US = -1L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special microsecond constant representing the end of a source.
|
* Special microsecond constant representing the end of a source.
|
||||||
*/
|
*/
|
||||||
public static final long END_OF_SOURCE_US = -2L;
|
public static final long END_OF_SOURCE_US = Long.MIN_VALUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special microsecond constant representing an unset or unknown time or duration.
|
||||||
|
*/
|
||||||
|
public static final long UNSET_TIME_US = Long.MIN_VALUE + 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of microseconds in one second.
|
* The number of microseconds in one second.
|
||||||
|
@ -187,12 +187,12 @@ public final class DefaultLoadControl implements LoadControl {
|
|||||||
updateControlState();
|
updateControlState();
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentBufferSize < targetBufferSize && nextLoadPositionUs != -1
|
return currentBufferSize < targetBufferSize && nextLoadPositionUs != C.UNSET_TIME_US
|
||||||
&& nextLoadPositionUs <= maxLoadStartPositionUs;
|
&& nextLoadPositionUs <= maxLoadStartPositionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getLoaderBufferState(long playbackPositionUs, long nextLoadPositionUs) {
|
private int getLoaderBufferState(long playbackPositionUs, long nextLoadPositionUs) {
|
||||||
if (nextLoadPositionUs == -1) {
|
if (nextLoadPositionUs == C.UNSET_TIME_US) {
|
||||||
return ABOVE_HIGH_WATERMARK;
|
return ABOVE_HIGH_WATERMARK;
|
||||||
} else {
|
} else {
|
||||||
long timeUntilNextLoadPosition = nextLoadPositionUs - playbackPositionUs;
|
long timeUntilNextLoadPosition = nextLoadPositionUs - playbackPositionUs;
|
||||||
@ -216,7 +216,7 @@ public final class DefaultLoadControl implements LoadControl {
|
|||||||
for (int i = 0; i < loaders.size(); i++) {
|
for (int i = 0; i < loaders.size(); i++) {
|
||||||
LoaderState loaderState = loaderStates.get(loaders.get(i));
|
LoaderState loaderState = loaderStates.get(loaders.get(i));
|
||||||
loading |= loaderState.loading;
|
loading |= loaderState.loading;
|
||||||
haveNextLoadPosition |= loaderState.nextLoadPositionUs != -1;
|
haveNextLoadPosition |= loaderState.nextLoadPositionUs != C.UNSET_TIME_US;
|
||||||
highestState = Math.max(highestState, loaderState.bufferState);
|
highestState = Math.max(highestState, loaderState.bufferState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,14 +233,14 @@ public final class DefaultLoadControl implements LoadControl {
|
|||||||
notifyLoadingChanged(false);
|
notifyLoadingChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxLoadStartPositionUs = -1;
|
maxLoadStartPositionUs = C.UNSET_TIME_US;
|
||||||
if (fillingBuffers) {
|
if (fillingBuffers) {
|
||||||
for (int i = 0; i < loaders.size(); i++) {
|
for (int i = 0; i < loaders.size(); i++) {
|
||||||
Object loader = loaders.get(i);
|
Object loader = loaders.get(i);
|
||||||
LoaderState loaderState = loaderStates.get(loader);
|
LoaderState loaderState = loaderStates.get(loader);
|
||||||
long loaderTime = loaderState.nextLoadPositionUs;
|
long loaderTime = loaderState.nextLoadPositionUs;
|
||||||
if (loaderTime != -1
|
if (loaderTime != C.UNSET_TIME_US
|
||||||
&& (maxLoadStartPositionUs == -1 || loaderTime < maxLoadStartPositionUs)) {
|
&& (maxLoadStartPositionUs == C.UNSET_TIME_US || loaderTime < maxLoadStartPositionUs)) {
|
||||||
maxLoadStartPositionUs = loaderTime;
|
maxLoadStartPositionUs = loaderTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +270,7 @@ public final class DefaultLoadControl implements LoadControl {
|
|||||||
this.bufferSizeContribution = bufferSizeContribution;
|
this.bufferSizeContribution = bufferSizeContribution;
|
||||||
bufferState = ABOVE_HIGH_WATERMARK;
|
bufferState = ABOVE_HIGH_WATERMARK;
|
||||||
loading = false;
|
loading = false;
|
||||||
nextLoadPositionUs = -1;
|
nextLoadPositionUs = C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -100,8 +100,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
this.playWhenReady = playWhenReady;
|
this.playWhenReady = playWhenReady;
|
||||||
this.eventHandler = eventHandler;
|
this.eventHandler = eventHandler;
|
||||||
this.state = ExoPlayer.STATE_IDLE;
|
this.state = ExoPlayer.STATE_IDLE;
|
||||||
this.durationUs = C.UNKNOWN_TIME_US;
|
this.durationUs = C.UNSET_TIME_US;
|
||||||
this.bufferedPositionUs = C.UNKNOWN_TIME_US;
|
this.bufferedPositionUs = C.UNSET_TIME_US;
|
||||||
|
|
||||||
for (int i = 0; i < renderers.length; i++) {
|
for (int i = 0; i < renderers.length; i++) {
|
||||||
renderers[i].setIndex(i);
|
renderers[i].setIndex(i);
|
||||||
@ -131,13 +131,13 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
public long getBufferedPosition() {
|
public long getBufferedPosition() {
|
||||||
long bufferedPositionUs = this.bufferedPositionUs;
|
long bufferedPositionUs = this.bufferedPositionUs;
|
||||||
return bufferedPositionUs == C.UNKNOWN_TIME_US ? ExoPlayer.UNKNOWN_TIME
|
return bufferedPositionUs == C.UNSET_TIME_US ? ExoPlayer.UNKNOWN_TIME
|
||||||
: bufferedPositionUs / 1000;
|
: bufferedPositionUs / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDuration() {
|
public long getDuration() {
|
||||||
long durationUs = this.durationUs;
|
long durationUs = this.durationUs;
|
||||||
return durationUs == C.UNKNOWN_TIME_US ? ExoPlayer.UNKNOWN_TIME : durationUs / 1000;
|
return durationUs == C.UNSET_TIME_US ? ExoPlayer.UNKNOWN_TIME : durationUs / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSource(SampleSource sampleSource) {
|
public void setSource(SampleSource sampleSource) {
|
||||||
@ -273,10 +273,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
private boolean haveSufficientBuffer() {
|
private boolean haveSufficientBuffer() {
|
||||||
long minBufferDurationUs = rebuffering ? minRebufferUs : minBufferUs;
|
long minBufferDurationUs = rebuffering ? minRebufferUs : minBufferUs;
|
||||||
return minBufferDurationUs <= 0
|
return minBufferDurationUs <= 0
|
||||||
|| bufferedPositionUs == C.UNKNOWN_TIME_US
|
|| bufferedPositionUs == C.UNSET_TIME_US
|
||||||
|| bufferedPositionUs == C.END_OF_SOURCE_US
|
|| bufferedPositionUs == C.END_OF_SOURCE_US
|
||||||
|| bufferedPositionUs >= positionUs + minBufferDurationUs
|
|| bufferedPositionUs >= positionUs + minBufferDurationUs
|
||||||
|| (durationUs != C.UNKNOWN_TIME_US && bufferedPositionUs >= durationUs);
|
|| (durationUs != C.UNSET_TIME_US && bufferedPositionUs >= durationUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSourceInternal(SampleSource source) {
|
private void setSourceInternal(SampleSource source) {
|
||||||
@ -336,7 +336,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
long sourceBufferedPositionUs = enabledRenderers.length > 0 ? source.getBufferedPositionUs()
|
long sourceBufferedPositionUs = enabledRenderers.length > 0 ? source.getBufferedPositionUs()
|
||||||
: C.END_OF_SOURCE_US;
|
: C.END_OF_SOURCE_US;
|
||||||
bufferedPositionUs = sourceBufferedPositionUs == C.END_OF_SOURCE_US
|
bufferedPositionUs = sourceBufferedPositionUs == C.END_OF_SOURCE_US
|
||||||
&& durationUs != C.UNKNOWN_TIME_US ? durationUs : sourceBufferedPositionUs;
|
&& durationUs != C.UNSET_TIME_US ? durationUs : sourceBufferedPositionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doSomeWork() throws ExoPlaybackException, IOException {
|
private void doSomeWork() throws ExoPlaybackException, IOException {
|
||||||
@ -384,7 +384,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
allRenderersReadyOrEnded = allRenderersReadyOrEnded && rendererReadyOrEnded;
|
allRenderersReadyOrEnded = allRenderersReadyOrEnded && rendererReadyOrEnded;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allRenderersEnded && (durationUs == C.UNKNOWN_TIME_US || durationUs <= positionUs)) {
|
if (allRenderersEnded && (durationUs == C.UNSET_TIME_US || durationUs <= positionUs)) {
|
||||||
setState(ExoPlayer.STATE_ENDED);
|
setState(ExoPlayer.STATE_ENDED);
|
||||||
stopRenderers();
|
stopRenderers();
|
||||||
} else if (state == ExoPlayer.STATE_BUFFERING && allRenderersReadyOrEnded
|
} else if (state == ExoPlayer.STATE_BUFFERING && allRenderersReadyOrEnded
|
||||||
@ -460,7 +460,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateBufferedPositionUs();
|
updateBufferedPositionUs();
|
||||||
if (allRenderersEnded && (durationUs == C.UNKNOWN_TIME_US || durationUs <= positionUs)) {
|
if (allRenderersEnded && (durationUs == C.UNSET_TIME_US || durationUs <= positionUs)) {
|
||||||
setState(ExoPlayer.STATE_ENDED);
|
setState(ExoPlayer.STATE_ENDED);
|
||||||
} else {
|
} else {
|
||||||
setState(allRenderersReadyOrEnded && haveSufficientBuffer() ? ExoPlayer.STATE_READY
|
setState(allRenderersReadyOrEnded && haveSufficientBuffer() ? ExoPlayer.STATE_READY
|
||||||
|
@ -132,7 +132,7 @@ public final class FrameworkSampleSource implements SampleSource {
|
|||||||
} else {
|
} else {
|
||||||
extractor.setDataSource(fileDescriptor, fileDescriptorOffset, fileDescriptorLength);
|
extractor.setDataSource(fileDescriptor, fileDescriptorOffset, fileDescriptorLength);
|
||||||
}
|
}
|
||||||
durationUs = C.UNKNOWN_TIME_US;
|
durationUs = C.UNSET_TIME_US;
|
||||||
trackStates = new int[extractor.getTrackCount()];
|
trackStates = new int[extractor.getTrackCount()];
|
||||||
pendingResets = new boolean[trackStates.length];
|
pendingResets = new boolean[trackStates.length];
|
||||||
TrackGroup[] trackArray = new TrackGroup[trackStates.length];
|
TrackGroup[] trackArray = new TrackGroup[trackStates.length];
|
||||||
@ -150,7 +150,7 @@ public final class FrameworkSampleSource implements SampleSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDurationUs() {
|
public long getDurationUs() {
|
||||||
return C.UNKNOWN_TIME_US;
|
return C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -212,7 +212,7 @@ public final class FrameworkSampleSource implements SampleSource {
|
|||||||
|
|
||||||
long bufferedDurationUs = extractor.getCachedDuration();
|
long bufferedDurationUs = extractor.getCachedDuration();
|
||||||
if (bufferedDurationUs == -1) {
|
if (bufferedDurationUs == -1) {
|
||||||
return C.UNKNOWN_TIME_US;
|
return C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
long sampleTime = extractor.getSampleTime();
|
long sampleTime = extractor.getSampleTime();
|
||||||
@ -234,7 +234,7 @@ public final class FrameworkSampleSource implements SampleSource {
|
|||||||
pendingResets[track] = false;
|
pendingResets[track] = false;
|
||||||
return lastSeekPositionUs;
|
return lastSeekPositionUs;
|
||||||
}
|
}
|
||||||
return TrackStream.NO_RESET;
|
return C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ int readData(int track, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
/* package */ int readData(int track, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||||
@ -266,7 +266,7 @@ public final class FrameworkSampleSource implements SampleSource {
|
|||||||
buffer.addFlag(C.BUFFER_FLAG_ENCRYPTED);
|
buffer.addFlag(C.BUFFER_FLAG_ENCRYPTED);
|
||||||
buffer.cryptoInfo.setFromExtractorV16(extractor);
|
buffer.cryptoInfo.setFromExtractorV16(extractor);
|
||||||
}
|
}
|
||||||
pendingSeekPositionUs = C.UNKNOWN_TIME_US;
|
pendingSeekPositionUs = C.UNSET_TIME_US;
|
||||||
extractor.advance();
|
extractor.advance();
|
||||||
return TrackStream.BUFFER_READ;
|
return TrackStream.BUFFER_READ;
|
||||||
} else if (extractorTrackIndex < 0) {
|
} else if (extractorTrackIndex < 0) {
|
||||||
|
@ -65,8 +65,8 @@ public interface LoadControl {
|
|||||||
*
|
*
|
||||||
* @param loader The loader invoking the update.
|
* @param loader The loader invoking the update.
|
||||||
* @param playbackPositionUs The loader's playback position.
|
* @param playbackPositionUs The loader's playback position.
|
||||||
* @param nextLoadPositionUs The loader's next load position. -1 if finished, failed, or if the
|
* @param nextLoadPositionUs The loader's next load position. {@link C#UNSET_TIME_US} if finished,
|
||||||
* next load position is not yet known.
|
* failed, or if the next load position is not yet known.
|
||||||
* @param loading Whether the loader is currently loading data.
|
* @param loading Whether the loader is currently loading data.
|
||||||
* @return True if the loader is allowed to start its next load. False otherwise.
|
* @return True if the loader is allowed to start its next load. False otherwise.
|
||||||
*/
|
*/
|
||||||
|
@ -367,7 +367,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
|
|||||||
if (audioTrackHadData && !audioTrackHasData && getState() == TrackRenderer.STATE_STARTED) {
|
if (audioTrackHadData && !audioTrackHasData && getState() == TrackRenderer.STATE_STARTED) {
|
||||||
long elapsedSinceLastFeedMs = SystemClock.elapsedRealtime() - lastFeedElapsedRealtimeMs;
|
long elapsedSinceLastFeedMs = SystemClock.elapsedRealtime() - lastFeedElapsedRealtimeMs;
|
||||||
long bufferSizeUs = audioTrack.getBufferSizeUs();
|
long bufferSizeUs = audioTrack.getBufferSizeUs();
|
||||||
long bufferSizeMs = bufferSizeUs == C.UNKNOWN_TIME_US ? -1 : bufferSizeUs / 1000;
|
long bufferSizeMs = bufferSizeUs == C.UNSET_TIME_US ? -1 : bufferSizeUs / 1000;
|
||||||
notifyAudioTrackUnderrun(audioTrack.getBufferSize(), bufferSizeMs, elapsedSinceLastFeedMs);
|
notifyAudioTrackUnderrun(audioTrack.getBufferSize(), bufferSizeMs, elapsedSinceLastFeedMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
private boolean codecNeedsMonoChannelCountWorkaround;
|
private boolean codecNeedsMonoChannelCountWorkaround;
|
||||||
private ByteBuffer[] inputBuffers;
|
private ByteBuffer[] inputBuffers;
|
||||||
private ByteBuffer[] outputBuffers;
|
private ByteBuffer[] outputBuffers;
|
||||||
private long codecHotswapTimeMs;
|
private long codecHotswapDeadlineMs;
|
||||||
private int inputIndex;
|
private int inputIndex;
|
||||||
private int outputIndex;
|
private int outputIndex;
|
||||||
private boolean openedDrmSession;
|
private boolean openedDrmSession;
|
||||||
@ -366,8 +366,8 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
notifyAndThrowDecoderInitError(new DecoderInitializationException(format, e,
|
notifyAndThrowDecoderInitError(new DecoderInitializationException(format, e,
|
||||||
requiresSecureDecoder, codecName));
|
requiresSecureDecoder, codecName));
|
||||||
}
|
}
|
||||||
codecHotswapTimeMs = getState() == TrackRenderer.STATE_STARTED ?
|
codecHotswapDeadlineMs = getState() == TrackRenderer.STATE_STARTED
|
||||||
SystemClock.elapsedRealtime() : -1;
|
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS) : -1;
|
||||||
inputIndex = -1;
|
inputIndex = -1;
|
||||||
outputIndex = -1;
|
outputIndex = -1;
|
||||||
codecCounters.codecInitCount++;
|
codecCounters.codecInitCount++;
|
||||||
@ -411,7 +411,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
|
|
||||||
protected void releaseCodec() {
|
protected void releaseCodec() {
|
||||||
if (codec != null) {
|
if (codec != null) {
|
||||||
codecHotswapTimeMs = -1;
|
codecHotswapDeadlineMs = -1;
|
||||||
inputIndex = -1;
|
inputIndex = -1;
|
||||||
outputIndex = -1;
|
outputIndex = -1;
|
||||||
waitingForKeys = false;
|
waitingForKeys = false;
|
||||||
@ -484,7 +484,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void flushCodec() throws ExoPlaybackException {
|
private void flushCodec() throws ExoPlaybackException {
|
||||||
codecHotswapTimeMs = -1;
|
codecHotswapDeadlineMs = -1;
|
||||||
inputIndex = -1;
|
inputIndex = -1;
|
||||||
outputIndex = -1;
|
outputIndex = -1;
|
||||||
waitingForKeys = false;
|
waitingForKeys = false;
|
||||||
@ -776,12 +776,8 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReady() {
|
protected boolean isReady() {
|
||||||
return format != null && !waitingForKeys
|
return format != null && !waitingForKeys && (isSourceReady() || outputIndex >= 0
|
||||||
&& (isSourceReady() || outputIndex >= 0 || isWithinHotswapPeriod());
|
|| (SystemClock.elapsedRealtime() < codecHotswapDeadlineMs));
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isWithinHotswapPeriod() {
|
|
||||||
return SystemClock.elapsedRealtime() < codecHotswapTimeMs + MAX_CODEC_HOTSWAP_TIME_MS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,7 +107,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
|
|
||||||
private final VideoFrameReleaseTimeHelper frameReleaseTimeHelper;
|
private final VideoFrameReleaseTimeHelper frameReleaseTimeHelper;
|
||||||
private final EventListener eventListener;
|
private final EventListener eventListener;
|
||||||
private final long allowedJoiningTimeUs;
|
private final long allowedJoiningTimeMs;
|
||||||
private final int videoScalingMode;
|
private final int videoScalingMode;
|
||||||
private final int maxDroppedFrameCountToNotify;
|
private final int maxDroppedFrameCountToNotify;
|
||||||
private final boolean deviceNeedsAutoFrcWorkaround;
|
private final boolean deviceNeedsAutoFrcWorkaround;
|
||||||
@ -118,7 +118,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
private Surface surface;
|
private Surface surface;
|
||||||
private boolean reportedDrawnToSurface;
|
private boolean reportedDrawnToSurface;
|
||||||
private boolean renderedFirstFrame;
|
private boolean renderedFirstFrame;
|
||||||
private long joiningDeadlineUs;
|
private long joiningDeadlineMs;
|
||||||
private long droppedFrameAccumulationStartTimeMs;
|
private long droppedFrameAccumulationStartTimeMs;
|
||||||
private int droppedFrameCount;
|
private int droppedFrameCount;
|
||||||
private int consecutiveDroppedFrameCount;
|
private int consecutiveDroppedFrameCount;
|
||||||
@ -206,11 +206,11 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
eventListener);
|
eventListener);
|
||||||
this.frameReleaseTimeHelper = new VideoFrameReleaseTimeHelper(context);
|
this.frameReleaseTimeHelper = new VideoFrameReleaseTimeHelper(context);
|
||||||
this.videoScalingMode = videoScalingMode;
|
this.videoScalingMode = videoScalingMode;
|
||||||
this.allowedJoiningTimeUs = allowedJoiningTimeMs * 1000;
|
this.allowedJoiningTimeMs = allowedJoiningTimeMs;
|
||||||
this.eventListener = eventListener;
|
this.eventListener = eventListener;
|
||||||
this.maxDroppedFrameCountToNotify = maxDroppedFrameCountToNotify;
|
this.maxDroppedFrameCountToNotify = maxDroppedFrameCountToNotify;
|
||||||
deviceNeedsAutoFrcWorkaround = deviceNeedsAutoFrcWorkaround();
|
deviceNeedsAutoFrcWorkaround = deviceNeedsAutoFrcWorkaround();
|
||||||
joiningDeadlineUs = -1;
|
joiningDeadlineMs = -1;
|
||||||
currentWidth = -1;
|
currentWidth = -1;
|
||||||
currentHeight = -1;
|
currentHeight = -1;
|
||||||
currentPixelWidthHeightRatio = -1;
|
currentPixelWidthHeightRatio = -1;
|
||||||
@ -276,8 +276,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
adaptiveMaxHeight = 1080;
|
adaptiveMaxHeight = 1080;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (joining && allowedJoiningTimeUs > 0) {
|
if (joining && allowedJoiningTimeMs > 0) {
|
||||||
joiningDeadlineUs = SystemClock.elapsedRealtime() * 1000L + allowedJoiningTimeUs;
|
joiningDeadlineMs = SystemClock.elapsedRealtime() + allowedJoiningTimeMs;
|
||||||
}
|
}
|
||||||
frameReleaseTimeHelper.enable();
|
frameReleaseTimeHelper.enable();
|
||||||
}
|
}
|
||||||
@ -287,24 +287,24 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
super.reset(positionUs);
|
super.reset(positionUs);
|
||||||
renderedFirstFrame = false;
|
renderedFirstFrame = false;
|
||||||
consecutiveDroppedFrameCount = 0;
|
consecutiveDroppedFrameCount = 0;
|
||||||
joiningDeadlineUs = -1;
|
joiningDeadlineMs = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReady() {
|
protected boolean isReady() {
|
||||||
if (renderedFirstFrame && super.isReady()) {
|
if (renderedFirstFrame && super.isReady()) {
|
||||||
// Ready. If we were joining then we've now joined, so clear the joining deadline.
|
// Ready. If we were joining then we've now joined, so clear the joining deadline.
|
||||||
joiningDeadlineUs = -1;
|
joiningDeadlineMs = -1;
|
||||||
return true;
|
return true;
|
||||||
} else if (joiningDeadlineUs == -1) {
|
} else if (joiningDeadlineMs == -1) {
|
||||||
// Not joining.
|
// Not joining.
|
||||||
return false;
|
return false;
|
||||||
} else if (SystemClock.elapsedRealtime() * 1000 < joiningDeadlineUs) {
|
} else if (SystemClock.elapsedRealtime() < joiningDeadlineMs) {
|
||||||
// Joining and still within the joining deadline.
|
// Joining and still within the joining deadline.
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// The joining deadline has been exceeded. Give up and clear the deadline.
|
// The joining deadline has been exceeded. Give up and clear the deadline.
|
||||||
joiningDeadlineUs = -1;
|
joiningDeadlineMs = -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,7 +318,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStopped() {
|
protected void onStopped() {
|
||||||
joiningDeadlineUs = -1;
|
joiningDeadlineMs = -1;
|
||||||
maybeNotifyDroppedFrameCount();
|
maybeNotifyDroppedFrameCount();
|
||||||
super.onStopped();
|
super.onStopped();
|
||||||
}
|
}
|
||||||
|
@ -61,10 +61,10 @@ public final class MultiSampleSource implements SampleSource {
|
|||||||
int totalTrackGroupCount = 0;
|
int totalTrackGroupCount = 0;
|
||||||
for (SampleSource source : sources) {
|
for (SampleSource source : sources) {
|
||||||
totalTrackGroupCount += source.getTrackGroups().length;
|
totalTrackGroupCount += source.getTrackGroups().length;
|
||||||
if (durationUs != C.UNKNOWN_TIME_US) {
|
if (durationUs != C.UNSET_TIME_US) {
|
||||||
long sourceDurationUs = source.getDurationUs();
|
long sourceDurationUs = source.getDurationUs();
|
||||||
durationUs = sourceDurationUs == C.UNKNOWN_TIME_US
|
durationUs = sourceDurationUs == C.UNSET_TIME_US
|
||||||
? C.UNKNOWN_TIME_US : Math.max(durationUs, sourceDurationUs);
|
? C.UNSET_TIME_US : Math.max(durationUs, sourceDurationUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount];
|
TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount];
|
||||||
@ -125,18 +125,18 @@ public final class MultiSampleSource implements SampleSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getBufferedPositionUs() {
|
public long getBufferedPositionUs() {
|
||||||
long bufferedPositionUs = durationUs != C.UNKNOWN_TIME_US ? durationUs : Long.MAX_VALUE;
|
long bufferedPositionUs = durationUs != C.UNSET_TIME_US ? durationUs : Long.MAX_VALUE;
|
||||||
for (SampleSource source : enabledSources) {
|
for (SampleSource source : enabledSources) {
|
||||||
long rendererBufferedPositionUs = source.getBufferedPositionUs();
|
long rendererBufferedPositionUs = source.getBufferedPositionUs();
|
||||||
if (rendererBufferedPositionUs == C.UNKNOWN_TIME_US) {
|
if (rendererBufferedPositionUs == C.UNSET_TIME_US) {
|
||||||
return C.UNKNOWN_TIME_US;
|
return C.UNSET_TIME_US;
|
||||||
} else if (rendererBufferedPositionUs == C.END_OF_SOURCE_US) {
|
} else if (rendererBufferedPositionUs == C.END_OF_SOURCE_US) {
|
||||||
// This source is fully buffered.
|
// This source is fully buffered.
|
||||||
} else {
|
} else {
|
||||||
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
|
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bufferedPositionUs == Long.MAX_VALUE ? C.UNKNOWN_TIME_US : bufferedPositionUs;
|
return bufferedPositionUs == Long.MAX_VALUE ? C.UNSET_TIME_US : bufferedPositionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,8 +41,8 @@ public interface SampleSource {
|
|||||||
* <p>
|
* <p>
|
||||||
* This method should only be called after the source has been prepared.
|
* This method should only be called after the source has been prepared.
|
||||||
*
|
*
|
||||||
* @return The duration of the source in microseconds, or {@link C#UNKNOWN_TIME_US} if the
|
* @return The duration of the source in microseconds, or {@link C#UNSET_TIME_US} if the duration
|
||||||
* duration is not known.
|
* is not known.
|
||||||
*/
|
*/
|
||||||
long getDurationUs();
|
long getDurationUs();
|
||||||
|
|
||||||
@ -89,9 +89,9 @@ public interface SampleSource {
|
|||||||
* <p>
|
* <p>
|
||||||
* This method should only be called when at least one track is selected.
|
* This method should only be called when at least one track is selected.
|
||||||
*
|
*
|
||||||
* @return An estimate of the absolute position in microseconds up to which data is buffered,
|
* @return An estimate of the absolute position in microseconds up to which data is buffered, or
|
||||||
* or {@link C#END_OF_SOURCE_US} if the track is fully buffered, or {@link C#UNKNOWN_TIME_US}
|
* {@link C#END_OF_SOURCE_US} if the track is fully buffered, or {@link C#UNSET_TIME_US} if no
|
||||||
* if no estimate is available.
|
* estimate is available.
|
||||||
*/
|
*/
|
||||||
long getBufferedPositionUs();
|
long getBufferedPositionUs();
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
|
|||||||
if (!newSelections.isEmpty()) {
|
if (!newSelections.isEmpty()) {
|
||||||
newStreams[0] = this;
|
newStreams[0] = this;
|
||||||
streamState = STREAM_STATE_SEND_FORMAT;
|
streamState = STREAM_STATE_SEND_FORMAT;
|
||||||
pendingResetPositionUs = NO_RESET;
|
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
maybeStartLoading();
|
maybeStartLoading();
|
||||||
}
|
}
|
||||||
return newStreams;
|
return newStreams;
|
||||||
@ -183,7 +183,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
|
|||||||
@Override
|
@Override
|
||||||
public long readReset() {
|
public long readReset() {
|
||||||
long resetPositionUs = pendingResetPositionUs;
|
long resetPositionUs = pendingResetPositionUs;
|
||||||
pendingResetPositionUs = NO_RESET;
|
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
return resetPositionUs;
|
return resetPositionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
|
|||||||
*/
|
*/
|
||||||
/* package */ final void checkForReset() throws ExoPlaybackException {
|
/* package */ final void checkForReset() throws ExoPlaybackException {
|
||||||
long resetPositionUs = stream.readReset();
|
long resetPositionUs = stream.readReset();
|
||||||
if (resetPositionUs != TrackStream.NO_RESET) {
|
if (resetPositionUs != C.UNSET_TIME_US) {
|
||||||
reset(resetPositionUs);
|
reset(resetPositionUs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,6 @@ public interface TrackStream {
|
|||||||
* A format was read.
|
* A format was read.
|
||||||
*/
|
*/
|
||||||
int FORMAT_READ = -3;
|
int FORMAT_READ = -3;
|
||||||
/**
|
|
||||||
* Returned from {@link #readReset()} to indicate no reset is required.
|
|
||||||
*/
|
|
||||||
long NO_RESET = Long.MIN_VALUE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether data is available to be read.
|
* Returns whether data is available to be read.
|
||||||
@ -60,7 +56,8 @@ public interface TrackStream {
|
|||||||
/**
|
/**
|
||||||
* Attempts to read a pending reset.
|
* Attempts to read a pending reset.
|
||||||
*
|
*
|
||||||
* @return If a reset was read then the position after the reset. Else {@link #NO_RESET}.
|
* @return If a reset was read then the playback position in microseconds after the reset. Else
|
||||||
|
* {@link C#UNSET_TIME_US}.
|
||||||
*/
|
*/
|
||||||
long readReset();
|
long readReset();
|
||||||
|
|
||||||
|
@ -423,8 +423,7 @@ public final class AudioTrack {
|
|||||||
: multipliedBufferSize > maxAppBufferSize ? maxAppBufferSize
|
: multipliedBufferSize > maxAppBufferSize ? maxAppBufferSize
|
||||||
: multipliedBufferSize;
|
: multipliedBufferSize;
|
||||||
}
|
}
|
||||||
bufferSizeUs = passthrough ? C.UNKNOWN_TIME_US
|
bufferSizeUs = passthrough ? C.UNSET_TIME_US : framesToDurationUs(pcmBytesToFrames(bufferSize));
|
||||||
: framesToDurationUs(pcmBytesToFrames(bufferSize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -501,13 +500,13 @@ public final class AudioTrack {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the size of the buffer in microseconds for PCM {@link AudioTrack}s, or
|
* Returns the size of the buffer in microseconds for PCM {@link AudioTrack}s, or
|
||||||
* {@link C#UNKNOWN_TIME_US} for passthrough {@link AudioTrack}s.
|
* {@link C#UNSET_TIME_US} for passthrough {@link AudioTrack}s.
|
||||||
* <p>
|
* <p>
|
||||||
* The value returned from this method may change as a result of calling one of the
|
* The value returned from this method may change as a result of calling one of the
|
||||||
* {@link #configure} methods.
|
* {@link #configure} methods.
|
||||||
*
|
*
|
||||||
* @return The size of the buffer in microseconds for PCM {@link AudioTrack}s, or
|
* @return The size of the buffer in microseconds for PCM {@link AudioTrack}s, or
|
||||||
* {@link C#UNKNOWN_TIME_US} for passthrough {@link AudioTrack}s.
|
* {@link C#UNSET_TIME_US} for passthrough {@link AudioTrack}s.
|
||||||
*/
|
*/
|
||||||
public long getBufferSizeUs() {
|
public long getBufferSizeUs() {
|
||||||
return bufferSizeUs;
|
return bufferSizeUs;
|
||||||
@ -1003,7 +1002,7 @@ public final class AudioTrack {
|
|||||||
boolean needsPassthroughWorkaround) {
|
boolean needsPassthroughWorkaround) {
|
||||||
this.audioTrack = audioTrack;
|
this.audioTrack = audioTrack;
|
||||||
this.needsPassthroughWorkaround = needsPassthroughWorkaround;
|
this.needsPassthroughWorkaround = needsPassthroughWorkaround;
|
||||||
stopTimestampUs = -1;
|
stopTimestampUs = C.UNSET_TIME_US;
|
||||||
lastRawPlaybackHeadPosition = 0;
|
lastRawPlaybackHeadPosition = 0;
|
||||||
rawPlaybackHeadWrapCount = 0;
|
rawPlaybackHeadWrapCount = 0;
|
||||||
passthroughWorkaroundPauseOffset = 0;
|
passthroughWorkaroundPauseOffset = 0;
|
||||||
@ -1031,7 +1030,7 @@ public final class AudioTrack {
|
|||||||
* this method does nothing.
|
* this method does nothing.
|
||||||
*/
|
*/
|
||||||
public void pause() {
|
public void pause() {
|
||||||
if (stopTimestampUs != -1) {
|
if (stopTimestampUs != C.UNSET_TIME_US) {
|
||||||
// We don't want to knock the audio track back into the paused state.
|
// We don't want to knock the audio track back into the paused state.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1048,7 +1047,7 @@ public final class AudioTrack {
|
|||||||
* expressed as a long.
|
* expressed as a long.
|
||||||
*/
|
*/
|
||||||
public long getPlaybackHeadPosition() {
|
public long getPlaybackHeadPosition() {
|
||||||
if (stopTimestampUs != -1) {
|
if (stopTimestampUs != C.UNSET_TIME_US) {
|
||||||
// Simulate the playback head position up to the total number of frames submitted.
|
// Simulate the playback head position up to the total number of frames submitted.
|
||||||
long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
|
long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
|
||||||
long framesSinceStop = (elapsedTimeSinceStopUs * sampleRate) / C.MICROS_PER_SECOND;
|
long framesSinceStop = (elapsedTimeSinceStopUs * sampleRate) / C.MICROS_PER_SECOND;
|
||||||
|
@ -50,8 +50,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
|||||||
*/
|
*/
|
||||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
||||||
|
|
||||||
private static final long NO_RESET_PENDING = Long.MIN_VALUE;
|
|
||||||
|
|
||||||
private final Loader loader;
|
private final Loader loader;
|
||||||
private final LoadControl loadControl;
|
private final LoadControl loadControl;
|
||||||
private final ChunkSource chunkSource;
|
private final ChunkSource chunkSource;
|
||||||
@ -128,7 +126,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
|||||||
mediaChunks = new LinkedList<>();
|
mediaChunks = new LinkedList<>();
|
||||||
readOnlyMediaChunks = Collections.unmodifiableList(mediaChunks);
|
readOnlyMediaChunks = Collections.unmodifiableList(mediaChunks);
|
||||||
sampleQueue = new DefaultTrackOutput(loadControl.getAllocator());
|
sampleQueue = new DefaultTrackOutput(loadControl.getAllocator());
|
||||||
pendingResetPositionUs = NO_RESET_PENDING;
|
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SampleSource implementation.
|
// SampleSource implementation.
|
||||||
@ -279,7 +277,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
|||||||
pendingReset = false;
|
pendingReset = false;
|
||||||
return lastSeekPositionUs;
|
return lastSeekPositionUs;
|
||||||
}
|
}
|
||||||
return TrackStream.NO_RESET;
|
return C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -430,14 +428,13 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
|||||||
lastPreferredQueueSizeEvaluationTimeMs = now;
|
lastPreferredQueueSizeEvaluationTimeMs = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
long nextLoadPositionUs = getNextLoadPositionUs();
|
boolean isNext = loadControl.update(this, downstreamPositionUs, getNextLoadPositionUs(), false);
|
||||||
boolean isNext = loadControl.update(this, downstreamPositionUs, nextLoadPositionUs, false);
|
|
||||||
if (!isNext) {
|
if (!isNext) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkSource.getNextChunk(mediaChunks.isEmpty() ? null : mediaChunks.getLast(),
|
chunkSource.getNextChunk(mediaChunks.isEmpty() ? null : mediaChunks.getLast(),
|
||||||
pendingResetPositionUs != NO_RESET_PENDING ? pendingResetPositionUs : downstreamPositionUs,
|
pendingResetPositionUs != C.UNSET_TIME_US ? pendingResetPositionUs : downstreamPositionUs,
|
||||||
nextChunkHolder);
|
nextChunkHolder);
|
||||||
boolean endOfStream = nextChunkHolder.endOfStream;
|
boolean endOfStream = nextChunkHolder.endOfStream;
|
||||||
Chunk nextLoadable = nextChunkHolder.chunk;
|
Chunk nextLoadable = nextChunkHolder.chunk;
|
||||||
@ -445,7 +442,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
|||||||
|
|
||||||
if (endOfStream) {
|
if (endOfStream) {
|
||||||
loadingFinished = true;
|
loadingFinished = true;
|
||||||
loadControl.update(this, downstreamPositionUs, -1, false);
|
loadControl.update(this, downstreamPositionUs, C.UNSET_TIME_US, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +457,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
|||||||
mediaChunk.init(sampleQueue);
|
mediaChunk.init(sampleQueue);
|
||||||
mediaChunks.add(mediaChunk);
|
mediaChunks.add(mediaChunk);
|
||||||
if (isPendingReset()) {
|
if (isPendingReset()) {
|
||||||
pendingResetPositionUs = NO_RESET_PENDING;
|
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
eventDispatcher.loadStarted(mediaChunk.dataSpec.length, mediaChunk.type, mediaChunk.trigger,
|
eventDispatcher.loadStarted(mediaChunk.dataSpec.length, mediaChunk.type, mediaChunk.trigger,
|
||||||
mediaChunk.format, mediaChunk.startTimeUs, mediaChunk.endTimeUs);
|
mediaChunk.format, mediaChunk.startTimeUs, mediaChunk.endTimeUs);
|
||||||
@ -481,7 +478,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
|||||||
if (isPendingReset()) {
|
if (isPendingReset()) {
|
||||||
return pendingResetPositionUs;
|
return pendingResetPositionUs;
|
||||||
} else {
|
} else {
|
||||||
return loadingFinished ? -1 : mediaChunks.getLast().endTimeUs;
|
return loadingFinished ? C.UNSET_TIME_US : mediaChunks.getLast().endTimeUs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +511,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPendingReset() {
|
private boolean isPendingReset() {
|
||||||
return pendingResetPositionUs != NO_RESET_PENDING;
|
return pendingResetPositionUs != C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ public interface ChunkSource {
|
|||||||
* <p>
|
* <p>
|
||||||
* This method should only be called after the source has been prepared.
|
* This method should only be called after the source has been prepared.
|
||||||
*
|
*
|
||||||
* @return The duration of the source in microseconds, or {@link C#UNKNOWN_TIME_US} if the
|
* @return The duration of the source in microseconds, or {@link C#UNSET_TIME_US} if the duration
|
||||||
* duration is unknown.
|
* is unknown.
|
||||||
*/
|
*/
|
||||||
long getDurationUs();
|
long getDurationUs();
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ public class DashChunkSource implements ChunkSource {
|
|||||||
private void initForManifest(MediaPresentationDescription manifest) {
|
private void initForManifest(MediaPresentationDescription manifest) {
|
||||||
Period period = manifest.getPeriod(0);
|
Period period = manifest.getPeriod(0);
|
||||||
live = currentManifest.dynamic;
|
live = currentManifest.dynamic;
|
||||||
durationUs = live ? C.UNKNOWN_TIME_US : currentManifest.duration * 1000;
|
durationUs = live ? C.UNSET_TIME_US : currentManifest.duration * 1000;
|
||||||
|
|
||||||
for (int i = 0; i < period.adaptationSets.size(); i++) {
|
for (int i = 0; i < period.adaptationSets.size(); i++) {
|
||||||
AdaptationSet adaptationSet = period.adaptationSets.get(i);
|
AdaptationSet adaptationSet = period.adaptationSets.get(i);
|
||||||
@ -439,7 +439,7 @@ public class DashChunkSource implements ChunkSource {
|
|||||||
private static long getPeriodDurationUs(MediaPresentationDescription manifest, int index) {
|
private static long getPeriodDurationUs(MediaPresentationDescription manifest, int index) {
|
||||||
long durationMs = manifest.getPeriodDuration(index);
|
long durationMs = manifest.getPeriodDuration(index);
|
||||||
if (durationMs == -1) {
|
if (durationMs == -1) {
|
||||||
return C.UNKNOWN_TIME_US;
|
return C.UNSET_TIME_US;
|
||||||
} else {
|
} else {
|
||||||
return durationMs * 1000;
|
return durationMs * 1000;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public interface DashSegmentIndex {
|
|||||||
*
|
*
|
||||||
* @param timeUs The time in microseconds.
|
* @param timeUs The time in microseconds.
|
||||||
* @param periodDurationUs The duration of the enclosing period in microseconds, or
|
* @param periodDurationUs The duration of the enclosing period in microseconds, or
|
||||||
* {@link C#UNKNOWN_TIME_US} if the period's duration is not yet known.
|
* {@link C#UNSET_TIME_US} if the period's duration is not yet known.
|
||||||
* @return The segment number of the corresponding segment.
|
* @return The segment number of the corresponding segment.
|
||||||
*/
|
*/
|
||||||
int getSegmentNum(long timeUs, long periodDurationUs);
|
int getSegmentNum(long timeUs, long periodDurationUs);
|
||||||
@ -55,7 +55,7 @@ public interface DashSegmentIndex {
|
|||||||
*
|
*
|
||||||
* @param segmentNum The segment number.
|
* @param segmentNum The segment number.
|
||||||
* @param periodDurationUs The duration of the enclosing period in microseconds, or
|
* @param periodDurationUs The duration of the enclosing period in microseconds, or
|
||||||
* {@link C#UNKNOWN_TIME_US} if the period's duration is not yet known.
|
* {@link C#UNSET_TIME_US} if the period's duration is not yet known.
|
||||||
* @return The duration of the segment, in microseconds.
|
* @return The duration of the segment, in microseconds.
|
||||||
*/
|
*/
|
||||||
long getDurationUs(int segmentNum, long periodDurationUs);
|
long getDurationUs(int segmentNum, long periodDurationUs);
|
||||||
@ -83,7 +83,7 @@ public interface DashSegmentIndex {
|
|||||||
* must manually determine the window of currently available segments.
|
* must manually determine the window of currently available segments.
|
||||||
*
|
*
|
||||||
* @param periodDurationUs The duration of the enclosing period in microseconds, or
|
* @param periodDurationUs The duration of the enclosing period in microseconds, or
|
||||||
* {@link C#UNKNOWN_TIME_US} if the period's duration is not yet known.
|
* {@link C#UNSET_TIME_US} if the period's duration is not yet known.
|
||||||
* @return The segment number of the last segment, or {@link #INDEX_UNBOUNDED}.
|
* @return The segment number of the last segment, or {@link #INDEX_UNBOUNDED}.
|
||||||
*/
|
*/
|
||||||
int getLastSegmentNum(long periodDurationUs);
|
int getLastSegmentNum(long periodDurationUs);
|
||||||
|
@ -342,7 +342,7 @@ public abstract class SegmentBase {
|
|||||||
public int getLastSegmentNum(long periodDurationUs) {
|
public int getLastSegmentNum(long periodDurationUs) {
|
||||||
if (segmentTimeline != null) {
|
if (segmentTimeline != null) {
|
||||||
return segmentTimeline.size() + startNumber - 1;
|
return segmentTimeline.size() + startNumber - 1;
|
||||||
} else if (periodDurationUs == C.UNKNOWN_TIME_US) {
|
} else if (periodDurationUs == C.UNSET_TIME_US) {
|
||||||
return DashSegmentIndex.INDEX_UNBOUNDED;
|
return DashSegmentIndex.INDEX_UNBOUNDED;
|
||||||
} else {
|
} else {
|
||||||
long durationUs = (duration * C.MICROS_PER_SECOND) / timescale;
|
long durationUs = (duration * C.MICROS_PER_SECOND) / timescale;
|
||||||
|
@ -108,7 +108,6 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE = 6;
|
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE = 6;
|
||||||
|
|
||||||
private static final int MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA = -1;
|
private static final int MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA = -1;
|
||||||
private static final long NO_RESET_PENDING = Long.MIN_VALUE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default extractor classes in priority order. They are referred to indirectly so that it is
|
* Default extractor classes in priority order. They are referred to indirectly so that it is
|
||||||
@ -326,7 +325,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||||||
}
|
}
|
||||||
extractorHolder = new ExtractorHolder(extractors, this);
|
extractorHolder = new ExtractorHolder(extractors, this);
|
||||||
sampleQueues = new SparseArray<>();
|
sampleQueues = new SparseArray<>();
|
||||||
pendingResetPositionUs = NO_RESET_PENDING;
|
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SampleSource implementation.
|
// SampleSource implementation.
|
||||||
@ -348,7 +347,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||||||
}
|
}
|
||||||
tracks = new TrackGroupArray(trackArray);
|
tracks = new TrackGroupArray(trackArray);
|
||||||
if (minLoadableRetryCount == MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA && !seekMap.isSeekable()
|
if (minLoadableRetryCount == MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA && !seekMap.isSeekable()
|
||||||
&& durationUs == C.UNKNOWN_TIME_US) {
|
&& durationUs == C.UNSET_TIME_US) {
|
||||||
loader.setMinRetryCount(DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE);
|
loader.setMinRetryCount(DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE);
|
||||||
}
|
}
|
||||||
prepared = true;
|
prepared = true;
|
||||||
@ -467,7 +466,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||||||
pendingResets[track] = false;
|
pendingResets[track] = false;
|
||||||
return lastSeekPositionUs;
|
return lastSeekPositionUs;
|
||||||
}
|
}
|
||||||
return TrackStream.NO_RESET;
|
return C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ int readData(int track, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
/* package */ int readData(int track, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||||
@ -598,13 +597,13 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||||||
requestedBufferSize);
|
requestedBufferSize);
|
||||||
if (prepared) {
|
if (prepared) {
|
||||||
Assertions.checkState(isPendingReset());
|
Assertions.checkState(isPendingReset());
|
||||||
if (durationUs != C.UNKNOWN_TIME_US && pendingResetPositionUs >= durationUs) {
|
if (durationUs != C.UNSET_TIME_US && pendingResetPositionUs >= durationUs) {
|
||||||
loadingFinished = true;
|
loadingFinished = true;
|
||||||
pendingResetPositionUs = NO_RESET_PENDING;
|
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loadable.setLoadPosition(seekMap.getPosition(pendingResetPositionUs));
|
loadable.setLoadPosition(seekMap.getPosition(pendingResetPositionUs));
|
||||||
pendingResetPositionUs = NO_RESET_PENDING;
|
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
currentLoadExtractedSamples = false;
|
currentLoadExtractedSamples = false;
|
||||||
loader.startLoading(loadable, this);
|
loader.startLoading(loadable, this);
|
||||||
@ -620,7 +619,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||||||
sampleQueues.valueAt(i).clear();
|
sampleQueues.valueAt(i).clear();
|
||||||
}
|
}
|
||||||
loadable.setLoadPosition(0);
|
loadable.setLoadPosition(0);
|
||||||
} else if (!seekMap.isSeekable() && durationUs == C.UNKNOWN_TIME_US) {
|
} else if (!seekMap.isSeekable() && durationUs == C.UNSET_TIME_US) {
|
||||||
// We're playing a non-seekable stream with unknown duration. Assume it's live, and
|
// We're playing a non-seekable stream with unknown duration. Assume it's live, and
|
||||||
// therefore that the data at the uri is a continuously shifting window of the latest
|
// therefore that the data at the uri is a continuously shifting window of the latest
|
||||||
// available media. For this case there's no way to continue loading from where a previous
|
// available media. For this case there's no way to continue loading from where a previous
|
||||||
@ -665,7 +664,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPendingReset() {
|
private boolean isPendingReset() {
|
||||||
return pendingResetPositionUs != NO_RESET_PENDING;
|
return pendingResetPositionUs != C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isLoadableExceptionFatal(IOException e) {
|
private boolean isLoadableExceptionFatal(IOException e) {
|
||||||
|
@ -30,7 +30,7 @@ public interface SeekMap {
|
|||||||
private final long durationUs;
|
private final long durationUs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param durationUs The duration of the stream in microseconds, or {@link C#UNKNOWN_TIME_US} if
|
* @param durationUs The duration of the stream in microseconds, or {@link C#UNSET_TIME_US} if
|
||||||
* the duration is unknown.
|
* the duration is unknown.
|
||||||
*/
|
*/
|
||||||
public Unseekable(long durationUs) {
|
public Unseekable(long durationUs) {
|
||||||
@ -67,7 +67,7 @@ public interface SeekMap {
|
|||||||
/**
|
/**
|
||||||
* Returns the duration of the stream in microseconds.
|
* Returns the duration of the stream in microseconds.
|
||||||
*
|
*
|
||||||
* @return The duration of the stream in microseconds, or {@link C#UNKNOWN_TIME_US} if the
|
* @return The duration of the stream in microseconds, or {@link C#UNSET_TIME_US} if the
|
||||||
* duration is unknown.
|
* duration is unknown.
|
||||||
*/
|
*/
|
||||||
long getDurationUs();
|
long getDurationUs();
|
||||||
|
@ -50,7 +50,7 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public ScriptTagPayloadReader(TrackOutput output) {
|
public ScriptTagPayloadReader(TrackOutput output) {
|
||||||
super(output);
|
super(output);
|
||||||
durationUs = C.UNKNOWN_TIME_US;
|
durationUs = C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDurationUs() {
|
public long getDurationUs() {
|
||||||
|
@ -189,9 +189,9 @@ public final class MatroskaExtractor implements Extractor {
|
|||||||
|
|
||||||
private long segmentContentPosition = UNKNOWN;
|
private long segmentContentPosition = UNKNOWN;
|
||||||
private long segmentContentSize = UNKNOWN;
|
private long segmentContentSize = UNKNOWN;
|
||||||
private long timecodeScale = C.UNKNOWN_TIME_US;
|
private long timecodeScale = C.UNSET_TIME_US;
|
||||||
private long durationTimecode = C.UNKNOWN_TIME_US;
|
private long durationTimecode = C.UNSET_TIME_US;
|
||||||
private long durationUs = C.UNKNOWN_TIME_US;
|
private long durationUs = C.UNSET_TIME_US;
|
||||||
|
|
||||||
// The track corresponding to the current TrackEntry element, or null.
|
// The track corresponding to the current TrackEntry element, or null.
|
||||||
private Track currentTrack;
|
private Track currentTrack;
|
||||||
@ -417,11 +417,11 @@ public final class MatroskaExtractor implements Extractor {
|
|||||||
/* package */ void endMasterElement(int id) throws ParserException {
|
/* package */ void endMasterElement(int id) throws ParserException {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case ID_SEGMENT_INFO:
|
case ID_SEGMENT_INFO:
|
||||||
if (timecodeScale == C.UNKNOWN_TIME_US) {
|
if (timecodeScale == C.UNSET_TIME_US) {
|
||||||
// timecodeScale was omitted. Use the default value.
|
// timecodeScale was omitted. Use the default value.
|
||||||
timecodeScale = 1000000;
|
timecodeScale = 1000000;
|
||||||
}
|
}
|
||||||
if (durationTimecode != C.UNKNOWN_TIME_US) {
|
if (durationTimecode != C.UNSET_TIME_US) {
|
||||||
durationUs = scaleTimecodeToUs(durationTimecode);
|
durationUs = scaleTimecodeToUs(durationTimecode);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -987,7 +987,7 @@ public final class MatroskaExtractor implements Extractor {
|
|||||||
* information was missing or incomplete.
|
* information was missing or incomplete.
|
||||||
*/
|
*/
|
||||||
private SeekMap buildSeekMap() {
|
private SeekMap buildSeekMap() {
|
||||||
if (segmentContentPosition == UNKNOWN || durationUs == C.UNKNOWN_TIME_US
|
if (segmentContentPosition == UNKNOWN || durationUs == C.UNSET_TIME_US
|
||||||
|| cueTimesUs == null || cueTimesUs.size() == 0
|
|| cueTimesUs == null || cueTimesUs.size() == 0
|
||||||
|| cueClusterPositions == null || cueClusterPositions.size() != cueTimesUs.size()) {
|
|| cueClusterPositions == null || cueClusterPositions.size() != cueTimesUs.size()) {
|
||||||
// Cues information is missing or incomplete.
|
// Cues information is missing or incomplete.
|
||||||
@ -1043,7 +1043,7 @@ public final class MatroskaExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long scaleTimecodeToUs(long unscaledTimecode) throws ParserException {
|
private long scaleTimecodeToUs(long unscaledTimecode) throws ParserException {
|
||||||
if (timecodeScale == C.UNKNOWN_TIME_US) {
|
if (timecodeScale == C.UNSET_TIME_US) {
|
||||||
throw new ParserException("Can't scale timecode prior to timecodeScale being set.");
|
throw new ParserException("Can't scale timecode prior to timecodeScale being set.");
|
||||||
}
|
}
|
||||||
return Util.scaleLargeTimestamp(unscaledTimecode, timecodeScale, 1000);
|
return Util.scaleLargeTimestamp(unscaledTimecode, timecodeScale, 1000);
|
||||||
|
@ -31,17 +31,17 @@ import com.google.android.exoplayer.C;
|
|||||||
public ConstantBitrateSeeker(long firstFramePosition, int bitrate, long inputLength) {
|
public ConstantBitrateSeeker(long firstFramePosition, int bitrate, long inputLength) {
|
||||||
this.firstFramePosition = firstFramePosition;
|
this.firstFramePosition = firstFramePosition;
|
||||||
this.bitrate = bitrate;
|
this.bitrate = bitrate;
|
||||||
durationUs = inputLength == C.LENGTH_UNBOUNDED ? C.UNKNOWN_TIME_US : getTimeUs(inputLength);
|
durationUs = inputLength == C.LENGTH_UNBOUNDED ? C.UNSET_TIME_US : getTimeUs(inputLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSeekable() {
|
public boolean isSeekable() {
|
||||||
return durationUs != C.UNKNOWN_TIME_US;
|
return durationUs != C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getPosition(long timeUs) {
|
public long getPosition(long timeUs) {
|
||||||
return durationUs == C.UNKNOWN_TIME_US ? 0
|
return durationUs == C.UNSET_TIME_US ? 0
|
||||||
: firstFramePosition + (timeUs * bitrate) / (C.MICROS_PER_SECOND * BITS_PER_BYTE);
|
: firstFramePosition + (timeUs * bitrate) / (C.MICROS_PER_SECOND * BITS_PER_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ import java.util.List;
|
|||||||
long movieTimescale = parseMvhd(mvhd.data);
|
long movieTimescale = parseMvhd(mvhd.data);
|
||||||
long durationUs;
|
long durationUs;
|
||||||
if (duration == -1) {
|
if (duration == -1) {
|
||||||
durationUs = C.UNKNOWN_TIME_US;
|
durationUs = C.UNSET_TIME_US;
|
||||||
} else {
|
} else {
|
||||||
durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, movieTimescale);
|
durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, movieTimescale);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
extendedTypeScratch = new byte[16];
|
extendedTypeScratch = new byte[16];
|
||||||
containerAtoms = new Stack<>();
|
containerAtoms = new Stack<>();
|
||||||
trackBundles = new SparseArray<>();
|
trackBundles = new SparseArray<>();
|
||||||
durationUs = C.UNKNOWN_TIME_US;
|
durationUs = C.UNSET_TIME_US;
|
||||||
enterReadingAtomHeaderState();
|
enterReadingAtomHeaderState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
|||||||
* Updates the stored track metadata to reflect the contents of the specified moov atom.
|
* Updates the stored track metadata to reflect the contents of the specified moov atom.
|
||||||
*/
|
*/
|
||||||
private void processMoovAtom(ContainerAtom moov) throws ParserException {
|
private void processMoovAtom(ContainerAtom moov) throws ParserException {
|
||||||
long durationUs = C.UNKNOWN_TIME_US;
|
long durationUs = C.UNSET_TIME_US;
|
||||||
List<Mp4Track> tracks = new ArrayList<>();
|
List<Mp4Track> tracks = new ArrayList<>();
|
||||||
long earliestSampleOffset = Long.MAX_VALUE;
|
long earliestSampleOffset = Long.MAX_VALUE;
|
||||||
GaplessInfo gaplessInfo = null;
|
GaplessInfo gaplessInfo = null;
|
||||||
|
@ -44,7 +44,7 @@ public final class Track {
|
|||||||
public final long movieTimescale;
|
public final long movieTimescale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The duration of the track in microseconds, or {@link C#UNKNOWN_TIME_US} if unknown.
|
* The duration of the track in microseconds, or {@link C#UNSET_TIME_US} if unknown.
|
||||||
*/
|
*/
|
||||||
public final long durationUs;
|
public final long durationUs;
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ public final class AdtsExtractor implements Extractor {
|
|||||||
public void init(ExtractorOutput output) {
|
public void init(ExtractorOutput output) {
|
||||||
adtsReader = new AdtsReader(output.track(0), output.track(1));
|
adtsReader = new AdtsReader(output.track(0), output.track(1));
|
||||||
output.endTracks();
|
output.endTracks();
|
||||||
output.seekMap(new SeekMap.Unseekable(C.UNKNOWN_TIME_US));
|
output.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -77,7 +77,7 @@ import java.util.Collections;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void packetStarted(long pesTimeUs, boolean dataAlignmentIndicator) {
|
public void packetStarted(long pesTimeUs, boolean dataAlignmentIndicator) {
|
||||||
pesPtsUsAvailable = pesTimeUs != C.UNKNOWN_TIME_US;
|
pesPtsUsAvailable = pesTimeUs != C.UNSET_TIME_US;
|
||||||
if (pesPtsUsAvailable) {
|
if (pesPtsUsAvailable) {
|
||||||
this.pesTimeUs = pesTimeUs;
|
this.pesTimeUs = pesTimeUs;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ public final class PsExtractor implements Extractor {
|
|||||||
@Override
|
@Override
|
||||||
public void init(ExtractorOutput output) {
|
public void init(ExtractorOutput output) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
output.seekMap(new SeekMap.Unseekable(C.UNKNOWN_TIME_US));
|
output.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -112,7 +112,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
@Override
|
@Override
|
||||||
public void init(ExtractorOutput output) {
|
public void init(ExtractorOutput output) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
output.seekMap(new SeekMap.Unseekable(C.UNKNOWN_TIME_US));
|
output.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -607,7 +607,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
|
|
||||||
private void parseHeaderExtension() {
|
private void parseHeaderExtension() {
|
||||||
pesScratch.setPosition(0);
|
pesScratch.setPosition(0);
|
||||||
timeUs = C.UNKNOWN_TIME_US;
|
timeUs = C.UNSET_TIME_US;
|
||||||
if (ptsFlag) {
|
if (ptsFlag) {
|
||||||
pesScratch.skipBits(4); // '0010' or '0011'
|
pesScratch.skipBits(4); // '0010' or '0011'
|
||||||
long pts = (long) pesScratch.readBits(3) << 30;
|
long pts = (long) pesScratch.readBits(3) << 30;
|
||||||
|
@ -189,7 +189,7 @@ public class HlsChunkSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the duration of the source, or {@link C#UNKNOWN_TIME_US} if the duration is unknown.
|
* Returns the duration of the source, or {@link C#UNSET_TIME_US} if the duration is unknown.
|
||||||
* <p>
|
* <p>
|
||||||
* This method should only be called after the source has been prepared.
|
* This method should only be called after the source has been prepared.
|
||||||
*
|
*
|
||||||
@ -660,7 +660,7 @@ public class HlsChunkSource {
|
|||||||
variantLastPlaylistLoadTimesMs[variantIndex] = SystemClock.elapsedRealtime();
|
variantLastPlaylistLoadTimesMs[variantIndex] = SystemClock.elapsedRealtime();
|
||||||
variantPlaylists[variantIndex] = mediaPlaylist;
|
variantPlaylists[variantIndex] = mediaPlaylist;
|
||||||
live |= mediaPlaylist.live;
|
live |= mediaPlaylist.live;
|
||||||
durationUs = live ? C.UNKNOWN_TIME_US : mediaPlaylist.durationUs;
|
durationUs = live ? C.UNSET_TIME_US : mediaPlaylist.durationUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean allEnabledVariantsBlacklisted() {
|
private boolean allEnabledVariantsBlacklisted() {
|
||||||
|
@ -52,8 +52,6 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
*/
|
*/
|
||||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
||||||
|
|
||||||
private static final long NO_RESET_PENDING = Long.MIN_VALUE;
|
|
||||||
|
|
||||||
private static final int PRIMARY_TYPE_NONE = 0;
|
private static final int PRIMARY_TYPE_NONE = 0;
|
||||||
private static final int PRIMARY_TYPE_TEXT = 1;
|
private static final int PRIMARY_TYPE_TEXT = 1;
|
||||||
private static final int PRIMARY_TYPE_AUDIO = 2;
|
private static final int PRIMARY_TYPE_AUDIO = 2;
|
||||||
@ -111,7 +109,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
this.chunkSource = chunkSource;
|
this.chunkSource = chunkSource;
|
||||||
this.loadControl = loadControl;
|
this.loadControl = loadControl;
|
||||||
this.bufferSizeContribution = bufferSizeContribution;
|
this.bufferSizeContribution = bufferSizeContribution;
|
||||||
this.pendingResetPositionUs = NO_RESET_PENDING;
|
this.pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
loader = new Loader("Loader:HLS", minLoadableRetryCount);
|
loader = new Loader("Loader:HLS", minLoadableRetryCount);
|
||||||
eventDispatcher = new EventDispatcher(eventHandler, eventListener, eventSourceId);
|
eventDispatcher = new EventDispatcher(eventHandler, eventListener, eventSourceId);
|
||||||
extractors = new LinkedList<>();
|
extractors = new LinkedList<>();
|
||||||
@ -303,7 +301,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
pendingResets[group] = false;
|
pendingResets[group] = false;
|
||||||
return lastSeekPositionUs;
|
return lastSeekPositionUs;
|
||||||
}
|
}
|
||||||
return TrackStream.NO_RESET;
|
return C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ int readData(int group, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
/* package */ int readData(int group, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||||
@ -533,10 +531,8 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
if (containerFormat == null) {
|
if (containerFormat == null) {
|
||||||
return sampleFormat;
|
return sampleFormat;
|
||||||
}
|
}
|
||||||
int width = containerFormat.width == -1 ? Format.NO_VALUE : containerFormat.width;
|
return sampleFormat.copyWithContainerInfo(containerFormat.id, containerFormat.bitrate,
|
||||||
int height = containerFormat.height == -1 ? Format.NO_VALUE : containerFormat.height;
|
containerFormat.width, containerFormat.height, containerFormat.language);
|
||||||
return sampleFormat.copyWithContainerInfo(containerFormat.id, containerFormat.bitrate, width,
|
|
||||||
height, containerFormat.language);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -630,7 +626,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chunkSource.getNextChunk(previousTsLoadable,
|
chunkSource.getNextChunk(previousTsLoadable,
|
||||||
pendingResetPositionUs != NO_RESET_PENDING ? pendingResetPositionUs : downstreamPositionUs,
|
pendingResetPositionUs != C.UNSET_TIME_US ? pendingResetPositionUs : downstreamPositionUs,
|
||||||
nextChunkHolder);
|
nextChunkHolder);
|
||||||
boolean endOfStream = nextChunkHolder.endOfStream;
|
boolean endOfStream = nextChunkHolder.endOfStream;
|
||||||
Chunk nextLoadable = nextChunkHolder.chunk;
|
Chunk nextLoadable = nextChunkHolder.chunk;
|
||||||
@ -639,7 +635,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
if (endOfStream) {
|
if (endOfStream) {
|
||||||
loadingFinished = true;
|
loadingFinished = true;
|
||||||
if (prepared) {
|
if (prepared) {
|
||||||
loadControl.update(this, downstreamPositionUs, -1, false);
|
loadControl.update(this, downstreamPositionUs, C.UNSET_TIME_US, false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -653,7 +649,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
if (isTsChunk(currentLoadable)) {
|
if (isTsChunk(currentLoadable)) {
|
||||||
TsChunk tsChunk = (TsChunk) currentLoadable;
|
TsChunk tsChunk = (TsChunk) currentLoadable;
|
||||||
if (isPendingReset()) {
|
if (isPendingReset()) {
|
||||||
pendingResetPositionUs = NO_RESET_PENDING;
|
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
HlsExtractorWrapper extractorWrapper = tsChunk.extractorWrapper;
|
HlsExtractorWrapper extractorWrapper = tsChunk.extractorWrapper;
|
||||||
if (extractors.isEmpty() || extractors.getLast() != extractorWrapper) {
|
if (extractors.isEmpty() || extractors.getLast() != extractorWrapper) {
|
||||||
@ -682,8 +678,8 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
if (isPendingReset()) {
|
if (isPendingReset()) {
|
||||||
return pendingResetPositionUs;
|
return pendingResetPositionUs;
|
||||||
} else {
|
} else {
|
||||||
return loadingFinished ? -1 : (currentTsLoadable != null ? currentTsLoadable.endTimeUs
|
return loadingFinished ? C.UNSET_TIME_US : (currentTsLoadable != null
|
||||||
: previousTsLoadable.endTimeUs);
|
? currentTsLoadable.endTimeUs : previousTsLoadable.endTimeUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,7 +688,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPendingReset() {
|
private boolean isPendingReset() {
|
||||||
return pendingResetPositionUs != NO_RESET_PENDING;
|
return pendingResetPositionUs != C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class TrackStreamImpl implements TrackStream {
|
private final class TrackStreamImpl implements TrackStream {
|
||||||
|
@ -76,7 +76,7 @@ import java.util.regex.Pattern;
|
|||||||
@Override
|
@Override
|
||||||
public void init(ExtractorOutput output) {
|
public void init(ExtractorOutput output) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
output.seekMap(new SeekMap.Unseekable(C.UNKNOWN_TIME_US));
|
output.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -304,7 +304,7 @@ public class SmoothStreamingChunkSource implements ChunkSource {
|
|||||||
extractorWrappers = new ChunkExtractorWrapper[formats.length];
|
extractorWrappers = new ChunkExtractorWrapper[formats.length];
|
||||||
for (int j = 0; j < formats.length; j++) {
|
for (int j = 0; j < formats.length; j++) {
|
||||||
int nalUnitLengthFieldLength = streamElementType == C.TRACK_TYPE_VIDEO ? 4 : -1;
|
int nalUnitLengthFieldLength = streamElementType == C.TRACK_TYPE_VIDEO ? 4 : -1;
|
||||||
Track track = new Track(j, streamElementType, timescale, C.UNKNOWN_TIME_US, durationUs,
|
Track track = new Track(j, streamElementType, timescale, C.UNSET_TIME_US, durationUs,
|
||||||
formats[j], trackEncryptionBoxes, nalUnitLengthFieldLength, null, null);
|
formats[j], trackEncryptionBoxes, nalUnitLengthFieldLength, null, null);
|
||||||
FragmentedMp4Extractor extractor = new FragmentedMp4Extractor(
|
FragmentedMp4Extractor extractor = new FragmentedMp4Extractor(
|
||||||
FragmentedMp4Extractor.FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME
|
FragmentedMp4Extractor.FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME
|
||||||
|
@ -65,14 +65,14 @@ public class SmoothStreamingManifest {
|
|||||||
public final StreamElement[] streamElements;
|
public final StreamElement[] streamElements;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The overall presentation duration of the media in microseconds, or {@link C#UNKNOWN_TIME_US}
|
* The overall presentation duration of the media in microseconds, or {@link C#UNSET_TIME_US}
|
||||||
* if the duration is unknown.
|
* if the duration is unknown.
|
||||||
*/
|
*/
|
||||||
public final long durationUs;
|
public final long durationUs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The length of the trailing window for a live broadcast in microseconds, or
|
* The length of the trailing window for a live broadcast in microseconds, or
|
||||||
* {@link C#UNKNOWN_TIME_US} if the stream is not live or if the window length is unspecified.
|
* {@link C#UNSET_TIME_US} if the stream is not live or if the window length is unspecified.
|
||||||
*/
|
*/
|
||||||
public final long dvrWindowLengthUs;
|
public final long dvrWindowLengthUs;
|
||||||
|
|
||||||
@ -101,9 +101,9 @@ public class SmoothStreamingManifest {
|
|||||||
this.isLive = isLive;
|
this.isLive = isLive;
|
||||||
this.protectionElement = protectionElement;
|
this.protectionElement = protectionElement;
|
||||||
this.streamElements = streamElements;
|
this.streamElements = streamElements;
|
||||||
dvrWindowLengthUs = dvrWindowLength == 0 ? C.UNKNOWN_TIME_US
|
dvrWindowLengthUs = dvrWindowLength == 0 ? C.UNSET_TIME_US
|
||||||
: Util.scaleLargeTimestamp(dvrWindowLength, C.MICROS_PER_SECOND, timescale);
|
: Util.scaleLargeTimestamp(dvrWindowLength, C.MICROS_PER_SECOND, timescale);
|
||||||
durationUs = duration == 0 ? C.UNKNOWN_TIME_US
|
durationUs = duration == 0 ? C.UNSET_TIME_US
|
||||||
: Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, timescale);
|
: Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, timescale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,11 +341,11 @@ public final class Eia608TrackRenderer extends TrackRenderer implements Callback
|
|||||||
|
|
||||||
private void clearPendingBuffer() {
|
private void clearPendingBuffer() {
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
buffer.timeUs = C.UNKNOWN_TIME_US;
|
buffer.timeUs = C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBufferPending() {
|
private boolean isBufferPending() {
|
||||||
return buffer.timeUs != C.UNKNOWN_TIME_US;
|
return buffer.timeUs != C.UNSET_TIME_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user