Commit 1579b68c by olly Committed by Oliver Woodman

Sanitize constants

- Use a single constant for unset/unknown times across
  all time bases. Note also that this moves away from
  use of -1 for unset/unknown times in ms, which was a
  bad choice (it might conflict with real times, such
  as a time representing being just behind the start
  of a live window).
- Add a few other unset constants, and use them.
- Fix some hardcoding of -1 where existing constants
  should have been used.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=130775594
parent 725337da
Showing with 536 additions and 545 deletions
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.demo;
import android.os.SystemClock;
import android.util.Log;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format;
......@@ -375,16 +376,16 @@ import java.util.Locale;
if (format.bitrate != Format.NO_VALUE) {
builder.append(", bitrate=").append(format.bitrate);
}
if (format.width != -1 && format.height != -1) {
if (format.width != Format.NO_VALUE && format.height != Format.NO_VALUE) {
builder.append(", res=").append(format.width).append("x").append(format.height);
}
if (format.frameRate != -1) {
if (format.frameRate != Format.NO_VALUE) {
builder.append(", fps=").append(format.frameRate);
}
if (format.channelCount != -1) {
if (format.channelCount != Format.NO_VALUE) {
builder.append(", channels=").append(format.channelCount);
}
if (format.sampleRate != -1) {
if (format.sampleRate != Format.NO_VALUE) {
builder.append(", sample_rate=").append(format.sampleRate);
}
if (format.language != null) {
......@@ -396,7 +397,7 @@ import java.util.Locale;
private static String getTrackStatusString(TrackSelection selection, TrackGroup group,
int trackIndex) {
return getTrackStatusString(selection != null && selection.getTrackGroup() == group
&& selection.indexOf(trackIndex) != -1);
&& selection.indexOf(trackIndex) != C.INDEX_UNSET);
}
private static String getTrackStatusString(boolean enabled) {
......
......@@ -281,7 +281,7 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi
player.setVideoListener(this);
player.setVideoSurfaceHolder(surfaceView.getHolder());
if (shouldRestorePosition) {
if (playerPosition == -1) {
if (playerPosition == C.TIME_UNSET) {
player.seekToDefaultPositionForPeriod(playerPeriod);
} else {
player.seekInPeriod(playerPeriod, playerPosition);
......@@ -381,7 +381,7 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi
if (!window.isDynamic) {
shouldRestorePosition = true;
playerPeriod = player.getCurrentPeriodIndex();
playerPosition = window.isSeekable ? player.getCurrentPositionInPeriod() : -1;
playerPosition = window.isSeekable ? player.getCurrentPositionInPeriod() : C.TIME_UNSET;
}
}
player.release();
......
......@@ -180,9 +180,8 @@ public class OkHttpDataSource implements HttpDataSource {
// Determine the length of the data to be read, after skipping.
long contentLength = response.body().contentLength();
bytesToRead = dataSpec.length != C.LENGTH_UNBOUNDED ? dataSpec.length
: contentLength != -1 ? contentLength - bytesToSkip
: C.LENGTH_UNBOUNDED;
bytesToRead = dataSpec.length != C.LENGTH_UNSET ? dataSpec.length
: (contentLength != -1 ? (contentLength - bytesToSkip) : C.LENGTH_UNSET);
opened = true;
if (listener != null) {
......@@ -237,12 +236,12 @@ public class OkHttpDataSource implements HttpDataSource {
* Returns the number of bytes that are still to be read for the current {@link DataSpec}.
* <p>
* If the total length of the data being read is known, then this length minus {@code bytesRead()}
* is returned. If the total length is unknown, {@link C#LENGTH_UNBOUNDED} is returned.
* is returned. If the total length is unknown, {@link C#LENGTH_UNSET} is returned.
*
* @return The remaining length, or {@link C#LENGTH_UNBOUNDED}.
* @return The remaining length, or {@link C#LENGTH_UNSET}.
*/
protected final long bytesRemaining() {
return bytesToRead == C.LENGTH_UNBOUNDED ? bytesToRead : bytesToRead - bytesRead;
return bytesToRead == C.LENGTH_UNSET ? bytesToRead : bytesToRead - bytesRead;
}
/**
......@@ -263,9 +262,9 @@ public class OkHttpDataSource implements HttpDataSource {
builder.addHeader(property.getKey(), property.getValue());
}
}
if (!(position == 0 && length == C.LENGTH_UNBOUNDED)) {
if (!(position == 0 && length == C.LENGTH_UNSET)) {
String rangeRequest = "bytes=" + position + "-";
if (length != C.LENGTH_UNBOUNDED) {
if (length != C.LENGTH_UNSET) {
rangeRequest += (position + length - 1);
}
builder.addHeader("Range", rangeRequest);
......@@ -333,7 +332,7 @@ public class OkHttpDataSource implements HttpDataSource {
* @throws IOException If an error occurs reading from the source.
*/
private int readInternal(byte[] buffer, int offset, int readLength) throws IOException {
readLength = bytesToRead == C.LENGTH_UNBOUNDED ? readLength
readLength = bytesToRead == C.LENGTH_UNSET ? readLength
: (int) Math.min(readLength, bytesToRead - bytesRead);
if (readLength == 0) {
// We've read all of the requested data.
......@@ -342,7 +341,7 @@ public class OkHttpDataSource implements HttpDataSource {
int read = responseByteStream.read(buffer, offset, readLength);
if (read == -1) {
if (bytesToRead != C.LENGTH_UNBOUNDED && bytesToRead != bytesRead) {
if (bytesToRead != C.LENGTH_UNSET && bytesToRead != bytesRead) {
// The server closed the connection having not sent sufficient data.
throw new EOFException();
}
......
......@@ -36,7 +36,7 @@ public class DefaultExtractorInputTest extends TestCase {
public void testInitialPosition() throws IOException {
FakeDataSource testDataSource = buildDataSource();
DefaultExtractorInput input =
new DefaultExtractorInput(testDataSource, 123, C.LENGTH_UNBOUNDED);
new DefaultExtractorInput(testDataSource, 123, C.LENGTH_UNSET);
assertEquals(123, input.getPosition());
}
......@@ -55,7 +55,7 @@ public class DefaultExtractorInputTest extends TestCase {
assertTrue(Arrays.equals(TEST_DATA, target));
// Check we're now indicated that the end of input is reached.
int expectedEndOfInput = input.read(target, 0, TEST_DATA.length);
assertEquals(-1, expectedEndOfInput);
assertEquals(C.RESULT_END_OF_INPUT, expectedEndOfInput);
}
public void testReadPeeked() throws IOException, InterruptedException {
......@@ -143,7 +143,7 @@ public class DefaultExtractorInputTest extends TestCase {
public void testReadFullyWithFailingDataSource() throws IOException, InterruptedException {
FakeDataSource testDataSource = buildFailingDataSource();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
try {
byte[] target = new byte[TEST_DATA.length];
input.readFully(target, 0, TEST_DATA.length);
......@@ -170,19 +170,19 @@ public class DefaultExtractorInputTest extends TestCase {
public void testSkip() throws IOException, InterruptedException {
FakeDataSource testDataSource = buildDataSource();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
// We expect to perform three skips of three bytes, as setup in buildTestDataSource.
for (int i = 0; i < 3; i++) {
assertEquals(3, input.skip(TEST_DATA.length));
}
// Check we're now indicated that the end of input is reached.
int expectedEndOfInput = input.skip(TEST_DATA.length);
assertEquals(-1, expectedEndOfInput);
assertEquals(C.RESULT_END_OF_INPUT, expectedEndOfInput);
}
public void testLargeSkip() throws IOException, InterruptedException {
FakeDataSource testDataSource = buildLargeDataSource();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
// Check that skipping the entire data source succeeds.
int bytesToSkip = LARGE_TEST_DATA_LENGTH;
while (bytesToSkip > 0) {
......@@ -255,7 +255,7 @@ public class DefaultExtractorInputTest extends TestCase {
public void testSkipFullyWithFailingDataSource() throws IOException, InterruptedException {
FakeDataSource testDataSource = buildFailingDataSource();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
try {
input.skipFully(TEST_DATA.length);
fail();
......@@ -274,7 +274,7 @@ public class DefaultExtractorInputTest extends TestCase {
FakeDataSource testDataSource = builder.build();
testDataSource.open(new DataSpec(Uri.parse(TEST_URI)));
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
input.skipFully(largeSkipSize);
assertEquals(largeSkipSize, input.getPosition());
// Check that we fail with EOFException we skip again.
......@@ -412,6 +412,6 @@ public class DefaultExtractorInputTest extends TestCase {
private static DefaultExtractorInput createDefaultExtractorInput() throws IOException {
FakeDataSource testDataSource = buildDataSource();
return new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
return new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
}
}
......@@ -201,6 +201,10 @@ public final class VarintReaderTest extends TestCase {
while (result == -1) {
try {
result = reader.readUnsignedVarint(input, false, removeMask, 8);
if (result == C.RESULT_END_OF_INPUT || result == C.RESULT_MAX_LENGTH_EXCEEDED) {
// Unexpected.
fail();
}
} catch (SimulatedIOException e) {
// Expected.
}
......
......@@ -56,7 +56,7 @@ public final class XingSeekerTest extends InstrumentationTestCase {
MpegAudioHeader xingFrameHeader = new MpegAudioHeader();
MpegAudioHeader.populateHeader(XING_FRAME_HEADER_DATA, xingFrameHeader);
seeker = XingSeeker.create(xingFrameHeader, new ParsableByteArray(XING_FRAME_PAYLOAD),
XING_FRAME_POSITION, C.LENGTH_UNBOUNDED);
XING_FRAME_POSITION, C.LENGTH_UNSET);
seekerWithInputLength = XingSeeker.create(xingFrameHeader,
new ParsableByteArray(XING_FRAME_PAYLOAD), XING_FRAME_POSITION, INPUT_LENGTH);
xingFrameSize = xingFrameHeader.frameSize;
......
......@@ -29,7 +29,7 @@ public final class DefaultOggSeekerTest extends TestCase {
public void testSetupUnboundAudioLength() {
try {
new DefaultOggSeeker(0, C.LENGTH_UNBOUNDED, new TestStreamReader());
new DefaultOggSeeker(0, C.LENGTH_UNSET, new TestStreamReader());
fail();
} catch (IllegalArgumentException e) {
// ignored
......
......@@ -23,7 +23,7 @@ import junit.framework.Assert;
/**
* Generates test data.
*/
class OggTestFile {
/* package */ final class OggTestFile {
public static final int MAX_PACKET_LENGTH = 2048;
public static final int MAX_SEGMENT_COUNT = 10;
......@@ -41,7 +41,7 @@ class OggTestFile {
this.pageCount = pageCount;
}
static OggTestFile generate(Random random, int pageCount) {
public static OggTestFile generate(Random random, int pageCount) {
ArrayList<byte[]> fileData = new ArrayList<>();
int fileSize = 0;
long granule = 0;
......@@ -100,7 +100,7 @@ class OggTestFile {
return new OggTestFile(file, granule, packetCount, pageCount);
}
int findPreviousPageStart(long position) {
public int findPreviousPageStart(long position) {
for (int i = (int) (position - 4); i >= 0; i--) {
if (data[i] == 'O' && data[i + 1] == 'g' && data[i + 2] == 'g' && data[i + 3] == 'S') {
return i;
......@@ -109,4 +109,5 @@ class OggTestFile {
Assert.fail();
return -1;
}
}
......@@ -32,7 +32,6 @@ public final class VorbisUtilTest extends TestCase {
assertEquals(3, VorbisUtil.iLog(4));
assertEquals(3, VorbisUtil.iLog(5));
assertEquals(4, VorbisUtil.iLog(8));
assertEquals(0, VorbisUtil.iLog(-1));
assertEquals(0, VorbisUtil.iLog(-122));
}
......@@ -40,7 +39,6 @@ public final class VorbisUtilTest extends TestCase {
public void testReadIdHeader() throws Exception {
byte[] data = TestData.getIdentificationHeaderData();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.VorbisIdHeader vorbisIdHeader =
VorbisUtil.readVorbisIdentificationHeader(headerData);
......@@ -59,8 +57,8 @@ public final class VorbisUtilTest extends TestCase {
public void testReadCommentHeader() throws ParserException {
byte[] data = TestData.getCommentHeaderDataUTF8();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.CommentHeader commentHeader = VorbisUtil.readVorbisCommentHeader(headerData);
assertEquals("Xiph.Org libVorbis I 20120203 (Omnipresent)", commentHeader.vendor);
assertEquals(3, commentHeader.comments.length);
assertEquals("ALBUM=äö", commentHeader.comments[0]);
......@@ -71,16 +69,13 @@ public final class VorbisUtilTest extends TestCase {
public void testReadVorbisModes() throws ParserException {
byte[] data = TestData.getSetupHeaderData();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.Mode[] modes = VorbisUtil.readVorbisModes(headerData, 2);
assertEquals(2, modes.length);
assertEquals(false, modes[0].blockFlag);
assertEquals(0, modes[0].mapping);
assertEquals(0, modes[0].transformType);
assertEquals(0, modes[0].windowType);
assertEquals(true, modes[1].blockFlag);
assertEquals(1, modes[1].mapping);
assertEquals(0, modes[1].transformType);
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.C;
import junit.framework.TestCase;
/**
......@@ -33,8 +34,8 @@ public class RangedUriTest extends TestCase {
public void testMergeUnbounded() {
RangedUri rangeA = new RangedUri(null, FULL_URI, 0, 10);
RangedUri rangeB = new RangedUri(null, FULL_URI, 10, -1);
RangedUri expected = new RangedUri(null, FULL_URI, 0, -1);
RangedUri rangeB = new RangedUri(null, FULL_URI, 10, C.LENGTH_UNSET);
RangedUri expected = new RangedUri(null, FULL_URI, 0, C.LENGTH_UNSET);
assertMerge(rangeA, rangeB, expected);
}
......@@ -46,7 +47,7 @@ public class RangedUriTest extends TestCase {
// A and B do not overlap, so should not merge
rangeA = new RangedUri(null, FULL_URI, 0, 10);
rangeB = new RangedUri(null, FULL_URI, 11, -1);
rangeB = new RangedUri(null, FULL_URI, 11, C.LENGTH_UNSET);
assertNonMerge(rangeA, rangeB);
// A and B are bounded but overlap, so should not merge
......@@ -55,8 +56,8 @@ public class RangedUriTest extends TestCase {
assertNonMerge(rangeA, rangeB);
// A and B overlap due to unboundedness, so should not merge
rangeA = new RangedUri(null, FULL_URI, 0, -1);
rangeB = new RangedUri(null, FULL_URI, 10, -1);
rangeA = new RangedUri(null, FULL_URI, 0, C.LENGTH_UNSET);
rangeB = new RangedUri(null, FULL_URI, 10, C.LENGTH_UNSET);
assertNonMerge(rangeA, rangeB);
}
......
......@@ -35,7 +35,8 @@ public class RepresentationTest extends TestCase {
format = Format.createVideoContainerFormat("150", MimeTypes.APPLICATION_MP4, null,
MimeTypes.VIDEO_H264, 2500000, 1920, 1080, Format.NO_VALUE, null);
representation = Representation.newInstance("test_stream_1", -1, format, base);
representation = Representation.newInstance("test_stream_1", Representation.REVISION_ID_DEFAULT,
format, base);
assertEquals("test_stream_1.150.-1", representation.getCacheKey());
}
......
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source.hls.playlist;
import android.net.Uri;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
......@@ -79,15 +80,15 @@ public class HlsMasterPlaylistParserTest extends TestCase {
assertEquals(7680000, variants.get(3).format.bitrate);
assertEquals(null, variants.get(3).codecs);
assertEquals(-1, variants.get(3).format.width);
assertEquals(-1, variants.get(3).format.height);
assertEquals(Format.NO_VALUE, variants.get(3).format.width);
assertEquals(Format.NO_VALUE, variants.get(3).format.height);
assertEquals("http://example.com/hi.m3u8", variants.get(3).url);
assertEquals(65000, variants.get(4).format.bitrate);
assertNotNull(variants.get(4).codecs);
assertEquals("mp4a.40.5", variants.get(4).codecs);
assertEquals(-1, variants.get(4).format.width);
assertEquals(-1, variants.get(4).format.height);
assertEquals(Format.NO_VALUE, variants.get(4).format.width);
assertEquals(Format.NO_VALUE, variants.get(4).format.height);
assertEquals("http://example.com/audio-only.m3u8", variants.get(4).url);
} catch (IOException exception) {
fail(exception.getMessage());
......
......@@ -124,7 +124,7 @@ public class HlsMediaPlaylistParserTest extends TestCase {
// 0xA7B == 2683.
assertNotNull(segments.get(4).encryptionIV);
assertEquals("A7B", segments.get(4).encryptionIV.toUpperCase(Locale.getDefault()));
assertEquals(C.LENGTH_UNBOUNDED, segments.get(4).byterangeLength);
assertEquals(C.LENGTH_UNSET, segments.get(4).byterangeLength);
assertEquals(0, segments.get(4).byterangeOffset);
assertEquals("https://priv.example.com/fileSequence2683.ts", segments.get(4).url);
} catch (IOException exception) {
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.text.webvtt;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.text.Cue;
import java.util.ArrayList;
import java.util.Collections;
......@@ -208,9 +209,9 @@ public class WebvttSubtitleTest extends TestCase {
assertEquals(3, subtitle.getNextEventTimeIndex(3999999));
// Test null event (i.e. look for events after the last event)
assertEquals(-1, subtitle.getNextEventTimeIndex(4000000));
assertEquals(-1, subtitle.getNextEventTimeIndex(4500000));
assertEquals(-1, subtitle.getNextEventTimeIndex(Long.MAX_VALUE));
assertEquals(C.INDEX_UNSET, subtitle.getNextEventTimeIndex(4000000));
assertEquals(C.INDEX_UNSET, subtitle.getNextEventTimeIndex(4500000));
assertEquals(C.INDEX_UNSET, subtitle.getNextEventTimeIndex(Long.MAX_VALUE));
}
private void assertSingleCueEmpty(List<Cue> cues) {
......
......@@ -28,11 +28,11 @@ public class ByteArrayDataSourceTest extends TestCase {
private static final byte[] TEST_DATA_ODD = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
public void testFullReadSingleBytes() {
readTestData(TEST_DATA, 0, C.LENGTH_UNBOUNDED, 1, 0, 1, false);
readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 1, 0, 1, false);
}
public void testFullReadAllBytes() {
readTestData(TEST_DATA, 0, C.LENGTH_UNBOUNDED, 100, 0, 100, false);
readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 100, 0, 100, false);
}
public void testLimitReadSingleBytes() {
......@@ -44,9 +44,9 @@ public class ByteArrayDataSourceTest extends TestCase {
public void testFullReadTwoBytes() {
// Try with the total data length an exact multiple of the size of each individual read.
readTestData(TEST_DATA, 0, C.LENGTH_UNBOUNDED, 2, 0, 2, false);
readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 2, 0, 2, false);
// And not.
readTestData(TEST_DATA_ODD, 0, C.LENGTH_UNBOUNDED, 2, 0, 2, false);
readTestData(TEST_DATA_ODD, 0, C.LENGTH_UNSET, 2, 0, 2, false);
}
public void testLimitReadTwoBytes() {
......@@ -58,18 +58,18 @@ public class ByteArrayDataSourceTest extends TestCase {
public void testReadFromValidOffsets() {
// Read from an offset without bound.
readTestData(TEST_DATA, 1, C.LENGTH_UNBOUNDED, 1, 0, 1, false);
readTestData(TEST_DATA, 1, C.LENGTH_UNSET, 1, 0, 1, false);
// And with bound.
readTestData(TEST_DATA, 1, 6, 1, 0, 1, false);
// Read from the last possible offset without bound.
readTestData(TEST_DATA, TEST_DATA.length - 1, C.LENGTH_UNBOUNDED, 1, 0, 1, false);
readTestData(TEST_DATA, TEST_DATA.length - 1, C.LENGTH_UNSET, 1, 0, 1, false);
// And with bound.
readTestData(TEST_DATA, TEST_DATA.length - 1, 1, 1, 0, 1, false);
}
public void testReadFromInvalidOffsets() {
// Read from first invalid offset and check failure without bound.
readTestData(TEST_DATA, TEST_DATA.length, C.LENGTH_UNBOUNDED, 1, 0, 1, true);
readTestData(TEST_DATA, TEST_DATA.length, C.LENGTH_UNSET, 1, 0, 1, true);
// And with bound.
readTestData(TEST_DATA, TEST_DATA.length, 1, 1, 0, 1, true);
}
......@@ -95,7 +95,7 @@ public class ByteArrayDataSourceTest extends TestCase {
private void readTestData(byte[] testData, int dataOffset, int dataLength, int outputBufferLength,
int writeOffset, int maxReadLength, boolean expectFailOnOpen) {
int expectedFinalBytesRead =
dataLength == C.LENGTH_UNBOUNDED ? (testData.length - dataOffset) : dataLength;
dataLength == C.LENGTH_UNSET ? (testData.length - dataOffset) : dataLength;
ByteArrayDataSource dataSource = new ByteArrayDataSource(testData);
boolean opened = false;
try {
......@@ -116,7 +116,7 @@ public class ByteArrayDataSourceTest extends TestCase {
assertTrue(requestedReadLength > 0);
int bytesRead = dataSource.read(outputBuffer, writeOffset, requestedReadLength);
if (bytesRead != -1) {
if (bytesRead != C.RESULT_END_OF_INPUT) {
assertTrue(bytesRead > 0);
assertTrue(bytesRead <= requestedReadLength);
// Check the data read was correct.
......
......@@ -59,11 +59,11 @@ public final class ExoPlaybackException extends Exception {
}
public static ExoPlaybackException createForSource(IOException cause) {
return new ExoPlaybackException(TYPE_SOURCE, null, cause, -1);
return new ExoPlaybackException(TYPE_SOURCE, null, cause, C.INDEX_UNSET);
}
/* package */ static ExoPlaybackException createForUnexpected(RuntimeException cause) {
return new ExoPlaybackException(TYPE_UNEXPECTED, null, cause, -1);
return new ExoPlaybackException(TYPE_UNEXPECTED, null, cause, C.INDEX_UNSET);
}
private ExoPlaybackException(int type, String message, Throwable cause, int rendererIndex) {
......
......@@ -208,11 +208,6 @@ public interface ExoPlayer {
int STATE_ENDED = 4;
/**
* Represents an unknown time or duration.
*/
long UNKNOWN_TIME = -1;
/**
* Register a listener to receive events from the player. The listener's methods will be called on
* the thread that was used to construct the player.
*
......@@ -391,7 +386,7 @@ public interface ExoPlayer {
int getCurrentPeriodIndex();
/**
* Returns the duration of the current period in milliseconds, or {@link #UNKNOWN_TIME} if the
* Returns the duration of the current period in milliseconds, or {@link C#TIME_UNSET} if the
* duration is not known.
*/
@Deprecated
......@@ -405,7 +400,7 @@ public interface ExoPlayer {
/**
* Returns an estimate of the position in the current period up to which data is buffered, or
* {@link #UNKNOWN_TIME} if no estimate is available.
* {@link C#TIME_UNSET} if no estimate is available.
*/
@Deprecated
long getBufferedPositionInPeriod();
......@@ -420,26 +415,26 @@ public interface ExoPlayer {
// Window based.
/**
* Returns the index of the seek window associated with the current period, or -1 if the timeline
* is not set.
* Returns the index of the seek window associated with the current period, or
* {@link C#INDEX_UNSET} if the timeline is not set.
*/
int getCurrentWindowIndex();
/**
* Returns the duration of the current window in milliseconds, or {@link #UNKNOWN_TIME} if the
* Returns the duration of the current window in milliseconds, or {@link C#TIME_UNSET} if the
* duration is not known.
*/
long getDuration();
/**
* Returns the playback position in the current seek window, in milliseconds, or
* {@link #UNKNOWN_TIME} if the timeline is not set.
* {@link C#TIME_UNSET} if the timeline is not set.
*/
long getCurrentPosition();
/**
* Returns an estimate of the position in the current window up to which data is buffered, or
* {@link #UNKNOWN_TIME} if no estimate is available.
* {@link C#TIME_UNSET} if no estimate is available.
*/
long getBufferedPosition();
......
......@@ -133,16 +133,16 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public void seekToDefaultPositionForPeriod(int periodIndex) {
seekInPeriod(periodIndex, UNKNOWN_TIME);
seekInPeriod(periodIndex, C.TIME_UNSET);
}
@Override
public void seekInPeriod(int periodIndex, long positionMs) {
boolean seekToDefaultPosition = positionMs == UNKNOWN_TIME;
boolean seekToDefaultPosition = positionMs == C.TIME_UNSET;
maskingPeriodIndex = periodIndex;
maskingPositionMs = seekToDefaultPosition ? 0 : positionMs;
pendingSeekAcks++;
internalPlayer.seekTo(periodIndex, seekToDefaultPosition ? C.UNSET_TIME_US : positionMs * 1000);
internalPlayer.seekTo(periodIndex, seekToDefaultPosition ? C.TIME_UNSET : positionMs * 1000);
if (!seekToDefaultPosition) {
for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(periodIndex, positionMs);
......@@ -186,7 +186,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
long periodPositionMs = timeline.getWindowOffsetInFirstPeriodUs(windowIndex) / 1000
+ positionMs;
long periodDurationMs = timeline.getPeriodDurationMs(periodIndex);
while (periodDurationMs != UNKNOWN_TIME && periodPositionMs >= periodDurationMs
while (periodDurationMs != C.TIME_UNSET && periodPositionMs >= periodDurationMs
&& periodIndex < lastPeriodIndex) {
periodPositionMs -= periodDurationMs;
periodDurationMs = timeline.getPeriodDurationMs(++periodIndex);
......@@ -225,7 +225,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Deprecated
public long getCurrentPeriodDuration() {
if (timeline == null) {
return UNKNOWN_TIME;
return C.TIME_UNSET;
}
return timeline.getPeriodDurationMs(getCurrentPeriodIndex());
}
......@@ -233,16 +233,14 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
@Deprecated
public long getCurrentPositionInPeriod() {
return pendingSeekAcks > 0 ? maskingPositionMs
: playbackInfo.positionUs == C.UNSET_TIME_US ? 0 : (playbackInfo.positionUs / 1000);
return pendingSeekAcks > 0 ? maskingPositionMs : C.usToMs(playbackInfo.positionUs);
}
@Override
@Deprecated
public long getBufferedPositionInPeriod() {
if (pendingSeekAcks == 0) {
long bufferedPositionUs = playbackInfo.bufferedPositionUs;
return bufferedPositionUs == C.UNSET_TIME_US ? UNKNOWN_TIME : (bufferedPositionUs / 1000);
return C.usToMs(playbackInfo.bufferedPositionUs);
} else {
return maskingPositionMs;
}
......@@ -256,14 +254,14 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
long bufferedPosition = getBufferedPositionInPeriod();
long duration = getCurrentPeriodDuration();
return bufferedPosition == ExoPlayer.UNKNOWN_TIME || duration == ExoPlayer.UNKNOWN_TIME ? 0
return (bufferedPosition == C.TIME_UNSET || duration == C.TIME_UNSET) ? 0
: (int) (duration == 0 ? 100 : (bufferedPosition * 100) / duration);
}
@Override
public int getCurrentWindowIndex() {
if (timeline == null) {
return -1;
return C.INDEX_UNSET;
}
return timeline.getPeriodWindowIndex(getCurrentPeriodIndex());
}
......@@ -271,16 +269,15 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public long getDuration() {
if (timeline == null) {
return UNKNOWN_TIME;
return C.TIME_UNSET;
}
long durationUs = timeline.getWindow(getCurrentWindowIndex()).durationUs;
return durationUs == C.UNSET_TIME_US ? ExoPlayer.UNKNOWN_TIME : durationUs / 1000;
return C.usToMs(timeline.getWindow(getCurrentWindowIndex()).durationUs);
}
@Override
public long getCurrentPosition() {
if (timeline == null) {
return UNKNOWN_TIME;
return C.TIME_UNSET;
}
int periodIndex = getCurrentPeriodIndex();
int windowIndex = timeline.getPeriodWindowIndex(periodIndex);
......@@ -296,7 +293,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
public long getBufferedPosition() {
// TODO - Implement this properly.
if (timeline == null) {
return UNKNOWN_TIME;
return C.TIME_UNSET;
}
int periodIndex = getCurrentPeriodIndex();
int windowIndex = timeline.getPeriodWindowIndex(periodIndex);
......@@ -318,7 +315,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
long bufferedPosition = getBufferedPosition();
long duration = getDuration();
return bufferedPosition == ExoPlayer.UNKNOWN_TIME || duration == ExoPlayer.UNKNOWN_TIME ? 0
return (bufferedPosition == C.TIME_UNSET || duration == C.TIME_UNSET) ? 0
: (int) (duration == 0 ? 100 : (bufferedPosition * 100) / duration);
}
......@@ -352,8 +349,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
case ExoPlayerImplInternal.MSG_SEEK_ACK: {
if (--pendingSeekAcks == 0) {
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
long positionMs = playbackInfo.startPositionUs == C.UNSET_TIME_US ? 0
: playbackInfo.startPositionUs / 1000;
long positionMs = C.usToMs(playbackInfo.startPositionUs);
if (playbackInfo.periodIndex != maskingPeriodIndex || positionMs != maskingPositionMs) {
for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(playbackInfo.periodIndex, positionMs);
......@@ -367,7 +363,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(playbackInfo.periodIndex,
playbackInfo.startPositionUs / 1000);
C.usToMs(playbackInfo.startPositionUs));
}
}
break;
......
......@@ -21,12 +21,6 @@ package com.google.android.exoplayer2;
public interface Timeline {
/**
* Returned by {@link #getIndexOfPeriod(Object)} if no period index corresponds to the specified
* identifier.
*/
int NO_PERIOD_INDEX = -1;
/**
* Returns the number of periods in the timeline.
*/
int getPeriodCount();
......@@ -38,19 +32,19 @@ public interface Timeline {
/**
* Returns the duration of the period at {@code periodIndex} in the timeline, in milliseconds, or
* {@link ExoPlayer#UNKNOWN_TIME} if not known.
* {@link C#TIME_UNSET} if not known.
*
* @param periodIndex The index of the period.
* @return The duration of the period in milliseconds, or {@link ExoPlayer#UNKNOWN_TIME}.
* @return The duration of the period in milliseconds, or {@link C#TIME_UNSET}.
*/
long getPeriodDurationMs(int periodIndex);
/**
* Returns the duration of the period at {@code periodIndex} in the timeline, in microseconds, or
* {@link C#UNSET_TIME_US} if not known.
* {@link C#TIME_UNSET} if not known.
*
* @param periodIndex The index of the period.
* @return The duration of the period in microseconds, or {@link C#UNSET_TIME_US}.
* @return The duration of the period in microseconds, or {@link C#TIME_UNSET}.
*/
long getPeriodDurationUs(int periodIndex);
......@@ -81,11 +75,11 @@ public interface Timeline {
int getPeriodWindowIndex(int periodIndex);
/**
* Returns the index of the period identified by {@code id}, or {@link #NO_PERIOD_INDEX} if the
* Returns the index of the period identified by {@code id}, or {@link C#INDEX_UNSET} if the
* period is not in the timeline.
*
* @param id An identifier for a period.
* @return The index of the period, or {@link #NO_PERIOD_INDEX} if the period was not found.
* @return The index of the period, or {@link C#INDEX_UNSET} if the period was not found.
*/
int getIndexOfPeriod(Object id);
......
......@@ -39,7 +39,7 @@ public final class Window {
*/
public final long defaultStartPositionUs;
/**
* The duration of the window in microseconds, or {@link C#UNSET_TIME_US} if unknown.
* The duration of the window in microseconds, or {@link C#TIME_UNSET} if unknown.
*/
public final long durationUs;
/**
......@@ -52,7 +52,7 @@ public final class Window {
public final boolean isDynamic;
/**
* @param durationUs The duration of the window in microseconds, or {@link C#UNSET_TIME_US} if
* @param durationUs The duration of the window in microseconds, or {@link C#TIME_UNSET} if
* unknown.
* @param isSeekable Whether seeking is supported within the window.
* @param isDynamic Whether this seek window may change when the timeline is updated.
......
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.audio;
import android.os.Handler;
import android.os.SystemClock;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.decoder.DecoderCounters;
......@@ -65,8 +66,8 @@ public interface AudioRendererEventListener {
*
* @param bufferSize The size of the {@link AudioTrack}'s buffer, in bytes.
* @param bufferSizeMs The size of the {@link AudioTrack}'s buffer, in milliseconds, if it is
* configured for PCM output. -1 if it is configured for passthrough output, as the buffered
* media can have a variable bitrate so the duration may be unknown.
* configured for PCM output. {@link C#TIME_UNSET} if it is configured for passthrough output,
* as the buffered media can have a variable bitrate so the duration may be unknown.
* @param elapsedSinceLastFeedMs The time since the {@link AudioTrack} was last fed data.
*/
void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs);
......@@ -183,7 +184,7 @@ public interface AudioRendererEventListener {
});
}
}
}
}
......@@ -427,7 +427,7 @@ public final class AudioTrack {
: multipliedBufferSize > maxAppBufferSize ? maxAppBufferSize
: multipliedBufferSize;
}
bufferSizeUs = passthrough ? C.UNSET_TIME_US : framesToDurationUs(pcmBytesToFrames(bufferSize));
bufferSizeUs = passthrough ? C.TIME_UNSET : framesToDurationUs(pcmBytesToFrames(bufferSize));
}
/**
......@@ -494,13 +494,13 @@ public final class AudioTrack {
/**
* Returns the size of the buffer in microseconds for PCM {@link AudioTrack}s, or
* {@link C#UNSET_TIME_US} for passthrough {@link AudioTrack}s.
* {@link C#TIME_UNSET} for passthrough {@link AudioTrack}s.
* <p>
* The value returned from this method may change as a result of calling one of the
* {@link #configure} methods.
*
* @return The size of the buffer in microseconds for PCM {@link AudioTrack}s, or
* {@link C#UNSET_TIME_US} for passthrough {@link AudioTrack}s.
* {@link C#TIME_UNSET} for passthrough {@link AudioTrack}s.
*/
public long getBufferSizeUs() {
return bufferSizeUs;
......@@ -1088,7 +1088,7 @@ public final class AudioTrack {
boolean needsPassthroughWorkaround) {
this.audioTrack = audioTrack;
this.needsPassthroughWorkaround = needsPassthroughWorkaround;
stopTimestampUs = C.UNSET_TIME_US;
stopTimestampUs = C.TIME_UNSET;
lastRawPlaybackHeadPosition = 0;
rawPlaybackHeadWrapCount = 0;
passthroughWorkaroundPauseOffset = 0;
......@@ -1116,7 +1116,7 @@ public final class AudioTrack {
* this method does nothing.
*/
public void pause() {
if (stopTimestampUs != C.UNSET_TIME_US) {
if (stopTimestampUs != C.TIME_UNSET) {
// We don't want to knock the audio track back into the paused state.
return;
}
......@@ -1133,7 +1133,7 @@ public final class AudioTrack {
* expressed as a long.
*/
public long getPlaybackHeadPosition() {
if (stopTimestampUs != C.UNSET_TIME_US) {
if (stopTimestampUs != C.TIME_UNSET) {
// Simulate the playback head position up to the total number of frames submitted.
long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
long framesSinceStop = (elapsedTimeSinceStopUs * sampleRate) / C.MICROS_PER_SECOND;
......
......@@ -350,8 +350,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
audioTrackHasData = audioTrack.hasPendingData();
if (audioTrackHadData && !audioTrackHasData && getState() == STATE_STARTED) {
long elapsedSinceLastFeedMs = SystemClock.elapsedRealtime() - lastFeedElapsedRealtimeMs;
long bufferSizeUs = audioTrack.getBufferSizeUs();
long bufferSizeMs = bufferSizeUs == C.UNSET_TIME_US ? -1 : bufferSizeUs / 1000;
long bufferSizeMs = C.usToMs(audioTrack.getBufferSizeUs());
eventDispatcher.audioTrackUnderrun(audioTrack.getBufferSize(), bufferSizeMs,
elapsedSinceLastFeedMs);
}
......
......@@ -203,8 +203,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
audioTrackHasData = audioTrack.hasPendingData();
if (audioTrackHadData && !audioTrackHasData && getState() == STATE_STARTED) {
long elapsedSinceLastFeedMs = SystemClock.elapsedRealtime() - lastFeedElapsedRealtimeMs;
long bufferSizeUs = audioTrack.getBufferSizeUs();
long bufferSizeMs = bufferSizeUs == C.UNSET_TIME_US ? -1 : bufferSizeUs / 1000;
long bufferSizeMs = C.usToMs(audioTrack.getBufferSizeUs());
eventDispatcher.audioTrackUnderrun(audioTrack.getBufferSize(), bufferSizeMs,
elapsedSinceLastFeedMs);
}
......
......@@ -82,7 +82,7 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
dataSource.setRequestProperty(requestProperty.getKey(), requestProperty.getValue());
}
}
DataSpec dataSpec = new DataSpec(Uri.parse(url), data, 0, 0, C.LENGTH_UNBOUNDED, null,
DataSpec dataSpec = new DataSpec(Uri.parse(url), data, 0, 0, C.LENGTH_UNSET, null,
DataSpec.FLAG_ALLOW_GZIP);
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);
try {
......
......@@ -40,7 +40,7 @@ public final class DefaultExtractorInput implements ExtractorInput {
/**
* @param dataSource The wrapped {@link DataSource}.
* @param position The initial position in the stream.
* @param length The length of the stream, or {@link C#LENGTH_UNBOUNDED} if it is unknown.
* @param length The length of the stream, or {@link C#LENGTH_UNSET} if it is unknown.
*/
public DefaultExtractorInput(DataSource dataSource, long position, long length) {
this.dataSource = dataSource;
......
......@@ -233,7 +233,7 @@ public final class DefaultTrackOutput implements TrackOutput {
*/
public boolean skipToKeyframeBefore(long timeUs) {
long nextOffset = infoQueue.skipToKeyframeBefore(timeUs);
if (nextOffset == -1) {
if (nextOffset == C.POSITION_UNSET) {
return false;
}
dropDownstreamTo(nextOffset);
......@@ -785,17 +785,18 @@ public final class DefaultTrackOutput implements TrackOutput {
* Attempts to locate the keyframe before the specified time, if it's present in the buffer.
*
* @param timeUs The seek time.
* @return The offset of the keyframe's data if the keyframe was present. -1 otherwise.
* @return The offset of the keyframe's data if the keyframe was present.
* {@link C#POSITION_UNSET} otherwise.
*/
public synchronized long skipToKeyframeBefore(long timeUs) {
if (queueSize == 0 || timeUs < timesUs[relativeReadIndex]) {
return -1;
return C.POSITION_UNSET;
}
int lastWriteIndex = (relativeWriteIndex == 0 ? capacity : relativeWriteIndex) - 1;
long lastTimeUs = timesUs[lastWriteIndex];
if (timeUs > lastTimeUs) {
return -1;
return C.POSITION_UNSET;
}
// This could be optimized to use a binary search, however in practice callers to this method
......@@ -817,7 +818,7 @@ public final class DefaultTrackOutput implements TrackOutput {
}
if (sampleCountToKeyframe == -1) {
return -1;
return C.POSITION_UNSET;
}
queueSize -= sampleCountToKeyframe;
......
......@@ -216,9 +216,9 @@ public interface ExtractorInput {
long getPosition();
/**
* Returns the length of the source stream, or {@link C#LENGTH_UNBOUNDED} if it is unknown.
* Returns the length of the source stream, or {@link C#LENGTH_UNSET} if it is unknown.
*
* @return The length of the source stream, or {@link C#LENGTH_UNBOUNDED}.
* @return The length of the source stream, or {@link C#LENGTH_UNSET}.
*/
long getLength();
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.extractor;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.MimeTypes;
/**
......@@ -45,32 +46,33 @@ public final class MpegAudioHeader {
{8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160};
/**
* Returns the size of the frame associated with {@code header}, or -1 if it is invalid.
* Returns the size of the frame associated with {@code header}, or {@link C#LENGTH_UNSET} if it
* is invalid.
*/
public static int getFrameSize(int header) {
if ((header & 0xFFE00000) != 0xFFE00000) {
return -1;
return C.LENGTH_UNSET;
}
int version = (header >>> 19) & 3;
if (version == 1) {
return -1;
return C.LENGTH_UNSET;
}
int layer = (header >>> 17) & 3;
if (layer == 0) {
return -1;
return C.LENGTH_UNSET;
}
int bitrateIndex = (header >>> 12) & 15;
if (bitrateIndex == 0 || bitrateIndex == 0xF) {
// Disallow "free" bitrate.
return -1;
return C.LENGTH_UNSET;
}
int samplingRateIndex = (header >>> 10) & 3;
if (samplingRateIndex == 3) {
return -1;
return C.LENGTH_UNSET;
}
int samplingRate = SAMPLING_RATE_V1[samplingRateIndex];
......
......@@ -30,7 +30,7 @@ public interface SeekMap {
private final long durationUs;
/**
* @param durationUs The duration of the stream in microseconds, or {@link C#UNSET_TIME_US} if
* @param durationUs The duration of the stream in microseconds, or {@link C#TIME_UNSET} if
* the duration is unknown.
*/
public Unseekable(long durationUs) {
......@@ -67,7 +67,7 @@ public interface SeekMap {
/**
* Returns the duration of the stream in microseconds.
*
* @return The duration of the stream in microseconds, or {@link C#UNSET_TIME_US} if the
* @return The duration of the stream in microseconds, or {@link C#TIME_UNSET} if the
* duration is unknown.
*/
long getDurationUs();
......
......@@ -49,7 +49,7 @@ import java.util.Map;
*/
public ScriptTagPayloadReader(TrackOutput output) {
super(output);
durationUs = C.UNSET_TIME_US;
durationUs = C.TIME_UNSET;
}
public long getDurationUs() {
......
......@@ -150,7 +150,7 @@ import java.util.Stack;
while (true) {
input.peekFully(scratch, 0, MAX_ID_BYTES);
int varintLength = VarintReader.parseUnsignedVarintLength(scratch[0]);
if (varintLength != -1 && varintLength <= MAX_ID_BYTES) {
if (varintLength != C.LENGTH_UNSET && varintLength <= MAX_ID_BYTES) {
int potentialId = (int) VarintReader.assembleVarint(scratch, varintLength, false);
if (output.isLevel1Element(potentialId)) {
input.skipFully(varintLength);
......
......@@ -63,6 +63,8 @@ public final class MatroskaExtractor implements Extractor {
};
private static final int UNSET_ENTRY_ID = -1;
private static final int BLOCK_STATE_START = 0;
private static final int BLOCK_STATE_HEADER = 1;
private static final int BLOCK_STATE_DATA = 2;
......@@ -100,7 +102,6 @@ public final class MatroskaExtractor implements Extractor {
private static final int MP3_MAX_INPUT_SIZE = 4096;
private static final int ENCRYPTION_IV_SIZE = 8;
private static final int TRACK_TYPE_AUDIO = 2;
private static final int UNKNOWN = -1;
private static final int ID_EBML = 0x1A45DFA3;
private static final int ID_EBML_READ_VERSION = 0x42F7;
......@@ -228,11 +229,11 @@ public final class MatroskaExtractor implements Extractor {
private final ParsableByteArray encryptionSubsampleData;
private ByteBuffer encryptionSubsampleDataBuffer;
private long segmentContentPosition = UNKNOWN;
private long segmentContentSize = UNKNOWN;
private long timecodeScale = C.UNSET_TIME_US;
private long durationTimecode = C.UNSET_TIME_US;
private long durationUs = C.UNSET_TIME_US;
private long segmentContentSize;
private long segmentContentPosition = C.POSITION_UNSET;
private long timecodeScale = C.TIME_UNSET;
private long durationTimecode = C.TIME_UNSET;
private long durationUs = C.TIME_UNSET;
// The track corresponding to the current TrackEntry element, or null.
private Track currentTrack;
......@@ -246,9 +247,9 @@ public final class MatroskaExtractor implements Extractor {
// Cue related elements.
private boolean seekForCues;
private long cuesContentPosition = UNKNOWN;
private long seekPositionAfterBuildingCues = UNKNOWN;
private long clusterTimecodeUs = UNKNOWN;
private long cuesContentPosition = C.POSITION_UNSET;
private long seekPositionAfterBuildingCues = C.POSITION_UNSET;
private long clusterTimecodeUs = C.TIME_UNSET;
private LongArray cueTimesUs;
private LongArray cueClusterPositions;
private boolean seenClusterPositionForCurrentCuePoint;
......@@ -312,7 +313,7 @@ public final class MatroskaExtractor implements Extractor {
@Override
public void seek(long position) {
clusterTimecodeUs = UNKNOWN;
clusterTimecodeUs = C.TIME_UNSET;
blockState = BLOCK_STATE_START;
reader.reset();
varintReader.reset();
......@@ -416,15 +417,16 @@ public final class MatroskaExtractor implements Extractor {
throws ParserException {
switch (id) {
case ID_SEGMENT:
if (segmentContentPosition != UNKNOWN && segmentContentPosition != contentPosition) {
if (segmentContentPosition != C.POSITION_UNSET
&& segmentContentPosition != contentPosition) {
throw new ParserException("Multiple Segment elements not supported");
}
segmentContentPosition = contentPosition;
segmentContentSize = contentSize;
return;
case ID_SEEK:
seekEntryId = UNKNOWN;
seekEntryPosition = UNKNOWN;
seekEntryId = UNSET_ENTRY_ID;
seekEntryPosition = C.POSITION_UNSET;
return;
case ID_CUES:
cueTimesUs = new LongArray();
......@@ -436,7 +438,7 @@ public final class MatroskaExtractor implements Extractor {
case ID_CLUSTER:
if (!sentSeekMap) {
// We need to build cues before parsing the cluster.
if (cuesContentPosition != UNKNOWN) {
if (cuesContentPosition != C.POSITION_UNSET) {
// We know where the Cues element is located. Seek to request it.
seekForCues = true;
} else {
......@@ -467,16 +469,16 @@ public final class MatroskaExtractor implements Extractor {
/* package */ void endMasterElement(int id) throws ParserException {
switch (id) {
case ID_SEGMENT_INFO:
if (timecodeScale == C.UNSET_TIME_US) {
if (timecodeScale == C.TIME_UNSET) {
// timecodeScale was omitted. Use the default value.
timecodeScale = 1000000;
}
if (durationTimecode != C.UNSET_TIME_US) {
if (durationTimecode != C.TIME_UNSET) {
durationUs = scaleTimecodeToUs(durationTimecode);
}
return;
case ID_SEEK:
if (seekEntryId == UNKNOWN || seekEntryPosition == UNKNOWN) {
if (seekEntryId == UNSET_ENTRY_ID || seekEntryPosition == C.POSITION_UNSET) {
throw new ParserException("Mandatory element SeekID or SeekPosition not found");
}
if (seekEntryId == ID_CUES) {
......@@ -721,7 +723,7 @@ public final class MatroskaExtractor implements Extractor {
if (blockState == BLOCK_STATE_START) {
blockTrackNumber = (int) varintReader.readUnsignedVarint(input, false, true, 8);
blockTrackNumberLength = varintReader.getLastLength();
blockDurationUs = UNKNOWN;
blockDurationUs = C.TIME_UNSET;
blockState = BLOCK_STATE_HEADER;
scratch.reset();
}
......@@ -1059,7 +1061,7 @@ public final class MatroskaExtractor implements Extractor {
private static void setSubripSampleEndTimecode(byte[] subripSampleData, long timeUs) {
byte[] timeCodeData;
if (timeUs == UNKNOWN) {
if (timeUs == C.TIME_UNSET) {
timeCodeData = SUBRIP_TIMECODE_EMPTY;
} else {
int hours = (int) (timeUs / 3600000000L);
......@@ -1116,7 +1118,7 @@ public final class MatroskaExtractor implements Extractor {
* information was missing or incomplete.
*/
private SeekMap buildSeekMap() {
if (segmentContentPosition == UNKNOWN || durationUs == C.UNSET_TIME_US
if (segmentContentPosition == C.POSITION_UNSET || durationUs == C.TIME_UNSET
|| cueTimesUs == null || cueTimesUs.size() == 0
|| cueClusterPositions == null || cueClusterPositions.size() != cueTimesUs.size()) {
// Cues information is missing or incomplete.
......@@ -1163,16 +1165,16 @@ public final class MatroskaExtractor implements Extractor {
}
// After parsing Cues, seek back to original position if available. We will not do this unless
// we seeked to get to the Cues in the first place.
if (sentSeekMap && seekPositionAfterBuildingCues != UNKNOWN) {
if (sentSeekMap && seekPositionAfterBuildingCues != C.POSITION_UNSET) {
seekPosition.position = seekPositionAfterBuildingCues;
seekPositionAfterBuildingCues = UNKNOWN;
seekPositionAfterBuildingCues = C.POSITION_UNSET;
return true;
}
return false;
}
private long scaleTimecodeToUs(long unscaledTimecode) throws ParserException {
if (timecodeScale == C.UNSET_TIME_US) {
if (timecodeScale == C.TIME_UNSET) {
throw new ParserException("Can't scale timecode prior to timecodeScale being set.");
}
return Util.scaleLargeTimestamp(unscaledTimecode, timecodeScale, 1000);
......@@ -1294,7 +1296,7 @@ public final class MatroskaExtractor implements Extractor {
// Audio elements. Initially set to their default values.
public int channelCount = 1;
public int audioBitDepth = -1;
public int audioBitDepth = Format.NO_VALUE;
public int sampleRate = 8000;
public long codecDelayNs = 0;
public long seekPreRollNs = 0;
......
......@@ -44,7 +44,7 @@ import java.io.IOException;
*/
public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
long inputLength = input.getLength();
int bytesToSearch = (int) (inputLength == C.LENGTH_UNBOUNDED || inputLength > SEARCH_LENGTH
int bytesToSearch = (int) (inputLength == C.LENGTH_UNSET || inputLength > SEARCH_LENGTH
? SEARCH_LENGTH : inputLength);
// Find four bytes equal to ID_EBML near the start of the input.
input.peekFully(scratch.data, 0, 4);
......@@ -63,7 +63,7 @@ import java.io.IOException;
long headerSize = readUint(input);
long headerStart = peekLength;
if (headerSize == Long.MIN_VALUE
|| (inputLength != C.LENGTH_UNBOUNDED && headerStart + headerSize >= inputLength)) {
|| (inputLength != C.LENGTH_UNSET && headerStart + headerSize >= inputLength)) {
return false;
}
......
......@@ -87,7 +87,7 @@ import java.io.IOException;
}
int firstByte = scratch[0] & 0xFF;
length = parseUnsignedVarintLength(firstByte);
if (length == -1) {
if (length == C.LENGTH_UNSET) {
throw new IllegalStateException("No valid varint length mask found");
}
state = STATE_READ_CONTENTS;
......@@ -118,10 +118,11 @@ import java.io.IOException;
* Parses and the length of the varint given the first byte.
*
* @param firstByte First byte of the varint.
* @return Length of the varint beginning with the given byte if it was valid, -1 otherwise.
* @return Length of the varint beginning with the given byte if it was valid,
* {@link C#LENGTH_UNSET} otherwise.
*/
public static int parseUnsignedVarintLength(int firstByte) {
int varIntLength = -1;
int varIntLength = C.LENGTH_UNSET;
for (int i = 0; i < VARINT_LENGTH_MASKS.length; i++) {
if ((VARINT_LENGTH_MASKS[i] & firstByte) != 0) {
varIntLength = i + 1;
......
......@@ -31,17 +31,17 @@ import com.google.android.exoplayer2.C;
public ConstantBitrateSeeker(long firstFramePosition, int bitrate, long inputLength) {
this.firstFramePosition = firstFramePosition;
this.bitrate = bitrate;
durationUs = inputLength == C.LENGTH_UNBOUNDED ? C.UNSET_TIME_US : getTimeUs(inputLength);
durationUs = inputLength == C.LENGTH_UNSET ? C.TIME_UNSET : getTimeUs(inputLength);
}
@Override
public boolean isSeekable() {
return durationUs != C.UNSET_TIME_US;
return durationUs != C.TIME_UNSET;
}
@Override
public long getPosition(long timeUs) {
return durationUs == C.UNSET_TIME_US ? 0
return durationUs == C.TIME_UNSET ? 0
: firstFramePosition + (timeUs * bitrate) / (C.MICROS_PER_SECOND * BITS_PER_BYTE);
}
......
......@@ -86,21 +86,21 @@ public final class Mp3Extractor implements Extractor {
* Constructs a new {@link Mp3Extractor}.
*/
public Mp3Extractor() {
this(-1);
this(C.TIME_UNSET);
}
/**
* Constructs a new {@link Mp3Extractor}.
*
* @param forcedFirstSampleTimestampUs A timestamp to force for the first sample, or -1 if forcing
* is not required.
* @param forcedFirstSampleTimestampUs A timestamp to force for the first sample, or
* {@link C#TIME_UNSET} if forcing is not required.
*/
public Mp3Extractor(long forcedFirstSampleTimestampUs) {
this.forcedFirstSampleTimestampUs = forcedFirstSampleTimestampUs;
scratch = new ParsableByteArray(4);
synchronizedHeader = new MpegAudioHeader();
gaplessInfoHolder = new GaplessInfoHolder();
basisTimeUs = -1;
basisTimeUs = C.TIME_UNSET;
}
@Override
......@@ -118,7 +118,7 @@ public final class Mp3Extractor implements Extractor {
@Override
public void seek(long position) {
synchronizedHeaderData = 0;
basisTimeUs = -1;
basisTimeUs = C.TIME_UNSET;
samplesRead = 0;
sampleBytesRemaining = 0;
}
......@@ -150,9 +150,9 @@ public final class Mp3Extractor implements Extractor {
if (!maybeResynchronize(extractorInput)) {
return RESULT_END_OF_INPUT;
}
if (basisTimeUs == -1) {
if (basisTimeUs == C.TIME_UNSET) {
basisTimeUs = seeker.getTimeUs(extractorInput.getPosition());
if (forcedFirstSampleTimestampUs != -1) {
if (forcedFirstSampleTimestampUs != C.TIME_UNSET) {
long embeddedFirstSampleTimestampUs = seeker.getTimeUs(0);
basisTimeUs += forcedFirstSampleTimestampUs - embeddedFirstSampleTimestampUs;
}
......@@ -189,7 +189,7 @@ public final class Mp3Extractor implements Extractor {
int sampleHeaderData = scratch.readInt();
if ((sampleHeaderData & HEADER_MASK) == (synchronizedHeaderData & HEADER_MASK)) {
int frameSize = MpegAudioHeader.getFrameSize(sampleHeaderData);
if (frameSize != -1) {
if (frameSize != C.LENGTH_UNSET) {
MpegAudioHeader.populateHeader(sampleHeaderData, synchronizedHeader);
return true;
}
......@@ -241,7 +241,7 @@ public final class Mp3Extractor implements Extractor {
int frameSize;
if ((candidateSynchronizedHeaderData != 0
&& (headerData & HEADER_MASK) != (candidateSynchronizedHeaderData & HEADER_MASK))
|| (frameSize = MpegAudioHeader.getFrameSize(headerData)) == -1) {
|| (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
// The header is invalid or doesn't match the candidate header. Try the next byte offset.
validFrameCount = 0;
candidateSynchronizedHeaderData = 0;
......
......@@ -82,7 +82,7 @@ import com.google.android.exoplayer2.util.Util;
position += segmentSize * scale;
timesUs[index] = index * durationUs / entryCount;
positions[index] =
inputLength == C.LENGTH_UNBOUNDED ? position : Math.min(inputLength, position);
inputLength == C.LENGTH_UNSET ? position : Math.min(inputLength, position);
}
return new VbriSeeker(timesUs, positions, durationUs);
}
......
......@@ -128,7 +128,7 @@ import com.google.android.exoplayer2.util.Util;
}
long position = Math.round((1.0 / 256) * fx * sizeBytes) + firstFramePosition;
long maximumPosition = inputLength != C.LENGTH_UNBOUNDED ? inputLength - 1
long maximumPosition = inputLength != C.LENGTH_UNSET ? inputLength - 1
: firstFramePosition - headerSize + sizeBytes - 1;
return Math.min(position, maximumPosition);
}
......
......@@ -49,8 +49,8 @@ import java.util.List;
*
* @param trak Atom to decode.
* @param mvhd Movie header atom, used to get the timescale.
* @param duration The duration in units of the timescale declared in the mvhd atom, or -1 if the
* duration should be parsed from the tkhd atom.
* @param duration The duration in units of the timescale declared in the mvhd atom, or
* {@link C#TIME_UNSET} if the duration should be parsed from the tkhd atom.
* @param drmInitData {@link DrmInitData} to be included in the format.
* @param isQuickTime True for QuickTime media. False otherwise.
* @return A {@link Track} instance, or {@code null} if the track's type isn't supported.
......@@ -64,13 +64,13 @@ import java.util.List;
}
TkhdData tkhdData = parseTkhd(trak.getLeafAtomOfType(Atom.TYPE_tkhd).data);
if (duration == -1) {
if (duration == C.TIME_UNSET) {
duration = tkhdData.duration;
}
long movieTimescale = parseMvhd(mvhd.data);
long durationUs;
if (duration == -1) {
durationUs = C.UNSET_TIME_US;
if (duration == C.TIME_UNSET) {
durationUs = C.TIME_UNSET;
} else {
durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, movieTimescale);
}
......@@ -152,7 +152,7 @@ import java.util.List;
remainingTimestampOffsetChanges = ctts.readUnsignedIntToInt();
}
int nextSynchronizationSampleIndex = -1;
int nextSynchronizationSampleIndex = C.INDEX_UNSET;
int remainingSynchronizationSamples = 0;
if (stss != null) {
stss.setPosition(Atom.FULL_HEADER_SIZE);
......@@ -509,13 +509,13 @@ import java.util.List;
long duration;
if (durationUnknown) {
tkhd.skipBytes(durationByteCount);
duration = -1;
duration = C.TIME_UNSET;
} else {
duration = version == 0 ? tkhd.readUnsignedInt() : tkhd.readUnsignedLongToLong();
if (duration == 0) {
// 0 duration normally indicates that the file is fully fragmented (i.e. all of the media
// samples are in fragments). Treat as unknown.
duration = -1;
duration = C.TIME_UNSET;
}
}
......@@ -833,7 +833,7 @@ import java.util.List;
if (childAtomType == Atom.TYPE_esds || (isQuickTime && childAtomType == Atom.TYPE_wave)) {
int esdsAtomPosition = childAtomType == Atom.TYPE_esds ? childPosition
: findEsdsPosition(parent, childPosition, childAtomSize);
if (esdsAtomPosition != -1) {
if (esdsAtomPosition != C.POSITION_UNSET) {
Pair<String, byte[]> mimeTypeAndInitializationData =
parseEsdsFromParent(parent, esdsAtomPosition);
mimeType = mimeTypeAndInitializationData.first;
......@@ -875,7 +875,8 @@ import java.util.List;
}
/**
* Returns the position of the esds box within a parent, or -1 if no esds box is found
* Returns the position of the esds box within a parent, or {@link C#POSITION_UNSET} if no esds
* box is found
*/
private static int findEsdsPosition(ParsableByteArray parent, int position, int size) {
int childAtomPosition = parent.getPosition();
......@@ -889,7 +890,7 @@ import java.util.List;
}
childAtomPosition += childAtomSize;
}
return -1;
return C.POSITION_UNSET;
}
/**
......@@ -1081,7 +1082,7 @@ import java.util.List;
stsc.setPosition(Atom.FULL_HEADER_SIZE);
remainingSamplesPerChunkChanges = stsc.readUnsignedIntToInt();
Assertions.checkState(stsc.readInt() == 1, "first_chunk must be 1");
index = -1;
index = C.INDEX_UNSET;
}
public boolean moveNext() {
......@@ -1094,7 +1095,7 @@ import java.util.List;
numSamples = stsc.readUnsignedIntToInt();
stsc.skipBytes(4); // Skip sample_description_index
nextSamplesPerChunkChangeIndex = --remainingSamplesPerChunkChanges > 0
? (stsc.readUnsignedIntToInt() - 1) : -1;
? (stsc.readUnsignedIntToInt() - 1) : C.INDEX_UNSET;
}
return true;
}
......@@ -1131,11 +1132,9 @@ import java.util.List;
public StsdData(int numberOfEntries) {
trackEncryptionBoxes = new TrackEncryptionBox[numberOfEntries];
nalUnitLengthFieldLength = -1;
requiredSampleTransformation = Track.TRANSFORMATION_NONE;
}
}
/**
......
......@@ -156,7 +156,7 @@ public final class FragmentedMp4Extractor implements Extractor {
extendedTypeScratch = new byte[16];
containerAtoms = new Stack<>();
trackBundles = new SparseArray<>();
durationUs = C.UNSET_TIME_US;
durationUs = C.TIME_UNSET;
enterReadingAtomHeaderState();
}
......@@ -356,7 +356,7 @@ public final class FragmentedMp4Extractor implements Extractor {
// Read declaration of track fragments in the Moov box.
ContainerAtom mvex = moov.getContainerAtomOfType(Atom.TYPE_mvex);
SparseArray<DefaultSampleValues> defaultSampleValuesArray = new SparseArray<>();
long duration = -1;
long duration = C.TIME_UNSET;
int mvexChildrenSize = mvex.leafChildren.size();
for (int i = 0; i < mvexChildrenSize; i++) {
Atom.LeafAtom atom = mvex.leafChildren.get(i);
......@@ -958,7 +958,7 @@ public final class FragmentedMp4Extractor implements Extractor {
Track track = currentTrackBundle.track;
TrackOutput output = currentTrackBundle.output;
int sampleIndex = currentTrackBundle.currentSampleIndex;
if (track.nalUnitLengthFieldLength != -1) {
if (track.nalUnitLengthFieldLength != 0) {
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
// they're only 1 or 2 bytes long.
byte[] nalLengthData = nalLength.data;
......
......@@ -168,7 +168,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
for (Mp4Track track : tracks) {
TrackSampleTable sampleTable = track.sampleTable;
int sampleIndex = sampleTable.getIndexOfEarlierOrEqualSynchronizationSample(timeUs);
if (sampleIndex == TrackSampleTable.NO_SAMPLE) {
if (sampleIndex == C.INDEX_UNSET) {
// Handle the case where the requested time is before the first synchronization sample.
sampleIndex = sampleTable.getIndexOfLaterOrEqualSynchronizationSample(timeUs);
}
......@@ -306,7 +306,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
* Updates the stored track metadata to reflect the contents of the specified moov atom.
*/
private void processMoovAtom(ContainerAtom moov) throws ParserException {
long durationUs = C.UNSET_TIME_US;
long durationUs = C.TIME_UNSET;
List<Mp4Track> tracks = new ArrayList<>();
long earliestSampleOffset = Long.MAX_VALUE;
......@@ -322,8 +322,8 @@ public final class Mp4Extractor implements Extractor, SeekMap {
continue;
}
Track track = AtomParsers.parseTrak(atom, moov.getLeafAtomOfType(Atom.TYPE_mvhd), -1, null,
isQuickTime);
Track track = AtomParsers.parseTrak(atom, moov.getLeafAtomOfType(Atom.TYPE_mvhd),
C.TIME_UNSET, null, isQuickTime);
if (track == null) {
continue;
}
......@@ -379,7 +379,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
private int readSample(ExtractorInput input, PositionHolder positionHolder)
throws IOException, InterruptedException {
int trackIndex = getTrackIndexOfEarliestCurrentSample();
if (trackIndex == TrackSampleTable.NO_SAMPLE) {
if (trackIndex == C.INDEX_UNSET) {
return RESULT_END_OF_INPUT;
}
Mp4Track track = tracks[trackIndex];
......@@ -399,7 +399,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
return RESULT_SEEK;
}
input.skipFully((int) skipAmount);
if (track.track.nalUnitLengthFieldLength != -1) {
if (track.track.nalUnitLengthFieldLength != 0) {
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
// they're only 1 or 2 bytes long.
byte[] nalLengthData = nalLength.data;
......@@ -446,10 +446,10 @@ public final class Mp4Extractor implements Extractor, SeekMap {
/**
* Returns the index of the track that contains the earliest current sample, or
* {@link TrackSampleTable#NO_SAMPLE} if no samples remain.
* {@link C#INDEX_UNSET} if no samples remain.
*/
private int getTrackIndexOfEarliestCurrentSample() {
int earliestSampleTrackIndex = TrackSampleTable.NO_SAMPLE;
int earliestSampleTrackIndex = C.INDEX_UNSET;
long earliestSampleOffset = Long.MAX_VALUE;
for (int trackIndex = 0; trackIndex < tracks.length; trackIndex++) {
Mp4Track track = tracks[trackIndex];
......
......@@ -90,7 +90,7 @@ import java.io.IOException;
private static boolean sniffInternal(ExtractorInput input, boolean fragmented)
throws IOException, InterruptedException {
long inputLength = input.getLength();
int bytesToSearch = (int) (inputLength == C.LENGTH_UNBOUNDED || inputLength > SEARCH_LENGTH
int bytesToSearch = (int) (inputLength == C.LENGTH_UNSET || inputLength > SEARCH_LENGTH
? SEARCH_LENGTH : inputLength);
ParsableByteArray buffer = new ParsableByteArray(64);
......
......@@ -53,7 +53,7 @@ public final class Track {
public final long movieTimescale;
/**
* The duration of the track in microseconds, or {@link C#UNSET_TIME_US} if unknown.
* The duration of the track in microseconds, or {@link C#TIME_UNSET} if unknown.
*/
public final long durationUs;
......
......@@ -25,11 +25,6 @@ import com.google.android.exoplayer2.util.Util;
/* package */ final class TrackSampleTable {
/**
* Sample index when no sample is available.
*/
public static final int NO_SAMPLE = -1;
/**
* Number of samples.
*/
public final int sampleCount;
......@@ -72,7 +67,7 @@ import com.google.android.exoplayer2.util.Util;
* timestamp, if one is available.
*
* @param timeUs Timestamp adjacent to which to find a synchronization sample.
* @return Index of the synchronization sample, or {@link #NO_SAMPLE} if none.
* @return Index of the synchronization sample, or {@link C#INDEX_UNSET} if none.
*/
public int getIndexOfEarlierOrEqualSynchronizationSample(long timeUs) {
// Video frame timestamps may not be sorted, so the behavior of this call can be undefined.
......@@ -83,7 +78,7 @@ import com.google.android.exoplayer2.util.Util;
return i;
}
}
return NO_SAMPLE;
return C.INDEX_UNSET;
}
/**
......@@ -91,7 +86,7 @@ import com.google.android.exoplayer2.util.Util;
* if one is available.
*
* @param timeUs Timestamp adjacent to which to find a synchronization sample.
* @return index Index of the synchronization sample, or {@link #NO_SAMPLE} if none.
* @return index Index of the synchronization sample, or {@link C#INDEX_UNSET} if none.
*/
public int getIndexOfLaterOrEqualSynchronizationSample(long timeUs) {
int startIndex = Util.binarySearchCeil(timestampsUs, timeUs, true, false);
......@@ -100,7 +95,7 @@ import com.google.android.exoplayer2.util.Util;
return i;
}
}
return NO_SAMPLE;
return C.INDEX_UNSET;
}
}
......@@ -73,22 +73,19 @@ import java.io.IOException;
switch (state) {
case STATE_IDLE:
return -1;
case STATE_SEEK_TO_END:
positionBeforeSeekToEnd = input.getPosition();
state = STATE_READ_LAST_PAGE;
// seek to the end just before the last page of stream to get the duration
// Seek to the end just before the last page of stream to get the duration.
long lastPagePosition = endPosition - OggPageHeader.MAX_PAGE_SIZE;
if (lastPagePosition > positionBeforeSeekToEnd) {
return lastPagePosition;
}
// fall through
// Fall through.
case STATE_READ_LAST_PAGE:
totalGranules = readGranuleOfLastPage(input);
state = STATE_IDLE;
return positionBeforeSeekToEnd;
case STATE_SEEK:
long currentGranule;
if (targetGranule == 0) {
......@@ -102,7 +99,6 @@ import java.io.IOException;
}
state = STATE_IDLE;
return -(currentGranule + 2);
default:
// Never happens.
throw new IllegalStateException();
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.extractor.ogg;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.ParsableByteArray;
......@@ -29,7 +30,7 @@ import java.io.IOException;
private final ParsableByteArray packetArray =
new ParsableByteArray(new byte[OggPageHeader.MAX_PAGE_PAYLOAD], 0);
private int currentSegmentIndex = -1;
private int currentSegmentIndex = C.INDEX_UNSET;
private int segmentCount;
private boolean populated;
......@@ -39,7 +40,7 @@ import java.io.IOException;
public void reset() {
pageHeader.reset();
packetArray.reset();
currentSegmentIndex = -1;
currentSegmentIndex = C.INDEX_UNSET;
populated = false;
}
......@@ -88,8 +89,8 @@ import java.io.IOException;
packetArray.setLimit(packetArray.limit() + size);
populated = pageHeader.laces[segmentIndex - 1] != 255;
}
// advance now since we are sure reading didn't throw an exception
currentSegmentIndex = segmentIndex == pageHeader.pageSegmentCount ? -1
// Advance now since we are sure reading didn't throw an exception.
currentSegmentIndex = segmentIndex == pageHeader.pageSegmentCount ? C.INDEX_UNSET
: segmentIndex;
}
return true;
......
......@@ -83,7 +83,7 @@ import java.io.IOException;
throws IOException, InterruptedException {
scratch.reset();
reset();
boolean hasEnoughBytes = input.getLength() == C.LENGTH_UNBOUNDED
boolean hasEnoughBytes = input.getLength() == C.LENGTH_UNSET
|| input.getLength() - input.getPeekPosition() >= EMPTY_PAGE_HEADER_SIZE;
if (!hasEnoughBytes || !input.peekFully(scratch.data, 0, EMPTY_PAGE_HEADER_SIZE, true)) {
if (quiet) {
......
......@@ -45,13 +45,14 @@ import java.io.IOException;
* <p/>
* If more data is required or if the position of the input needs to be modified then a position
* from which data should be provided is returned. Else a negative value is returned. If a seek
* has been completed then the value returned is -(currentGranule + 2). Else -1 is returned.
* has been completed then the value returned is -(currentGranule + 2). Else it is -1.
*
* @param input the {@link ExtractorInput} to read from.
* @return the non-negative position to seek the {@link ExtractorInput} to or -1 seeking not
* necessary or at the end of seeking a negative number < -1 which is -(currentGranule + 2).
* @throws IOException thrown if reading from the input fails.
* @throws InterruptedException thrown if interrupted while reading from the input.
* @param input The {@link ExtractorInput} to read from.
* @return A non-negative position to seek the {@link ExtractorInput} to, or -(currentGranule + 2)
* if the progressive seek has completed, or -1 otherwise.
* @throws IOException If reading from the {@link ExtractorInput} fails.
* @throws InterruptedException If the thread is interrupted.
*/
long read(ExtractorInput input) throws IOException, InterruptedException;
}
......@@ -141,7 +141,7 @@ import java.io.IOException;
if (setupData.oggSeeker != null) {
oggSeeker = setupData.oggSeeker;
} else if (input.getLength() == C.LENGTH_UNBOUNDED) {
} else if (input.getLength() == C.LENGTH_UNSET) {
oggSeeker = new UnseekableOggSeeker();
} else {
oggSeeker = new DefaultOggSeeker(payloadStartPosition, input.getLength(), this);
......@@ -236,6 +236,7 @@ import java.io.IOException;
}
private static final class UnseekableOggSeeker implements OggSeeker {
@Override
public long read(ExtractorInput input) throws IOException, InterruptedException {
return -1;
......@@ -248,8 +249,9 @@ import java.io.IOException;
@Override
public SeekMap createSeekMap() {
return new SeekMap.Unseekable(C.UNSET_TIME_US);
return new SeekMap.Unseekable(C.TIME_UNSET);
}
}
}
......@@ -64,7 +64,7 @@ public final class RawCcExtractor implements Extractor {
@Override
public void init(ExtractorOutput output) {
this.extractorOutput = output;
extractorOutput.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
extractorOutput.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
trackOutput = extractorOutput.track(0);
extractorOutput.endTracks();
......
......@@ -128,7 +128,7 @@ public final class AdtsExtractor implements Extractor {
public void init(ExtractorOutput output) {
adtsReader = new AdtsReader(output.track(0), output.track(1));
output.endTracks();
output.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
}
@Override
......@@ -146,7 +146,7 @@ public final class AdtsExtractor implements Extractor {
public int read(ExtractorInput input, PositionHolder seekPosition)
throws IOException, InterruptedException {
int bytesRead = input.read(packetBuffer.data, 0, MAX_PACKET_SIZE);
if (bytesRead == -1) {
if (bytesRead == C.RESULT_END_OF_INPUT) {
return RESULT_END_OF_INPUT;
}
......
......@@ -75,7 +75,7 @@ import java.util.Collections;
@Override
public void packetStarted(long pesTimeUs, boolean dataAlignmentIndicator) {
pesPtsUsAvailable = pesTimeUs != C.UNSET_TIME_US;
pesPtsUsAvailable = pesTimeUs != C.TIME_UNSET;
if (pesPtsUsAvailable) {
this.pesTimeUs = pesTimeUs;
}
......
......@@ -120,7 +120,7 @@ public final class PsExtractor implements Extractor {
@Override
public void init(ExtractorOutput output) {
this.output = output;
output.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
}
@Override
......
......@@ -132,7 +132,7 @@ public final class TsExtractor implements Extractor {
@Override
public void init(ExtractorOutput output) {
this.output = output;
output.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
}
@Override
......@@ -653,7 +653,7 @@ public final class TsExtractor implements Extractor {
private void parseHeaderExtension() {
pesScratch.setPosition(0);
timeUs = C.UNSET_TIME_US;
timeUs = C.TIME_UNSET;
if (ptsFlag) {
pesScratch.skipBits(4); // '0010' or '0011'
long pts = (long) pesScratch.readBits(3) << 30;
......
......@@ -358,9 +358,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
drmSessionRequiresSecureDecoder, codecName));
}
codecHotswapDeadlineMs = getState() == STATE_STARTED
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS) : -1;
inputIndex = -1;
outputIndex = -1;
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS) : C.TIME_UNSET;
inputIndex = C.INDEX_UNSET;
outputIndex = C.INDEX_UNSET;
decoderCounters.decoderInitCount++;
}
......@@ -412,9 +412,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
protected void releaseCodec() {
if (codec != null) {
codecHotswapDeadlineMs = -1;
inputIndex = -1;
outputIndex = -1;
codecHotswapDeadlineMs = C.TIME_UNSET;
inputIndex = C.INDEX_UNSET;
outputIndex = C.INDEX_UNSET;
waitingForKeys = false;
shouldSkipOutputBuffer = false;
decodeOnlyPresentationTimestamps.clear();
......@@ -489,9 +489,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
protected void flushCodec() throws ExoPlaybackException {
codecHotswapDeadlineMs = -1;
inputIndex = -1;
outputIndex = -1;
codecHotswapDeadlineMs = C.TIME_UNSET;
inputIndex = C.INDEX_UNSET;
outputIndex = C.INDEX_UNSET;
waitingForKeys = false;
shouldSkipOutputBuffer = false;
decodeOnlyPresentationTimestamps.clear();
......@@ -547,7 +547,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} else {
codecReceivedEos = true;
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
inputIndex = -1;
inputIndex = C.INDEX_UNSET;
}
codecReinitializationState = REINITIALIZATION_STATE_WAIT_END_OF_STREAM;
return false;
......@@ -557,7 +557,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecNeedsAdaptationWorkaroundBuffer = false;
buffer.data.put(ADAPTATION_WORKAROUND_BUFFER);
codec.queueInputBuffer(inputIndex, 0, ADAPTATION_WORKAROUND_BUFFER.length, 0, 0);
inputIndex = -1;
inputIndex = C.INDEX_UNSET;
codecReceivedBuffers = true;
return true;
}
......@@ -615,7 +615,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} else {
codecReceivedEos = true;
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
inputIndex = -1;
inputIndex = C.INDEX_UNSET;
}
} catch (CryptoException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
......@@ -650,7 +650,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} else {
codec.queueInputBuffer(inputIndex, 0, buffer.data.limit(), presentationTimeUs, 0);
}
inputIndex = -1;
inputIndex = C.INDEX_UNSET;
codecReceivedBuffers = true;
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
decoderCounters.inputBufferCount++;
......@@ -820,7 +820,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
@Override
public boolean isReady() {
return format != null && !waitingForKeys && (isSourceReady() || outputIndex >= 0
|| (SystemClock.elapsedRealtime() < codecHotswapDeadlineMs));
|| (codecHotswapDeadlineMs != C.TIME_UNSET
&& SystemClock.elapsedRealtime() < codecHotswapDeadlineMs));
}
/**
......@@ -850,13 +851,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
if (shouldSkipAdaptationWorkaroundOutputBuffer) {
shouldSkipAdaptationWorkaroundOutputBuffer = false;
codec.releaseOutputBuffer(outputIndex, false);
outputIndex = -1;
outputIndex = C.INDEX_UNSET;
return true;
}
if ((outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
// The dequeued buffer indicates the end of the stream. Process it immediately.
processEndOfStream();
outputIndex = -1;
outputIndex = C.INDEX_UNSET;
return true;
} else {
// The dequeued buffer is a media buffer. Do some initial setup. The buffer will be
......@@ -888,7 +889,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
outputIndex, outputBufferInfo.flags, outputBufferInfo.presentationTimeUs,
shouldSkipOutputBuffer)) {
onProcessedOutputBuffer(outputBufferInfo.presentationTimeUs);
outputIndex = -1;
outputIndex = C.INDEX_UNSET;
return true;
}
......
......@@ -15,6 +15,8 @@
*/
package com.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.C.usToMs;
import android.os.Handler;
import android.os.SystemClock;
import com.google.android.exoplayer2.C;
......@@ -42,10 +44,10 @@ public interface AdaptiveMediaSourceEventListener {
* data belongs to a track. {@link C#SELECTION_REASON_UNKNOWN} otherwise.
* @param trackSelectionData Optional data associated with the selection of the track to which the
* data belongs. Null if the data does not belong to a track.
* @param mediaStartTimeMs The start time of the media being loaded, or -1 if the load is not for
* media data.
* @param mediaEndTimeMs The end time of the media being loaded, or -1 if the load is not for
* media data.
* @param mediaStartTimeMs The start time of the media being loaded, or {@link C#TIME_UNSET} if
* the load is not for media data.
* @param mediaEndTimeMs The end time of the media being loaded, or {@link C#TIME_UNSET} if the
* load is not for media data.
* @param elapsedRealtimeMs The value of {@link SystemClock#elapsedRealtime} when the load began.
*/
void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat,
......@@ -66,10 +68,10 @@ public interface AdaptiveMediaSourceEventListener {
* data belongs to a track. {@link C#SELECTION_REASON_UNKNOWN} otherwise.
* @param trackSelectionData Optional data associated with the selection of the track to which the
* data belongs. Null if the data does not belong to a track.
* @param mediaStartTimeMs The start time of the media being loaded, or -1 if the load is not for
* media data.
* @param mediaEndTimeMs The end time of the media being loaded, or -1 if the load is not for
* media data.
* @param mediaStartTimeMs The start time of the media being loaded, or {@link C#TIME_UNSET} if
* the load is not for media data.
* @param mediaEndTimeMs The end time of the media being loaded, or {@link C#TIME_UNSET} if the
* load is not for media data.
* @param elapsedRealtimeMs The value of {@link SystemClock#elapsedRealtime} when the load ended.
* @param loadDurationMs The duration of the load.
* @param bytesLoaded The number of bytes that were loaded.
......@@ -92,10 +94,10 @@ public interface AdaptiveMediaSourceEventListener {
* data belongs to a track. {@link C#SELECTION_REASON_UNKNOWN} otherwise.
* @param trackSelectionData Optional data associated with the selection of the track to which the
* data belongs. Null if the data does not belong to a track.
* @param mediaStartTimeMs The start time of the media being loaded, or -1 if the load is not for
* media data.
* @param mediaEndTimeMs The end time of the media being loaded, or -1 if the load is not for
* media data.
* @param mediaStartTimeMs The start time of the media being loaded, or {@link C#TIME_UNSET} if
* the load is not for media data.
* @param mediaEndTimeMs The end time of the media being loaded, or {@link C#TIME_UNSET} if the
* load is not for media data.
* @param elapsedRealtimeMs The value of {@link SystemClock#elapsedRealtime} when the load was
* canceled.
* @param loadDurationMs The duration of the load up to the point at which it was canceled.
......@@ -123,10 +125,10 @@ public interface AdaptiveMediaSourceEventListener {
* data belongs to a track. {@link C#SELECTION_REASON_UNKNOWN} otherwise.
* @param trackSelectionData Optional data associated with the selection of the track to which the
* data belongs. Null if the data does not belong to a track.
* @param mediaStartTimeMs The start time of the media being loaded, or -1 if the load is not for
* media data.
* @param mediaEndTimeMs The end time of the media being loaded, or -1 if the load is not for
* media data.
* @param mediaStartTimeMs The start time of the media being loaded, or {@link C#TIME_UNSET} if
* the load is not for media data.
* @param mediaEndTimeMs The end time of the media being loaded, or {@link C#TIME_UNSET} if the
* load is not for media data.
* @param elapsedRealtimeMs The value of {@link SystemClock#elapsedRealtime} when the error
* occurred.
* @param loadDurationMs The duration of the load up to the point at which the error occurred.
......@@ -180,7 +182,7 @@ public interface AdaptiveMediaSourceEventListener {
public void loadStarted(DataSpec dataSpec, int dataType, long elapsedRealtimeMs) {
loadStarted(dataSpec, dataType, C.TRACK_TYPE_UNKNOWN, null, C.SELECTION_REASON_UNKNOWN,
null, C.UNSET_TIME_US, C.UNSET_TIME_US, elapsedRealtimeMs);
null, C.TIME_UNSET, C.TIME_UNSET, elapsedRealtimeMs);
}
public void loadStarted(final DataSpec dataSpec, final int dataType, final int trackType,
......@@ -201,7 +203,7 @@ public interface AdaptiveMediaSourceEventListener {
public void loadCompleted(DataSpec dataSpec, int dataType, long elapsedRealtimeMs,
long loadDurationMs, long bytesLoaded) {
loadCompleted(dataSpec, dataType, C.TRACK_TYPE_UNKNOWN, null, C.SELECTION_REASON_UNKNOWN,
null, C.UNSET_TIME_US, C.UNSET_TIME_US, elapsedRealtimeMs, loadDurationMs, bytesLoaded);
null, C.TIME_UNSET, C.TIME_UNSET, elapsedRealtimeMs, loadDurationMs, bytesLoaded);
}
public void loadCompleted(final DataSpec dataSpec, final int dataType, final int trackType,
......@@ -223,7 +225,7 @@ public interface AdaptiveMediaSourceEventListener {
public void loadCanceled(DataSpec dataSpec, int dataType, long elapsedRealtimeMs,
long loadDurationMs, long bytesLoaded) {
loadCanceled(dataSpec, dataType, C.TRACK_TYPE_UNKNOWN, null, C.SELECTION_REASON_UNKNOWN,
null, C.UNSET_TIME_US, C.UNSET_TIME_US, elapsedRealtimeMs, loadDurationMs, bytesLoaded);
null, C.TIME_UNSET, C.TIME_UNSET, elapsedRealtimeMs, loadDurationMs, bytesLoaded);
}
public void loadCanceled(final DataSpec dataSpec, final int dataType, final int trackType,
......@@ -245,7 +247,7 @@ public interface AdaptiveMediaSourceEventListener {
public void loadError(DataSpec dataSpec, int dataType, long elapsedRealtimeMs,
long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {
loadError(dataSpec, dataType, C.TRACK_TYPE_UNKNOWN, null, C.SELECTION_REASON_UNKNOWN,
null, C.UNSET_TIME_US, C.UNSET_TIME_US, elapsedRealtimeMs, loadDurationMs, bytesLoaded,
null, C.TIME_UNSET, C.TIME_UNSET, elapsedRealtimeMs, loadDurationMs, bytesLoaded,
error, wasCanceled);
}
......@@ -293,16 +295,6 @@ public interface AdaptiveMediaSourceEventListener {
}
}
/**
* Converts microseconds to milliseconds (rounding down), mapping {@link C#UNSET_TIME_US} to -1
*
* @param timeUs A microsecond value.
* @return The value in milliseconds.
*/
private static long usToMs(long timeUs) {
return timeUs == C.UNSET_TIME_US ? -1 : (timeUs / 1000);
}
}
}
......@@ -33,11 +33,11 @@ public final class CompositeSequenceableLoader implements SequenceableLoader {
long nextLoadPositionUs = Long.MAX_VALUE;
for (SequenceableLoader loader : loaders) {
long loaderNextLoadPositionUs = loader.getNextLoadPositionUs();
if (loaderNextLoadPositionUs != C.END_OF_SOURCE_US) {
if (loaderNextLoadPositionUs != C.TIME_END_OF_SOURCE) {
nextLoadPositionUs = Math.min(nextLoadPositionUs, loaderNextLoadPositionUs);
}
}
return nextLoadPositionUs == Long.MAX_VALUE ? C.END_OF_SOURCE_US : nextLoadPositionUs;
return nextLoadPositionUs == Long.MAX_VALUE ? C.TIME_END_OF_SOURCE : nextLoadPositionUs;
}
@Override
......@@ -47,7 +47,7 @@ public final class CompositeSequenceableLoader implements SequenceableLoader {
do {
madeProgressThisIteration = false;
long nextLoadPositionUs = getNextLoadPositionUs();
if (nextLoadPositionUs == C.END_OF_SOURCE_US) {
if (nextLoadPositionUs == C.TIME_END_OF_SOURCE) {
break;
}
for (SequenceableLoader loader : loaders) {
......
......@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Window;
import com.google.android.exoplayer2.source.MediaPeriod.Callback;
......@@ -177,19 +178,19 @@ public final class ConcatenatingMediaSource implements MediaSource {
@Override
public int getIndexOfPeriod(Object id) {
if (!(id instanceof Pair)) {
return NO_PERIOD_INDEX;
return C.INDEX_UNSET;
}
Pair sourceIndexAndPeriodId = (Pair) id;
if (!(sourceIndexAndPeriodId.first instanceof Integer)) {
return NO_PERIOD_INDEX;
return C.INDEX_UNSET;
}
int sourceIndex = (int) sourceIndexAndPeriodId.first;
Object periodId = sourceIndexAndPeriodId.second;
if (sourceIndex < 0 || sourceIndex >= timelines.length) {
return NO_PERIOD_INDEX;
return C.INDEX_UNSET;
}
int periodIndexInSource = timelines[sourceIndex].getIndexOfPeriod(periodId);
return periodIndexInSource == NO_PERIOD_INDEX ? NO_PERIOD_INDEX
return periodIndexInSource == C.INDEX_UNSET ? C.INDEX_UNSET
: getFirstPeriodIndexInSource(sourceIndex) + periodIndexInSource;
}
......
......@@ -113,9 +113,9 @@ import java.util.Arrays;
extractorHolder = new ExtractorHolder(extractors, this);
loadCondition = new ConditionVariable();
pendingResetPositionUs = C.UNSET_TIME_US;
pendingResetPositionUs = C.TIME_UNSET;
sampleQueues = new DefaultTrackOutput[0];
length = C.LENGTH_UNBOUNDED;
length = C.LENGTH_UNSET;
loadCondition.open();
startLoading();
}
......@@ -225,13 +225,13 @@ import java.util.Arrays;
notifyReset = false;
return lastSeekPositionUs;
}
return C.UNSET_TIME_US;
return C.TIME_UNSET;
}
@Override
public long getBufferedPositionUs() {
if (loadingFinished) {
return C.END_OF_SOURCE_US;
return C.TIME_END_OF_SOURCE;
} else if (isPendingReset()) {
return pendingResetPositionUs;
} else {
......@@ -294,7 +294,7 @@ import java.util.Arrays;
long loadDurationMs) {
copyLengthFromLoader(loadable);
loadingFinished = true;
if (durationUs == C.UNSET_TIME_US) {
if (durationUs == C.TIME_UNSET) {
long largestQueuedTimestampUs = getLargestQueuedTimestampUs();
durationUs = largestQueuedTimestampUs == Long.MIN_VALUE ? 0
: largestQueuedTimestampUs + DEFAULT_LAST_SAMPLE_DURATION_US;
......@@ -387,7 +387,7 @@ import java.util.Arrays;
}
private void copyLengthFromLoader(ExtractingLoadable loadable) {
if (length == C.LENGTH_UNBOUNDED) {
if (length == C.LENGTH_UNSET) {
length = loadable.length;
}
}
......@@ -397,21 +397,21 @@ import java.util.Arrays;
loadCondition);
if (prepared) {
Assertions.checkState(isPendingReset());
if (durationUs != C.UNSET_TIME_US && pendingResetPositionUs >= durationUs) {
if (durationUs != C.TIME_UNSET && pendingResetPositionUs >= durationUs) {
loadingFinished = true;
pendingResetPositionUs = C.UNSET_TIME_US;
pendingResetPositionUs = C.TIME_UNSET;
return;
}
loadable.setLoadPosition(seekMap.getPosition(pendingResetPositionUs));
pendingResetPositionUs = C.UNSET_TIME_US;
pendingResetPositionUs = C.TIME_UNSET;
}
extractedSamplesCountAtStartOfLoad = getExtractedSamplesCount();
int minRetryCount = minLoadableRetryCount;
if (minRetryCount == ExtractorMediaSource.MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA) {
// We assume on-demand before we're prepared.
minRetryCount = !prepared || length != C.LENGTH_UNBOUNDED
|| (seekMap != null && seekMap.getDurationUs() != C.UNSET_TIME_US)
minRetryCount = !prepared || length != C.LENGTH_UNSET
|| (seekMap != null && seekMap.getDurationUs() != C.TIME_UNSET)
? ExtractorMediaSource.DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND
: ExtractorMediaSource.DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE;
}
......@@ -419,8 +419,8 @@ import java.util.Arrays;
}
private void configureRetry(ExtractingLoadable loadable) {
if (length != C.LENGTH_UNBOUNDED
|| (seekMap != null && seekMap.getDurationUs() != C.UNSET_TIME_US)) {
if (length != C.LENGTH_UNSET
|| (seekMap != null && seekMap.getDurationUs() != C.TIME_UNSET)) {
// We're playing an on-demand stream. Resume the current loadable, which will
// request data starting from the point it left off.
} else {
......@@ -456,7 +456,7 @@ import java.util.Arrays;
}
private boolean isPendingReset() {
return pendingResetPositionUs != C.UNSET_TIME_US;
return pendingResetPositionUs != C.TIME_UNSET;
}
private boolean isLoadableExceptionFatal(IOException e) {
......@@ -534,7 +534,7 @@ import java.util.Arrays;
this.loadCondition = loadCondition;
this.positionHolder = new PositionHolder();
this.pendingExtractorSeek = true;
this.length = C.LENGTH_UNBOUNDED;
this.length = C.LENGTH_UNSET;
}
public void setLoadPosition(long position) {
......@@ -560,8 +560,8 @@ import java.util.Arrays;
try {
long position = positionHolder.position;
length = dataSource.open(
new DataSpec(uri, position, C.LENGTH_UNBOUNDED, Util.sha1(uri.toString())));
if (length != C.LENGTH_UNBOUNDED) {
new DataSpec(uri, position, C.LENGTH_UNSET, Util.sha1(uri.toString())));
if (length != C.LENGTH_UNSET) {
length += position;
}
input = new DefaultExtractorInput(dataSource, position, length);
......
......@@ -135,7 +135,7 @@ public final class ExtractorMediaSource implements MediaSource, MediaSource.List
@Override
public void prepareSource(MediaSource.Listener listener) {
sourceListener = listener;
timeline = new SinglePeriodTimeline(C.UNSET_TIME_US, false);
timeline = new SinglePeriodTimeline(C.TIME_UNSET, false);
listener.onSourceInfoRefreshed(timeline, null);
}
......@@ -167,8 +167,8 @@ public final class ExtractorMediaSource implements MediaSource, MediaSource.List
@Override
public void onSourceInfoRefreshed(Timeline timeline, Object manifest) {
if (this.timeline.getPeriodDurationUs(0) != C.UNSET_TIME_US
&& timeline.getPeriodDurationUs(0) == C.UNSET_TIME_US) {
if (this.timeline.getPeriodDurationUs(0) != C.TIME_UNSET
&& timeline.getPeriodDurationUs(0) == C.TIME_UNSET) {
// Suppress source info changes that would make the duration unknown when it is already known.
return;
}
......
......@@ -91,11 +91,11 @@ public interface MediaPeriod extends SequenceableLoader {
/**
* Attempts to read a discontinuity.
* <p>
* After this method has returned a value other than {@link C#UNSET_TIME_US}, all
* After this method has returned a value other than {@link C#TIME_UNSET}, all
* {@link SampleStream}s provided by the period are guaranteed to start from a key frame.
*
* @return If a discontinuity was read then the playback position in microseconds after the
* discontinuity. Else {@link C#UNSET_TIME_US}.
* discontinuity. Else {@link C#TIME_UNSET}.
*/
long readDiscontinuity();
......@@ -105,7 +105,7 @@ public interface MediaPeriod extends SequenceableLoader {
* 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, or
* {@link C#END_OF_SOURCE_US} if the track is fully buffered.
* {@link C#TIME_END_OF_SOURCE} if the track is fully buffered.
*/
long getBufferedPositionUs();
......
......@@ -62,12 +62,13 @@ import java.util.IdentityHashMap;
int[] streamChildIndices = new int[selections.length];
int[] selectionChildIndices = new int[selections.length];
for (int i = 0; i < selections.length; i++) {
streamChildIndices[i] = streams[i] == null ? -1 : streamPeriodIndices.get(streams[i]);
selectionChildIndices[i] = -1;
streamChildIndices[i] = streams[i] == null ? C.INDEX_UNSET
: streamPeriodIndices.get(streams[i]);
selectionChildIndices[i] = C.INDEX_UNSET;
if (selections[i] != null) {
TrackGroup trackGroup = selections[i].getTrackGroup();
for (int j = 0; j < periods.length; j++) {
if (periods[j].getTrackGroups().indexOf(trackGroup) != -1) {
if (periods[j].getTrackGroups().indexOf(trackGroup) != C.INDEX_UNSET) {
selectionChildIndices[i] = j;
break;
}
......@@ -125,7 +126,7 @@ import java.util.IdentityHashMap;
@Override
public long readDiscontinuity() {
long positionUs = enabledPeriods[0].readDiscontinuity();
if (positionUs != C.UNSET_TIME_US) {
if (positionUs != C.TIME_UNSET) {
// It must be possible to seek additional periods to the new position.
for (int i = 1; i < enabledPeriods.length; i++) {
if (enabledPeriods[i].seekToUs(positionUs) != positionUs) {
......@@ -135,7 +136,7 @@ import java.util.IdentityHashMap;
}
// Additional periods are not allowed to report discontinuities.
for (int i = 1; i < enabledPeriods.length; i++) {
if (enabledPeriods[i].readDiscontinuity() != C.UNSET_TIME_US) {
if (enabledPeriods[i].readDiscontinuity() != C.TIME_UNSET) {
throw new IllegalStateException("Child reported discontinuity");
}
}
......@@ -147,11 +148,11 @@ import java.util.IdentityHashMap;
long bufferedPositionUs = Long.MAX_VALUE;
for (MediaPeriod period : enabledPeriods) {
long rendererBufferedPositionUs = period.getBufferedPositionUs();
if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) {
if (rendererBufferedPositionUs != C.TIME_END_OF_SOURCE) {
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
}
}
return bufferedPositionUs == Long.MAX_VALUE ? C.END_OF_SOURCE_US : bufferedPositionUs;
return bufferedPositionUs == Long.MAX_VALUE ? C.TIME_END_OF_SOURCE : bufferedPositionUs;
}
@Override
......
......@@ -28,6 +28,8 @@ import java.io.IOException;
*/
public final class MergingMediaSource implements MediaSource {
private static final int PERIOD_COUNT_UNSET = -1;
private final MediaSource[] mediaSources;
private int periodCount;
......@@ -37,7 +39,7 @@ public final class MergingMediaSource implements MediaSource {
*/
public MergingMediaSource(MediaSource... mediaSources) {
this.mediaSources = mediaSources;
periodCount = -1;
periodCount = PERIOD_COUNT_UNSET;
}
@Override
......@@ -106,7 +108,7 @@ public final class MergingMediaSource implements MediaSource {
Assertions.checkArgument(!timeline.getWindow(i).isDynamic);
}
int periodCount = timeline.getPeriodCount();
if (this.periodCount == -1) {
if (this.periodCount == PERIOD_COUNT_UNSET) {
this.periodCount = periodCount;
} else {
Assertions.checkState(this.periodCount == periodCount);
......
......@@ -36,7 +36,7 @@ public interface SequenceableLoader {
}
/**
* Returns the next load time, or {@link C#END_OF_SOURCE_US} if loading has finished.
* Returns the next load time, or {@link C#TIME_END_OF_SOURCE} if loading has finished.
*/
long getNextLoadPositionUs();
......
......@@ -16,7 +16,6 @@
package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Window;
import com.google.android.exoplayer2.util.Assertions;
......@@ -66,15 +65,13 @@ public final class SinglePeriodTimeline implements Timeline {
@Override
public long getPeriodDurationMs(int periodIndex) {
Assertions.checkIndex(periodIndex, 0, 1);
return window.durationUs == C.UNSET_TIME_US ? ExoPlayer.UNKNOWN_TIME
: ((offsetInFirstPeriodUs + window.durationUs) / 1000);
return C.usToMs(getPeriodDurationUs(periodIndex));
}
@Override
public long getPeriodDurationUs(int periodIndex) {
Assertions.checkIndex(periodIndex, 0, 1);
return window.durationUs == C.UNSET_TIME_US ? C.UNSET_TIME_US
return window.durationUs == C.TIME_UNSET ? C.TIME_UNSET
: (offsetInFirstPeriodUs + window.durationUs);
}
......@@ -98,7 +95,7 @@ public final class SinglePeriodTimeline implements Timeline {
@Override
public int getIndexOfPeriod(Object id) {
return ID.equals(id) ? 0 : Timeline.NO_PERIOD_INDEX;
return ID.equals(id) ? 0 : C.INDEX_UNSET;
}
@Override
......
......@@ -118,17 +118,17 @@ import java.util.Arrays;
@Override
public long readDiscontinuity() {
return C.UNSET_TIME_US;
return C.TIME_UNSET;
}
@Override
public long getNextLoadPositionUs() {
return loadingFinished || loader.isLoading() ? C.END_OF_SOURCE_US : 0;
return loadingFinished || loader.isLoading() ? C.TIME_END_OF_SOURCE : 0;
}
@Override
public long getBufferedPositionUs() {
return loadingFinished ? C.END_OF_SOURCE_US : 0;
return loadingFinished ? C.TIME_END_OF_SOURCE : 0;
}
@Override
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.util.Assertions;
import java.util.Arrays;
......@@ -63,7 +64,7 @@ public final class TrackGroup {
* Returns the index of the track with the given format in the group.
*
* @param format The format.
* @return The index of the track, or -1 if no such track exists.
* @return The index of the track, or {@link C#INDEX_UNSET} if no such track exists.
*/
public int indexOf(Format format) {
for (int i = 0; i < formats.length; i++) {
......@@ -71,7 +72,7 @@ public final class TrackGroup {
return i;
}
}
return -1;
return C.INDEX_UNSET;
}
@Override
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.C;
import java.util.Arrays;
/**
......@@ -54,7 +55,7 @@ public final class TrackGroupArray {
* Returns the index of a group within the array.
*
* @param group The group.
* @return The index of the group, or -1 if no such group exists.
* @return The index of the group, or {@link C#INDEX_UNSET} if no such group exists.
*/
public int indexOf(TrackGroup group) {
for (int i = 0; i < length; i++) {
......@@ -62,7 +63,7 @@ public final class TrackGroupArray {
return i;
}
}
return -1;
return C.INDEX_UNSET;
}
@Override
......
......@@ -53,12 +53,12 @@ public abstract class Chunk implements Loadable {
*/
public final Object trackSelectionData;
/**
* The start time of the media contained by the chunk, or {@link C#UNSET_TIME_US} if the data
* The start time of the media contained by the chunk, or {@link C#TIME_UNSET} if the data
* being loaded does not contain media samples.
*/
public final long startTimeUs;
/**
* The end time of the media contained by the chunk, or {@link C#UNSET_TIME_US} if the data being
* The end time of the media contained by the chunk, or {@link C#TIME_UNSET} if the data being
* loaded does not contain media samples.
*/
public final long endTimeUs;
......
......@@ -95,11 +95,11 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
* Returns an estimate of the position up to which data is buffered.
*
* @return An estimate of the absolute position in microseconds up to which data is buffered, or
* {@link C#END_OF_SOURCE_US} if the track is fully buffered.
* {@link C#TIME_END_OF_SOURCE} if the track is fully buffered.
*/
public long getBufferedPositionUs() {
if (loadingFinished) {
return C.END_OF_SOURCE_US;
return C.TIME_END_OF_SOURCE;
} else if (isPendingReset()) {
return pendingResetPositionUs;
} else {
......@@ -256,7 +256,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
}
chunkSource.getNextChunk(mediaChunks.isEmpty() ? null : mediaChunks.getLast(),
pendingResetPositionUs != C.UNSET_TIME_US ? pendingResetPositionUs : positionUs,
pendingResetPositionUs != C.TIME_UNSET ? pendingResetPositionUs : positionUs,
nextChunkHolder);
boolean endOfStream = nextChunkHolder.endOfStream;
Chunk loadable = nextChunkHolder.chunk;
......@@ -272,7 +272,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
}
if (isMediaChunk(loadable)) {
pendingResetPositionUs = C.UNSET_TIME_US;
pendingResetPositionUs = C.TIME_UNSET;
BaseMediaChunk mediaChunk = (BaseMediaChunk) loadable;
mediaChunk.init(sampleQueue);
mediaChunks.add(mediaChunk);
......@@ -289,7 +289,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
if (isPendingReset()) {
return pendingResetPositionUs;
} else {
return loadingFinished ? C.END_OF_SOURCE_US : mediaChunks.getLast().endTimeUs;
return loadingFinished ? C.TIME_END_OF_SOURCE : mediaChunks.getLast().endTimeUs;
}
}
......@@ -312,7 +312,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
}
private boolean isPendingReset() {
return pendingResetPositionUs != C.UNSET_TIME_US;
return pendingResetPositionUs != C.TIME_UNSET;
}
/**
......
......@@ -47,7 +47,7 @@ public abstract class DataChunk extends Chunk {
public DataChunk(DataSource dataSource, DataSpec dataSpec, int type, Format trackFormat,
int trackSelectionReason, Object trackSelectionData, byte[] data) {
super(dataSource, dataSpec, type, trackFormat, trackSelectionReason, trackSelectionData,
C.UNSET_TIME_US, C.UNSET_TIME_US);
C.TIME_UNSET, C.TIME_UNSET);
this.data = data;
}
......@@ -85,7 +85,7 @@ public abstract class DataChunk extends Chunk {
dataSource.open(dataSpec);
limit = 0;
int bytesRead = 0;
while (bytesRead != -1 && !loadCanceled) {
while (bytesRead != C.RESULT_END_OF_INPUT && !loadCanceled) {
maybeExpandData();
bytesRead = dataSource.read(data, limit, READ_GRANULARITY);
if (bytesRead != -1) {
......
......@@ -58,7 +58,7 @@ public final class InitializationChunk extends Chunk implements SingleTrackMetad
int trackSelectionReason, Object trackSelectionData,
ChunkExtractorWrapper extractorWrapper) {
super(dataSource, dataSpec, C.DATA_TYPE_MEDIA_INITIALIZATION, trackFormat, trackSelectionReason,
trackSelectionData, C.UNSET_TIME_US, C.UNSET_TIME_US);
trackSelectionData, C.TIME_UNSET, C.TIME_UNSET);
this.extractorWrapper = extractorWrapper;
}
......
......@@ -83,7 +83,7 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
try {
// Create and open the input.
long length = dataSource.open(loadDataSpec);
if (length != C.LENGTH_UNBOUNDED) {
if (length != C.LENGTH_UNSET) {
length += bytesLoaded;
}
ExtractorInput extractorInput = new DefaultExtractorInput(dataSource, bytesLoaded, length);
......
......@@ -141,7 +141,7 @@ import java.util.List;
@Override
public long readDiscontinuity() {
return C.UNSET_TIME_US;
return C.TIME_UNSET;
}
@Override
......@@ -149,11 +149,11 @@ import java.util.List;
long bufferedPositionUs = Long.MAX_VALUE;
for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
long rendererBufferedPositionUs = sampleStream.getBufferedPositionUs();
if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) {
if (rendererBufferedPositionUs != C.TIME_END_OF_SOURCE) {
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
}
}
return bufferedPositionUs == Long.MAX_VALUE ? C.END_OF_SOURCE_US : bufferedPositionUs;
return bufferedPositionUs == Long.MAX_VALUE ? C.TIME_END_OF_SOURCE : bufferedPositionUs;
}
@Override
......
......@@ -359,11 +359,11 @@ public final class DashMediaSource implements MediaSource {
if (manifest.dynamic && !lastPeriodSeekInfo.isIndexExplicit) {
long minStartPositionUs = firstPeriodSeekInfo.availableStartTimeUs;
long maxEndPositionUs = lastPeriodSeekInfo.availableEndTimeUs;
long timeShiftBufferDepthUs = manifest.timeShiftBufferDepth == -1 ? -1
: manifest.timeShiftBufferDepth * 1000;
long timeShiftBufferDepthUs = manifest.timeShiftBufferDepth == C.TIME_UNSET
? C.TIME_UNSET : (manifest.timeShiftBufferDepth * 1000);
currentEndTimeUs = Math.min(maxEndPositionUs,
getNowUnixTimeUs() - manifest.availabilityStartTime * 1000);
currentStartTimeUs = timeShiftBufferDepthUs == -1 ? minStartPositionUs
currentStartTimeUs = timeShiftBufferDepthUs == C.TIME_UNSET ? minStartPositionUs
: Math.max(minStartPositionUs, currentEndTimeUs - timeShiftBufferDepthUs);
// The window is changing implicitly. Post a simulated manifest refresh to update it.
handler.postDelayed(simulateManifestRefreshRunnable, NOTIFY_MANIFEST_INTERVAL_MS);
......@@ -379,7 +379,7 @@ public final class DashMediaSource implements MediaSource {
if (manifest.dynamic) {
long liveEdgeOffsetForManifestMs = liveEdgeOffsetMs;
if (liveEdgeOffsetForManifestMs == DEFAULT_LIVE_EDGE_OFFSET_PREFER_MANIFEST_MS) {
liveEdgeOffsetForManifestMs = manifest.suggestedPresentationDelay != -1
liveEdgeOffsetForManifestMs = manifest.suggestedPresentationDelay != C.TIME_UNSET
? manifest.suggestedPresentationDelay : DEFAULT_LIVE_EDGE_OFFSET_FIXED_MS;
}
defaultInitialTimeUs = Math.max(0, windowDurationUs - (liveEdgeOffsetForManifestMs * 1000));
......@@ -523,11 +523,11 @@ public final class DashMediaSource implements MediaSource {
@Override
public int getIndexOfPeriod(Object id) {
if (!(id instanceof Integer)) {
return NO_PERIOD_INDEX;
return C.INDEX_UNSET;
}
int periodId = (int) id;
return periodId < firstPeriodId || periodId >= firstPeriodId + getPeriodCount()
? NO_PERIOD_INDEX : periodId - firstPeriodId;
? C.INDEX_UNSET : (periodId - firstPeriodId);
}
@Override
......
......@@ -35,7 +35,7 @@ public interface DashSegmentIndex {
*
* @param timeUs The time in microseconds.
* @param periodDurationUs The duration of the enclosing period in microseconds, or
* {@link C#UNSET_TIME_US} if the period's duration is not yet known.
* {@link C#TIME_UNSET} if the period's duration is not yet known.
* @return The segment number of the corresponding segment.
*/
int getSegmentNum(long timeUs, long periodDurationUs);
......@@ -53,7 +53,7 @@ public interface DashSegmentIndex {
*
* @param segmentNum The segment number.
* @param periodDurationUs The duration of the enclosing period in microseconds, or
* {@link C#UNSET_TIME_US} if the period's duration is not yet known.
* {@link C#TIME_UNSET} if the period's duration is not yet known.
* @return The duration of the segment, in microseconds.
*/
long getDurationUs(int segmentNum, long periodDurationUs);
......@@ -81,7 +81,7 @@ public interface DashSegmentIndex {
* must manually determine the window of currently available segments.
*
* @param periodDurationUs The duration of the enclosing period in microseconds, or
* {@link C#UNSET_TIME_US} if the period's duration is not yet known.
* {@link C#TIME_UNSET} if the period's duration is not yet known.
* @return The segment number of the last segment, or {@link #INDEX_UNBOUNDED}.
*/
int getLastSegmentNum(long periodDurationUs);
......
......@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.dash;
import android.os.SystemClock;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.ChunkIndex;
import com.google.android.exoplayer2.extractor.Extractor;
......@@ -186,7 +187,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
// The index is itself unbounded. We need to use the current time to calculate the range of
// available segments.
long liveEdgeTimestampUs = nowUs - manifest.availabilityStartTime * 1000;
if (manifest.timeShiftBufferDepth != -1) {
if (manifest.timeShiftBufferDepth != C.TIME_UNSET) {
long bufferDepthUs = manifest.timeShiftBufferDepth * 1000;
firstAvailableSegmentNum = Math.max(firstAvailableSegmentNum,
representationHolder.getSegmentNum(liveEdgeTimestampUs - bufferDepthUs));
......
......@@ -23,6 +23,8 @@ import java.util.List;
*/
public class AdaptationSet {
public static final int UNSET_ID = -1;
public final int id;
public final int type;
......
......@@ -71,13 +71,12 @@ public class DashManifest {
public final long getPeriodDurationMs(int index) {
return index == periods.size() - 1
? (duration == -1 ? -1 : duration - periods.get(index).startMs)
: periods.get(index + 1).startMs - periods.get(index).startMs;
? (duration == C.TIME_UNSET ? C.TIME_UNSET : (duration - periods.get(index).startMs))
: (periods.get(index + 1).startMs - periods.get(index).startMs);
}
public final long getPeriodDurationUs(int index) {
long durationMs = getPeriodDurationMs(index);
return durationMs == -1 ? C.UNSET_TIME_US : durationMs * 1000;
return C.msToUs(getPeriodDurationMs(index));
}
}
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.C;
import java.util.Collections;
import java.util.List;
......@@ -50,11 +51,11 @@ public class Period {
}
/**
* Returns the index of the first adaptation set of a given type, or -1 if no adaptation set of
* the specified type exists.
* Returns the index of the first adaptation set of a given type, or {@link C#INDEX_UNSET} if no
* adaptation set of the specified type exists.
*
* @param type An adaptation set type.
* @return The index of the first adaptation set of the specified type, or -1.
* @return The index of the first adaptation set of the specified type, or {@link C#INDEX_UNSET}.
*/
public int getAdaptationSetIndex(int type) {
int adaptationCount = adaptationSets.size();
......@@ -63,7 +64,7 @@ public class Period {
return i;
}
}
return -1;
return C.INDEX_UNSET;
}
}
......@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.dash.manifest;
import android.net.Uri;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.UriUtil;
......@@ -30,7 +31,7 @@ public final class RangedUri {
public final long start;
/**
* The length of the range, or -1 to indicate that the range is unbounded.
* The length of the range, or {@link C#LENGTH_UNSET} to indicate that the range is unbounded.
*/
public final long length;
......@@ -50,7 +51,8 @@ public final class RangedUri {
* @param baseUri A uri that can form the base of the uri defined by the instance.
* @param referenceUri A reference uri that should be resolved with respect to {@code baseUri}.
* @param start The (zero based) index of the first byte of the range.
* @param length The length of the range, or -1 to indicate that the range is unbounded.
* @param length The length of the range, or {@link C#LENGTH_UNSET} to indicate that the range is
* unbounded.
*/
public RangedUri(String baseUri, String referenceUri, long start, long length) {
Assertions.checkArgument(baseUri != null || referenceUri != null);
......@@ -81,8 +83,8 @@ public final class RangedUri {
/**
* Attempts to merge this {@link RangedUri} with another.
* <p>
* A merge is successful if both instances define the same {@link Uri}, and if one starte the
* byte after the other ends, forming a contiguous region with no overlap.
* A merge is successful if both instances define the same {@link Uri}, and if one starts the byte
* after the other ends, forming a contiguous region with no overlap.
* <p>
* If {@code other} is null then the merge is considered unsuccessful, and null is returned.
*
......@@ -92,12 +94,12 @@ public final class RangedUri {
public RangedUri attemptMerge(RangedUri other) {
if (other == null || !getUriString().equals(other.getUriString())) {
return null;
} else if (length != -1 && start + length == other.start) {
} else if (length != C.LENGTH_UNSET && start + length == other.start) {
return new RangedUri(baseUri, referenceUri, start,
other.length == -1 ? -1 : length + other.length);
} else if (other.length != -1 && other.start + other.length == start) {
other.length == C.LENGTH_UNSET ? C.LENGTH_UNSET : length + other.length);
} else if (other.length != C.LENGTH_UNSET && other.start + other.length == start) {
return new RangedUri(baseUri, referenceUri, other.start,
length == -1 ? -1 : other.length + length);
length == C.LENGTH_UNSET ? C.LENGTH_UNSET : other.length + length);
} else {
return null;
}
......
......@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.dash.manifest;
import android.net.Uri;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.MultiSegmentBase;
......@@ -27,6 +28,11 @@ import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegm
public abstract class Representation {
/**
* A default value for {@link #revisionId}.
*/
public static final long REVISION_ID_DEFAULT = -1;
/**
* Identifies the piece of content to which this {@link Representation} belongs.
* <p>
* For example, all {@link Representation}s belonging to a video should have the same content
......@@ -82,7 +88,7 @@ public abstract class Representation {
SegmentBase segmentBase, String customCacheKey) {
if (segmentBase instanceof SingleSegmentBase) {
return new SingleSegmentRepresentation(contentId, revisionId, format,
(SingleSegmentBase) segmentBase, customCacheKey, -1);
(SingleSegmentBase) segmentBase, customCacheKey, C.LENGTH_UNSET);
} else if (segmentBase instanceof MultiSegmentBase) {
return new MultiSegmentRepresentation(contentId, revisionId, format,
(MultiSegmentBase) segmentBase, customCacheKey);
......@@ -141,7 +147,7 @@ public abstract class Representation {
public final Uri uri;
/**
* The content length, or -1 if unknown.
* The content length, or {@link C#LENGTH_UNSET} if unknown.
*/
public final long contentLength;
......@@ -158,7 +164,7 @@ public abstract class Representation {
* @param indexStart The offset of the first byte of index data.
* @param indexEnd The offset of the last byte of index data.
* @param customCacheKey A custom value to be returned from {@link #getCacheKey()}, or null.
* @param contentLength The content length, or -1 if unknown.
* @param contentLength The content length, or {@link C#LENGTH_UNSET} if unknown.
*/
public static SingleSegmentRepresentation newInstance(String contentId, long revisionId,
Format format, String uri, long initializationStart, long initializationEnd,
......@@ -177,7 +183,7 @@ public abstract class Representation {
* @param format The format of the representation.
* @param segmentBase The segment base underlying the representation.
* @param customCacheKey A custom value to be returned from {@link #getCacheKey()}, or null.
* @param contentLength The content length, or -1 if unknown.
* @param contentLength The content length, or {@link C#LENGTH_UNSET} if unknown.
*/
public SingleSegmentRepresentation(String contentId, long revisionId, Format format,
SingleSegmentBase segmentBase, String customCacheKey, long contentLength) {
......
......@@ -95,7 +95,7 @@ public abstract class SegmentBase {
* @param uri The uri of the segment.
*/
public SingleSegmentBase(String uri) {
this(null, 1, 0, uri, 0, -1);
this(null, 1, 0, uri, 0, 0);
}
public RangedUri getIndex() {
......@@ -316,7 +316,7 @@ public abstract class SegmentBase {
if (initializationTemplate != null) {
String urlString = initializationTemplate.buildUri(representation.format.id, 0,
representation.format.bitrate, 0);
return new RangedUri(baseUrl, urlString, 0, -1);
return new RangedUri(baseUrl, urlString, 0, C.LENGTH_UNSET);
} else {
return super.getInitialization(representation);
}
......@@ -332,14 +332,14 @@ public abstract class SegmentBase {
}
String uriString = mediaTemplate.buildUri(representation.format.id, sequenceNumber,
representation.format.bitrate, time);
return new RangedUri(baseUrl, uriString, 0, -1);
return new RangedUri(baseUrl, uriString, 0, C.LENGTH_UNSET);
}
@Override
public int getLastSegmentNum(long periodDurationUs) {
if (segmentTimeline != null) {
return segmentTimeline.size() + startNumber - 1;
} else if (periodDurationUs == C.UNSET_TIME_US) {
} else if (periodDurationUs == C.TIME_UNSET) {
return DashSegmentIndex.INDEX_UNBOUNDED;
} else {
long durationUs = (duration * C.MICROS_PER_SECOND) / timescale;
......
......@@ -81,7 +81,7 @@ import javax.crypto.spec.SecretKeySpec;
cipherInputStream = new CipherInputStream(
new DataSourceInputStream(upstream, dataSpec), cipher);
return C.LENGTH_UNBOUNDED;
return C.LENGTH_UNSET;
}
@Override
......@@ -95,7 +95,7 @@ import javax.crypto.spec.SecretKeySpec;
Assertions.checkState(cipherInputStream != null);
int bytesRead = cipherInputStream.read(buffer, offset, readLength);
if (bytesRead < 0) {
return -1;
return C.RESULT_END_OF_INPUT;
}
return bytesRead;
}
......
......@@ -139,7 +139,7 @@ public class HlsChunkSource {
}
/**
* Returns the duration of the source, or {@link C#UNSET_TIME_US} if the duration is unknown.
* Returns the duration of the source, or {@link C#TIME_UNSET} if the duration is unknown.
*/
public long getDurationUs() {
return durationUs;
......@@ -182,7 +182,8 @@ public class HlsChunkSource {
* @param out A holder to populate.
*/
public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, ChunkHolder out) {
int oldVariantIndex = previous == null ? -1 : trackGroup.indexOf(previous.trackFormat);
int oldVariantIndex = previous == null ? C.INDEX_UNSET
: trackGroup.indexOf(previous.trackFormat);
// Use start time of the previous chunk rather than its end time because switching format will
// require downloading overlapping segments.
......@@ -422,7 +423,7 @@ public class HlsChunkSource {
private MediaPlaylistChunk newMediaPlaylistChunk(int variantIndex, int trackSelectionReason,
Object trackSelectionData) {
Uri mediaPlaylistUri = UriUtil.resolveToUri(baseUri, variants[variantIndex].url);
DataSpec dataSpec = new DataSpec(mediaPlaylistUri, 0, C.LENGTH_UNBOUNDED, null,
DataSpec dataSpec = new DataSpec(mediaPlaylistUri, 0, C.LENGTH_UNSET, null,
DataSpec.FLAG_ALLOW_GZIP);
return new MediaPlaylistChunk(dataSource, dataSpec, variants[variantIndex].format,
trackSelectionReason, trackSelectionData, scratchSpace, playlistParser, variantIndex,
......@@ -431,7 +432,7 @@ public class HlsChunkSource {
private EncryptionKeyChunk newEncryptionKeyChunk(Uri keyUri, String iv, int variantIndex,
int trackSelectionReason, Object trackSelectionData) {
DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNBOUNDED, null, DataSpec.FLAG_ALLOW_GZIP);
DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP);
return new EncryptionKeyChunk(dataSource, dataSpec, variants[variantIndex].format,
trackSelectionReason, trackSelectionData, scratchSpace, iv);
}
......@@ -467,7 +468,7 @@ public class HlsChunkSource {
variantLastPlaylistLoadTimesMs[variantIndex] = SystemClock.elapsedRealtime();
variantPlaylists[variantIndex] = mediaPlaylist;
live |= mediaPlaylist.live;
durationUs = live ? C.UNSET_TIME_US : mediaPlaylist.durationUs;
durationUs = live ? C.TIME_UNSET : mediaPlaylist.durationUs;
}
// Private classes.
......
......@@ -125,12 +125,13 @@ import java.util.List;
int[] streamChildIndices = new int[selections.length];
int[] selectionChildIndices = new int[selections.length];
for (int i = 0; i < selections.length; i++) {
streamChildIndices[i] = streams[i] == null ? -1 : streamWrapperIndices.get(streams[i]);
selectionChildIndices[i] = -1;
streamChildIndices[i] = streams[i] == null ? C.INDEX_UNSET
: streamWrapperIndices.get(streams[i]);
selectionChildIndices[i] = C.INDEX_UNSET;
if (selections[i] != null) {
TrackGroup trackGroup = selections[i].getTrackGroup();
for (int j = 0; j < sampleStreamWrappers.length; j++) {
if (sampleStreamWrappers[j].getTrackGroups().indexOf(trackGroup) != -1) {
if (sampleStreamWrappers[j].getTrackGroups().indexOf(trackGroup) != C.INDEX_UNSET) {
selectionChildIndices[i] = j;
break;
}
......@@ -194,7 +195,7 @@ import java.util.List;
@Override
public long readDiscontinuity() {
return C.UNSET_TIME_US;
return C.TIME_UNSET;
}
@Override
......@@ -202,11 +203,11 @@ import java.util.List;
long bufferedPositionUs = Long.MAX_VALUE;
for (HlsSampleStreamWrapper sampleStreamWrapper : enabledSampleStreamWrappers) {
long rendererBufferedPositionUs = sampleStreamWrapper.getBufferedPositionUs();
if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) {
if (rendererBufferedPositionUs != C.TIME_END_OF_SOURCE) {
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
}
}
return bufferedPositionUs == Long.MAX_VALUE ? C.END_OF_SOURCE_US : bufferedPositionUs;
return bufferedPositionUs == Long.MAX_VALUE ? C.TIME_END_OF_SOURCE : bufferedPositionUs;
}
@Override
......
......@@ -64,7 +64,7 @@ public final class HlsMediaSource implements MediaSource {
public void prepareSource(MediaSource.Listener listener) {
sourceListener = listener;
// TODO: Defer until the playlist has been loaded.
listener.onSourceInfoRefreshed(new SinglePeriodTimeline(C.UNSET_TIME_US, false), null);
listener.onSourceInfoRefreshed(new SinglePeriodTimeline(C.TIME_UNSET, false), null);
}
@Override
......
......@@ -214,7 +214,7 @@ import java.util.LinkedList;
public long getBufferedPositionUs() {
if (loadingFinished) {
return C.END_OF_SOURCE_US;
return C.TIME_END_OF_SOURCE;
} else if (isPendingReset()) {
return pendingResetPositionUs;
} else {
......@@ -302,7 +302,7 @@ import java.util.LinkedList;
}
chunkSource.getNextChunk(mediaChunks.isEmpty() ? null : mediaChunks.getLast(),
pendingResetPositionUs != C.UNSET_TIME_US ? pendingResetPositionUs : positionUs,
pendingResetPositionUs != C.TIME_UNSET ? pendingResetPositionUs : positionUs,
nextChunkHolder);
boolean endOfStream = nextChunkHolder.endOfStream;
Chunk loadable = nextChunkHolder.chunk;
......@@ -318,7 +318,7 @@ import java.util.LinkedList;
}
if (isMediaChunk(loadable)) {
pendingResetPositionUs = C.UNSET_TIME_US;
pendingResetPositionUs = C.TIME_UNSET;
HlsMediaChunk mediaChunk = (HlsMediaChunk) loadable;
mediaChunk.init(this);
mediaChunks.add(mediaChunk);
......@@ -335,7 +335,7 @@ import java.util.LinkedList;
if (isPendingReset()) {
return pendingResetPositionUs;
} else {
return loadingFinished ? C.END_OF_SOURCE_US : mediaChunks.getLast().endTimeUs;
return loadingFinished ? C.TIME_END_OF_SOURCE : mediaChunks.getLast().endTimeUs;
}
}
......@@ -505,7 +505,7 @@ import java.util.LinkedList;
// Iterate through the extractor tracks to discover the "primary" track type, and the index
// of the single track of this type.
int primaryExtractorTrackType = PRIMARY_TYPE_NONE;
int primaryExtractorTrackIndex = -1;
int primaryExtractorTrackIndex = C.INDEX_UNSET;
int extractorTrackCount = sampleQueues.size();
for (int i = 0; i < extractorTrackCount; i++) {
String sampleMimeType = sampleQueues.valueAt(i).getUpstreamFormat().sampleMimeType;
......@@ -522,10 +522,11 @@ import java.util.LinkedList;
if (trackType > primaryExtractorTrackType) {
primaryExtractorTrackType = trackType;
primaryExtractorTrackIndex = i;
} else if (trackType == primaryExtractorTrackType && primaryExtractorTrackIndex != -1) {
// We have multiple tracks of the primary type. We only want an index if there only
// exists a single track of the primary type, so set the index back to -1.
primaryExtractorTrackIndex = -1;
} else if (trackType == primaryExtractorTrackType
&& primaryExtractorTrackIndex != C.INDEX_UNSET) {
// We have multiple tracks of the primary type. We only want an index if there only exists a
// single track of the primary type, so unset the index again.
primaryExtractorTrackIndex = C.INDEX_UNSET;
}
}
......@@ -533,7 +534,7 @@ import java.util.LinkedList;
int chunkSourceTrackCount = chunkSourceTrackGroup.length;
// Instantiate the necessary internal data-structures.
primaryTrackGroupIndex = -1;
primaryTrackGroupIndex = C.INDEX_UNSET;
groupEnabledStates = new boolean[extractorTrackCount];
// Construct the set of exposed track groups.
......@@ -596,7 +597,7 @@ import java.util.LinkedList;
}
private boolean isPendingReset() {
return pendingResetPositionUs != C.UNSET_TIME_US;
return pendingResetPositionUs != C.TIME_UNSET;
}
private final class SampleStreamImpl implements SampleStream {
......
......@@ -75,7 +75,7 @@ import java.util.regex.Pattern;
@Override
public void init(ExtractorOutput output) {
this.output = output;
output.seekMap(new SeekMap.Unseekable(C.UNSET_TIME_US));
output.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
}
@Override
......@@ -97,14 +97,14 @@ import java.util.regex.Pattern;
// Increase the size of sampleData if necessary.
if (sampleSize == sampleData.length) {
sampleData = Arrays.copyOf(sampleData,
(currentFileSize != C.LENGTH_UNBOUNDED ? currentFileSize : sampleData.length) * 3 / 2);
(currentFileSize != C.LENGTH_UNSET ? currentFileSize : sampleData.length) * 3 / 2);
}
// Consume to the input.
int bytesRead = input.read(sampleData, sampleSize, sampleData.length - sampleSize);
if (bytesRead != C.RESULT_END_OF_INPUT) {
sampleSize += bytesRead;
if (currentFileSize == C.LENGTH_UNBOUNDED || sampleSize != currentFileSize) {
if (currentFileSize == C.LENGTH_UNSET || sampleSize != currentFileSize) {
return Extractor.RESULT_CONTINUE;
}
}
......
......@@ -127,8 +127,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
ArrayList<Variant> subtitles = new ArrayList<>();
int bitrate = 0;
String codecs = null;
int width = -1;
int height = -1;
int width = Format.NO_VALUE;
int height = Format.NO_VALUE;
String name = null;
Format muxedAudioFormat = null;
Format muxedCaptionFormat = null;
......@@ -153,8 +153,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
String captionName = parseStringAttr(line, REGEX_NAME);
String language = parseOptionalStringAttr(line, REGEX_LANGUAGE);
muxedCaptionFormat = Format.createTextContainerFormat(captionName,
MimeTypes.APPLICATION_M3U8, MimeTypes.APPLICATION_EIA608, null, -1, selectionFlags,
language);
MimeTypes.APPLICATION_M3U8, MimeTypes.APPLICATION_EIA608, null, Format.NO_VALUE,
selectionFlags, language);
}
} else if (TYPE_SUBTITLES.equals(type)) {
// We assume all subtitles belong to the same group.
......@@ -169,9 +169,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
String uri = parseOptionalStringAttr(line, REGEX_URI);
String language = parseOptionalStringAttr(line, REGEX_LANGUAGE);
String audioName = parseStringAttr(line, REGEX_NAME);
int audioBitrate = uri != null ? bitrate : -1;
int audioBitrate = uri != null ? bitrate : Format.NO_VALUE;
Format format = Format.createAudioContainerFormat(audioName, MimeTypes.APPLICATION_M3U8,
null, null, audioBitrate, -1, -1, null, selectionFlags, language);
null, null, audioBitrate, Format.NO_VALUE, Format.NO_VALUE, null, selectionFlags,
language);
if (uri != null) {
audios.add(new Variant(uri, format, codecs));
} else {
......@@ -188,16 +189,16 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
width = Integer.parseInt(widthAndHeight[0]);
if (width <= 0) {
// Width was invalid.
width = -1;
width = Format.NO_VALUE;
}
height = Integer.parseInt(widthAndHeight[1]);
if (height <= 0) {
// Height was invalid.
height = -1;
height = Format.NO_VALUE;
}
} else {
width = -1;
height = -1;
width = Format.NO_VALUE;
height = Format.NO_VALUE;
}
expectingStreamInfUrl = true;
} else if (!line.startsWith("#") && expectingStreamInfUrl) {
......@@ -210,8 +211,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
bitrate = 0;
codecs = null;
name = null;
width = -1;
height = -1;
width = Format.NO_VALUE;
height = Format.NO_VALUE;
expectingStreamInfUrl = false;
}
}
......@@ -231,7 +232,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
int discontinuitySequenceNumber = 0;
long segmentStartTimeUs = 0;
long segmentByterangeOffset = 0;
long segmentByterangeLength = C.LENGTH_UNBOUNDED;
long segmentByterangeLength = C.LENGTH_UNSET;
int segmentMediaSequence = 0;
boolean isEncrypted = false;
......@@ -281,7 +282,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
segmentEncryptionIV = Integer.toHexString(segmentMediaSequence);
}
segmentMediaSequence++;
if (segmentByterangeLength == C.LENGTH_UNBOUNDED) {
if (segmentByterangeLength == C.LENGTH_UNSET) {
segmentByterangeOffset = 0;
}
segments.add(new Segment(line, segmentDurationSecs, discontinuitySequenceNumber,
......@@ -289,10 +290,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
segmentByterangeOffset, segmentByterangeLength));
segmentStartTimeUs += (long) (segmentDurationSecs * C.MICROS_PER_SECOND);
segmentDurationSecs = 0.0;
if (segmentByterangeLength != C.LENGTH_UNBOUNDED) {
if (segmentByterangeLength != C.LENGTH_UNSET) {
segmentByterangeOffset += segmentByterangeLength;
}
segmentByterangeLength = C.LENGTH_UNBOUNDED;
segmentByterangeLength = C.LENGTH_UNSET;
} else if (line.equals(TAG_ENDLIST)) {
live = false;
}
......
......@@ -97,7 +97,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
Format format = streamElement.formats[manifestTrackIndex];
int nalUnitLengthFieldLength = streamElement.type == C.TRACK_TYPE_VIDEO ? 4 : -1;
Track track = new Track(manifestTrackIndex, streamElement.type, streamElement.timescale,
C.UNSET_TIME_US, manifest.durationUs, format, Track.TRANSFORMATION_NONE,
C.TIME_UNSET, manifest.durationUs, format, Track.TRANSFORMATION_NONE,
trackEncryptionBoxes, nalUnitLengthFieldLength, null, null);
FragmentedMp4Extractor extractor = new FragmentedMp4Extractor(
FragmentedMp4Extractor.FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME
......@@ -213,7 +213,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
private static MediaChunk newMediaChunk(Format format, DataSource dataSource, Uri uri,
String cacheKey, int chunkIndex, long chunkStartTimeUs, long chunkEndTimeUs,
int trackSelectionReason, Object trackSelectionData, ChunkExtractorWrapper extractorWrapper) {
DataSpec dataSpec = new DataSpec(uri, 0, -1, cacheKey);
DataSpec dataSpec = new DataSpec(uri, 0, C.LENGTH_UNSET, cacheKey);
// In SmoothStreaming each chunk contains sample timestamps relative to the start of the chunk.
// To convert them the absolute timestamps, we need to set sampleOffsetUs to chunkStartTimeUs.
long sampleOffsetUs = chunkStartTimeUs;
......
......@@ -144,7 +144,7 @@ import java.util.ArrayList;
@Override
public long readDiscontinuity() {
return C.UNSET_TIME_US;
return C.TIME_UNSET;
}
@Override
......@@ -152,11 +152,11 @@ import java.util.ArrayList;
long bufferedPositionUs = Long.MAX_VALUE;
for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
long rendererBufferedPositionUs = sampleStream.getBufferedPositionUs();
if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) {
if (rendererBufferedPositionUs != C.TIME_END_OF_SOURCE) {
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
}
}
return bufferedPositionUs == Long.MAX_VALUE ? C.END_OF_SOURCE_US : bufferedPositionUs;
return bufferedPositionUs == Long.MAX_VALUE ? C.TIME_END_OF_SOURCE : bufferedPositionUs;
}
@Override
......
......@@ -170,9 +170,9 @@ public final class SsMediaSource implements MediaSource,
}
}
if (startTimeUs == Long.MAX_VALUE) {
timeline = new SinglePeriodTimeline(C.UNSET_TIME_US, false);
timeline = new SinglePeriodTimeline(C.TIME_UNSET, false);
} else {
if (manifest.dvrWindowLengthUs != C.UNSET_TIME_US
if (manifest.dvrWindowLengthUs != C.TIME_UNSET
&& manifest.dvrWindowLengthUs > 0) {
startTimeUs = Math.max(startTimeUs, endTimeUs - manifest.dvrWindowLengthUs);
}
......@@ -183,7 +183,7 @@ public final class SsMediaSource implements MediaSource,
timeline = new SinglePeriodTimeline(startTimeUs, window);
}
} else {
boolean isSeekable = manifest.durationUs != C.UNSET_TIME_US;
boolean isSeekable = manifest.durationUs != C.TIME_UNSET;
timeline = new SinglePeriodTimeline(manifest.durationUs, isSeekable);
}
sourceListener.onSourceInfoRefreshed(timeline, manifest);
......
......@@ -32,6 +32,8 @@ import java.util.UUID;
*/
public class SsManifest {
public static final int UNSET_LOOKAHEAD = -1;
/**
* The client manifest major version.
*/
......@@ -43,7 +45,8 @@ public class SsManifest {
public final int minorVersion;
/**
* The number of fragments in a lookahead, or -1 if the lookahead is unspecified.
* The number of fragments in a lookahead, or {@link #UNSET_LOOKAHEAD} if the lookahead is
* unspecified.
*/
public final int lookAheadCount;
......@@ -63,14 +66,14 @@ public class SsManifest {
public final StreamElement[] streamElements;
/**
* The overall presentation duration of the media in microseconds, or {@link C#UNSET_TIME_US}
* The overall presentation duration of the media in microseconds, or {@link C#TIME_UNSET}
* if the duration is unknown.
*/
public final long durationUs;
/**
* The length of the trailing window for a live broadcast in microseconds, or
* {@link C#UNSET_TIME_US} if the stream is not live or if the window length is unspecified.
* {@link C#TIME_UNSET} if the stream is not live or if the window length is unspecified.
*/
public final long dvrWindowLengthUs;
......@@ -82,8 +85,8 @@ public class SsManifest {
* if the duration is unknown.
* @param dvrWindowLength The length of the trailing window in units of the timescale attribute,
* or 0 if this attribute is unspecified or not applicable.
* @param lookAheadCount The number of fragments in a lookahead, or -1 if this attribute is
* unspecified or not applicable.
* @param lookAheadCount The number of fragments in a lookahead, or {@link #UNSET_LOOKAHEAD} if
* this attribute is unspecified or not applicable.
* @param isLive True if the manifest describes a live presentation still in progress. False
* otherwise.
* @param protectionElement Content protection information, or null if the content is not
......@@ -99,9 +102,9 @@ public class SsManifest {
this.isLive = isLive;
this.protectionElement = protectionElement;
this.streamElements = streamElements;
dvrWindowLengthUs = dvrWindowLength == 0 ? C.UNSET_TIME_US
dvrWindowLengthUs = dvrWindowLength == 0 ? C.TIME_UNSET
: Util.scaleLargeTimestamp(dvrWindowLength, C.MICROS_PER_SECOND, timescale);
durationUs = duration == 0 ? C.UNSET_TIME_US
durationUs = duration == 0 ? C.TIME_UNSET
: Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, timescale);
}
......@@ -132,7 +135,6 @@ public class SsManifest {
public final String subType;
public final long timescale;
public final String name;
public final int qualityLevels;
public final int maxWidth;
public final int maxHeight;
public final int displayWidth;
......@@ -149,16 +151,15 @@ public class SsManifest {
private final long lastChunkDurationUs;
public StreamElement(String baseUri, String chunkTemplate, int type, String subType,
long timescale, String name, int qualityLevels, int maxWidth, int maxHeight,
int displayWidth, int displayHeight, String language, Format[] formats,
List<Long> chunkStartTimes, long lastChunkDuration) {
long timescale, String name, int maxWidth, int maxHeight, int displayWidth,
int displayHeight, String language, Format[] formats, List<Long> chunkStartTimes,
long lastChunkDuration) {
this.baseUri = baseUri;
this.chunkTemplate = chunkTemplate;
this.type = type;
this.subType = subType;
this.timescale = timescale;
this.name = name;
this.qualityLevels = qualityLevels;
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.displayWidth = displayWidth;
......
......@@ -343,7 +343,7 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
public SmoothStreamingMediaParser(ElementParser parent, String baseUri) {
super(parent, baseUri, TAG);
lookAheadCount = -1;
lookAheadCount = SsManifest.UNSET_LOOKAHEAD;
protectionElement = null;
streamElements = new LinkedList<>();
}
......@@ -355,7 +355,7 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
timescale = parseLong(parser, KEY_TIME_SCALE, 10000000L);
duration = parseRequiredLong(parser, KEY_DURATION);
dvrWindowLength = parseLong(parser, KEY_DVR_WINDOW_LENGTH, 0);
lookAheadCount = parseInt(parser, KEY_LOOKAHEAD_COUNT, -1);
lookAheadCount = parseInt(parser, KEY_LOOKAHEAD_COUNT, SsManifest.UNSET_LOOKAHEAD);
isLive = parseBoolean(parser, KEY_IS_LIVE, false);
putNormalizedAttribute(KEY_TIME_SCALE, timescale);
}
......@@ -477,7 +477,6 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
private String subType;
private long timescale;
private String name;
private int qualityLevels;
private String url;
private int maxWidth;
private int maxHeight;
......@@ -510,12 +509,12 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
private void parseStreamFragmentStartTag(XmlPullParser parser) throws ParserException {
int chunkIndex = startTimes.size();
long startTime = parseLong(parser, KEY_FRAGMENT_START_TIME, -1L);
if (startTime == -1L) {
long startTime = parseLong(parser, KEY_FRAGMENT_START_TIME, C.TIME_UNSET);
if (startTime == C.TIME_UNSET) {
if (chunkIndex == 0) {
// Assume the track starts at t = 0.
startTime = 0;
} else if (lastChunkDuration != -1L) {
} else if (lastChunkDuration != C.INDEX_UNSET) {
// Infer the start time from the previous chunk's start time and duration.
startTime = startTimes.get(chunkIndex - 1) + lastChunkDuration;
} else {
......@@ -525,10 +524,10 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
}
chunkIndex++;
startTimes.add(startTime);
lastChunkDuration = parseLong(parser, KEY_FRAGMENT_DURATION, -1L);
lastChunkDuration = parseLong(parser, KEY_FRAGMENT_DURATION, C.TIME_UNSET);
// Handle repeated chunks.
long repeatCount = parseLong(parser, KEY_FRAGMENT_REPEAT_COUNT, 1L);
if (repeatCount > 1 && lastChunkDuration == -1L) {
if (repeatCount > 1 && lastChunkDuration == C.TIME_UNSET) {
throw new ParserException("Repeated chunk with unspecified duration");
}
for (int i = 1; i < repeatCount; i++) {
......@@ -546,12 +545,11 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
subType = parser.getAttributeValue(null, KEY_SUB_TYPE);
}
name = parser.getAttributeValue(null, KEY_NAME);
qualityLevels = parseInt(parser, KEY_QUALITY_LEVELS, -1);
url = parseRequiredString(parser, KEY_URL);
maxWidth = parseInt(parser, KEY_MAX_WIDTH, -1);
maxHeight = parseInt(parser, KEY_MAX_HEIGHT, -1);
displayWidth = parseInt(parser, KEY_DISPLAY_WIDTH, -1);
displayHeight = parseInt(parser, KEY_DISPLAY_HEIGHT, -1);
maxWidth = parseInt(parser, KEY_MAX_WIDTH, Format.NO_VALUE);
maxHeight = parseInt(parser, KEY_MAX_HEIGHT, Format.NO_VALUE);
displayWidth = parseInt(parser, KEY_DISPLAY_WIDTH, Format.NO_VALUE);
displayHeight = parseInt(parser, KEY_DISPLAY_HEIGHT, Format.NO_VALUE);
language = parser.getAttributeValue(null, KEY_LANGUAGE);
putNormalizedAttribute(KEY_LANGUAGE, language);
timescale = parseInt(parser, KEY_TIME_SCALE, -1);
......@@ -588,9 +586,8 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
public Object build() {
Format[] formatArray = new Format[formats.size()];
formats.toArray(formatArray);
return new StreamElement(baseUri, url, type, subType, timescale, name, qualityLevels,
maxWidth, maxHeight, displayWidth, displayHeight, language, formatArray, startTimes,
lastChunkDuration);
return new StreamElement(baseUri, url, type, subType, timescale, name, maxWidth, maxHeight,
displayWidth, displayHeight, language, formatArray, startTimes, lastChunkDuration);
}
}
......
......@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.text;
import com.google.android.exoplayer2.C;
import java.util.List;
/**
......@@ -26,7 +27,8 @@ public interface Subtitle {
* Returns the index of the first event that occurs after a given time (exclusive).
*
* @param timeUs The time in microseconds.
* @return The index of the next event, or -1 if there are no events after the specified time.
* @return The index of the next event, or {@link C#INDEX_UNSET} if there are no events after the
* specified time.
*/
int getNextEventTimeIndex(long timeUs);
......
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