Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
da656e6f
authored
Apr 11, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
More steps towards unified extractors.
parent
53a47524
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
161 additions
and
72 deletions
library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java
library/src/main/java/com/google/android/exoplayer/extractor/RollingSampleBuffer.java
library/src/main/java/com/google/android/exoplayer/hls/HlsExtractorWrapper.java
library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java
library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java
View file @
da656e6f
...
@@ -24,9 +24,8 @@ import com.google.android.exoplayer.util.ParsableByteArray;
...
@@ -24,9 +24,8 @@ import com.google.android.exoplayer.util.ParsableByteArray;
import
java.io.IOException
;
import
java.io.IOException
;
/**
/**
* Wraps a {@link RollingSampleBuffer}, adding higher level functionality such as enforcing that
* A {@link TrackOutput} that buffers extracted samples in a queue, and allows for consumption from
* the first sample returned from the queue is a keyframe, allowing splicing to another queue, and
* that queue.
* so on.
*/
*/
public
final
class
DefaultTrackOutput
implements
TrackOutput
{
public
final
class
DefaultTrackOutput
implements
TrackOutput
{
...
@@ -51,27 +50,60 @@ public final class DefaultTrackOutput implements TrackOutput {
...
@@ -51,27 +50,60 @@ public final class DefaultTrackOutput implements TrackOutput {
largestParsedTimestampUs
=
Long
.
MIN_VALUE
;
largestParsedTimestampUs
=
Long
.
MIN_VALUE
;
}
}
public
void
release
()
{
// Called by the consuming thread, but only when there is no loading thread.
rollingBuffer
.
release
();
/**
* Clears the queue, returning all allocations to the allocator.
*/
public
void
clear
()
{
rollingBuffer
.
clear
();
needKeyframe
=
true
;
lastReadTimeUs
=
Long
.
MIN_VALUE
;
spliceOutTimeUs
=
Long
.
MIN_VALUE
;
largestParsedTimestampUs
=
Long
.
MIN_VALUE
;
}
/**
* Returns the current absolute write index.
*/
public
int
getWriteIndex
()
{
return
rollingBuffer
.
getWriteIndex
();
}
}
// Called by the consuming thread.
// Called by the consuming thread.
/**
/**
* Returns the current absolute read index.
*/
public
int
getReadIndex
()
{
return
rollingBuffer
.
getReadIndex
();
}
/**
* True if the output has received a format. False otherwise.
* True if the output has received a format. False otherwise.
*/
*/
public
boolean
hasFormat
()
{
public
boolean
hasFormat
()
{
return
format
!=
null
;
return
format
!=
null
;
}
}
/**
* The format most recently received by the output, or null if a format has yet to be received.
*/
public
MediaFormat
getFormat
()
{
public
MediaFormat
getFormat
()
{
return
format
;
return
format
;
}
}
/**
* The largest timestamp of any sample received by the output, or {@link Long#MIN_VALUE} if a
* sample has yet to be received.
*/
public
long
getLargestParsedTimestampUs
()
{
public
long
getLargestParsedTimestampUs
()
{
return
largestParsedTimestampUs
;
return
largestParsedTimestampUs
;
}
}
/**
* True if at least one sample can be read from the queue. False otherwise.
*/
public
boolean
isEmpty
()
{
public
boolean
isEmpty
()
{
return
!
advanceToEligibleSample
();
return
!
advanceToEligibleSample
();
}
}
...
...
library/src/main/java/com/google/android/exoplayer/extractor/RollingSampleBuffer.java
View file @
da656e6f
...
@@ -55,17 +55,42 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -55,17 +55,42 @@ import java.util.concurrent.ConcurrentLinkedQueue;
dataQueue
=
new
ConcurrentLinkedQueue
<
byte
[]>();
dataQueue
=
new
ConcurrentLinkedQueue
<
byte
[]>();
extrasHolder
=
new
SampleExtrasHolder
();
extrasHolder
=
new
SampleExtrasHolder
();
scratch
=
new
ParsableByteArray
(
INITIAL_SCRATCH_SIZE
);
scratch
=
new
ParsableByteArray
(
INITIAL_SCRATCH_SIZE
);
lastFragmentOffset
=
fragmentLength
;
}
}
public
void
release
()
{
// Called by the consuming thread, but only when there is no loading thread.
/**
* Clears the buffer, returning all allocations to the allocator.
*/
public
void
clear
()
{
infoQueue
.
clear
();
while
(!
dataQueue
.
isEmpty
())
{
while
(!
dataQueue
.
isEmpty
())
{
fragmentPool
.
releaseDirect
(
dataQueue
.
remove
());
fragmentPool
.
releaseDirect
(
dataQueue
.
remove
());
}
}
totalBytesDropped
=
0
;
totalBytesWritten
=
0
;
lastFragment
=
null
;
lastFragmentOffset
=
fragmentLength
;
}
/**
* Returns the current absolute write index.
*/
public
int
getWriteIndex
()
{
return
infoQueue
.
getWriteIndex
();
}
}
// Called by the consuming thread.
// Called by the consuming thread.
/**
/**
* Returns the current absolute read index.
*/
public
int
getReadIndex
()
{
return
infoQueue
.
getReadIndex
();
}
/**
* Fills {@code holder} with information about the current sample, but does not write its data.
* Fills {@code holder} with information about the current sample, but does not write its data.
* <p>
* <p>
* The fields set are {@link SampleHolder#size}, {@link SampleHolder#timeUs} and
* The fields set are {@link SampleHolder#size}, {@link SampleHolder#timeUs} and
...
@@ -83,7 +108,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -83,7 +108,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
*/
*/
public
void
skipSample
()
{
public
void
skipSample
()
{
long
nextOffset
=
infoQueue
.
moveToNextSample
();
long
nextOffset
=
infoQueue
.
moveToNextSample
();
drop
Fragments
To
(
nextOffset
);
drop
Downstream
To
(
nextOffset
);
}
}
/**
/**
...
@@ -112,7 +137,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -112,7 +137,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
}
}
// Advance the read head.
// Advance the read head.
long
nextOffset
=
infoQueue
.
moveToNextSample
();
long
nextOffset
=
infoQueue
.
moveToNextSample
();
drop
Fragments
To
(
nextOffset
);
drop
Downstream
To
(
nextOffset
);
return
true
;
return
true
;
}
}
...
@@ -198,7 +223,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -198,7 +223,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
private
void
readData
(
long
absolutePosition
,
ByteBuffer
target
,
int
length
)
{
private
void
readData
(
long
absolutePosition
,
ByteBuffer
target
,
int
length
)
{
int
remaining
=
length
;
int
remaining
=
length
;
while
(
remaining
>
0
)
{
while
(
remaining
>
0
)
{
drop
Fragments
To
(
absolutePosition
);
drop
Downstream
To
(
absolutePosition
);
int
positionInFragment
=
(
int
)
(
absolutePosition
-
totalBytesDropped
);
int
positionInFragment
=
(
int
)
(
absolutePosition
-
totalBytesDropped
);
int
toCopy
=
Math
.
min
(
remaining
,
fragmentLength
-
positionInFragment
);
int
toCopy
=
Math
.
min
(
remaining
,
fragmentLength
-
positionInFragment
);
target
.
put
(
dataQueue
.
peek
(),
positionInFragment
,
toCopy
);
target
.
put
(
dataQueue
.
peek
(),
positionInFragment
,
toCopy
);
...
@@ -216,14 +241,14 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -216,14 +241,14 @@ import java.util.concurrent.ConcurrentLinkedQueue;
*/
*/
// TODO: Consider reducing duplication of this method and the one above.
// TODO: Consider reducing duplication of this method and the one above.
private
void
readData
(
long
absolutePosition
,
byte
[]
target
,
int
length
)
{
private
void
readData
(
long
absolutePosition
,
byte
[]
target
,
int
length
)
{
int
remaining
=
length
;
int
bytesRead
=
0
;
while
(
remaining
>
0
)
{
while
(
bytesRead
<
length
)
{
drop
Fragments
To
(
absolutePosition
);
drop
Downstream
To
(
absolutePosition
);
int
positionInFragment
=
(
int
)
(
absolutePosition
-
totalBytesDropped
);
int
positionInFragment
=
(
int
)
(
absolutePosition
-
totalBytesDropped
);
int
toCopy
=
Math
.
min
(
remaining
,
fragmentLength
-
positionInFragment
);
int
toCopy
=
Math
.
min
(
length
-
bytesRead
,
fragmentLength
-
positionInFragment
);
System
.
arraycopy
(
dataQueue
.
peek
(),
positionInFragment
,
target
,
0
,
toCopy
);
System
.
arraycopy
(
dataQueue
.
peek
(),
positionInFragment
,
target
,
bytesRead
,
toCopy
);
absolutePosition
+=
toCopy
;
absolutePosition
+=
toCopy
;
remaining
-
=
toCopy
;
bytesRead
+
=
toCopy
;
}
}
}
}
...
@@ -233,7 +258,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -233,7 +258,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
*
*
* @param absolutePosition The absolute position up to which fragments can be discarded.
* @param absolutePosition The absolute position up to which fragments can be discarded.
*/
*/
private
void
drop
Fragments
To
(
long
absolutePosition
)
{
private
void
drop
Downstream
To
(
long
absolutePosition
)
{
int
relativePosition
=
(
int
)
(
absolutePosition
-
totalBytesDropped
);
int
relativePosition
=
(
int
)
(
absolutePosition
-
totalBytesDropped
);
int
fragmentIndex
=
relativePosition
/
fragmentLength
;
int
fragmentIndex
=
relativePosition
/
fragmentLength
;
for
(
int
i
=
0
;
i
<
fragmentIndex
;
i
++)
{
for
(
int
i
=
0
;
i
<
fragmentIndex
;
i
++)
{
...
@@ -266,24 +291,23 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -266,24 +291,23 @@ import java.util.concurrent.ConcurrentLinkedQueue;
* Appends data to the rolling buffer.
* Appends data to the rolling buffer.
*
*
* @param dataSource The source from which to read.
* @param dataSource The source from which to read.
* @param length The maximum length of the read.
* @param length The maximum length of the read, or {@link C#LENGTH_UNBOUNDED} if the caller does
* @return The number of bytes read, or -1 if the the end of the source has been reached.
* not wish to impose a limit.
* @return The number of bytes appended.
* @throws IOException If an error occurs reading from the source.
* @throws IOException If an error occurs reading from the source.
*/
*/
public
int
appendData
(
DataSource
dataSource
,
int
length
)
throws
IOException
{
public
int
appendData
(
DataSource
dataSource
,
int
length
)
throws
IOException
{
int
remainingWriteLength
=
length
;
ensureSpaceForWrite
();
if
(
dataQueue
.
isEmpty
()
||
lastFragmentOffset
==
fragmentLength
)
{
int
remainingFragmentCapacity
=
fragmentLength
-
lastFragmentOffset
;
lastFragmentOffset
=
0
;
length
=
length
!=
C
.
LENGTH_UNBOUNDED
?
Math
.
min
(
length
,
remainingFragmentCapacity
)
lastFragment
=
fragmentPool
.
allocateDirect
();
:
remainingFragmentCapacity
;
dataQueue
.
add
(
lastFragment
);
}
int
bytesRead
=
dataSource
.
read
(
lastFragment
,
lastFragmentOffset
,
length
);
int
thisWriteLength
=
Math
.
min
(
remainingWriteLength
,
fragmentLength
-
lastFragmentOffset
);
if
(
bytesRead
==
C
.
RESULT_END_OF_INPUT
)
{
int
bytesRead
=
dataSource
.
read
(
lastFragment
,
lastFragmentOffset
,
thisWriteLength
);
return
C
.
RESULT_END_OF_INPUT
;
if
(
bytesRead
==
-
1
)
{
return
-
1
;
}
}
lastFragmentOffset
+=
bytesRead
;
lastFragmentOffset
+=
bytesRead
;
remainingWriteLength
-=
bytesRead
;
totalBytesWritten
+=
bytesRead
;
totalBytesWritten
+=
bytesRead
;
return
bytesRead
;
return
bytesRead
;
}
}
...
@@ -294,15 +318,10 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -294,15 +318,10 @@ import java.util.concurrent.ConcurrentLinkedQueue;
* @param buffer A buffer containing the data to append.
* @param buffer A buffer containing the data to append.
* @param length The length of the data to append.
* @param length The length of the data to append.
*/
*/
// TODO: Consider reducing duplication of this method and the one above.
public
void
appendData
(
ParsableByteArray
buffer
,
int
length
)
{
public
void
appendData
(
ParsableByteArray
buffer
,
int
length
)
{
int
remainingWriteLength
=
length
;
int
remainingWriteLength
=
length
;
while
(
remainingWriteLength
>
0
)
{
while
(
remainingWriteLength
>
0
)
{
if
(
dataQueue
.
isEmpty
()
||
lastFragmentOffset
==
fragmentLength
)
{
ensureSpaceForWrite
();
lastFragmentOffset
=
0
;
lastFragment
=
fragmentPool
.
allocateDirect
();
dataQueue
.
add
(
lastFragment
);
}
int
thisWriteLength
=
Math
.
min
(
remainingWriteLength
,
fragmentLength
-
lastFragmentOffset
);
int
thisWriteLength
=
Math
.
min
(
remainingWriteLength
,
fragmentLength
-
lastFragmentOffset
);
buffer
.
readBytes
(
lastFragment
,
lastFragmentOffset
,
thisWriteLength
);
buffer
.
readBytes
(
lastFragment
,
lastFragmentOffset
,
thisWriteLength
);
lastFragmentOffset
+=
thisWriteLength
;
lastFragmentOffset
+=
thisWriteLength
;
...
@@ -326,6 +345,17 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -326,6 +345,17 @@ import java.util.concurrent.ConcurrentLinkedQueue;
}
}
/**
/**
* Ensures at least one byte can be written, allocating a new fragment if necessary.
*/
private
void
ensureSpaceForWrite
()
{
if
(
lastFragmentOffset
==
fragmentLength
)
{
lastFragmentOffset
=
0
;
lastFragment
=
fragmentPool
.
allocateDirect
();
dataQueue
.
add
(
lastFragment
);
}
}
/**
* Holds information about the samples in the rolling buffer.
* Holds information about the samples in the rolling buffer.
*/
*/
private
static
final
class
InfoQueue
{
private
static
final
class
InfoQueue
{
...
@@ -341,8 +371,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -341,8 +371,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
private
byte
[][]
encryptionKeys
;
private
byte
[][]
encryptionKeys
;
private
int
queueSize
;
private
int
queueSize
;
private
int
readIndex
;
private
int
absoluteReadIndex
;
private
int
writeIndex
;
private
int
relativeReadIndex
;
private
int
relativeWriteIndex
;
public
InfoQueue
()
{
public
InfoQueue
()
{
capacity
=
SAMPLE_CAPACITY_INCREMENT
;
capacity
=
SAMPLE_CAPACITY_INCREMENT
;
...
@@ -353,9 +384,35 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -353,9 +384,35 @@ import java.util.concurrent.ConcurrentLinkedQueue;
encryptionKeys
=
new
byte
[
capacity
][];
encryptionKeys
=
new
byte
[
capacity
][];
}
}
// Called by the consuming thread, but only when there is no loading thread.
/**
* Clears the queue.
*/
public
void
clear
()
{
absoluteReadIndex
=
0
;
relativeReadIndex
=
0
;
relativeWriteIndex
=
0
;
queueSize
=
0
;
}
/**
* Returns the current absolute write index.
*/
public
int
getWriteIndex
()
{
return
absoluteReadIndex
+
queueSize
;
}
// Called by the consuming thread.
// Called by the consuming thread.
/**
/**
* Returns the current absolute read index.
*/
public
int
getReadIndex
()
{
return
absoluteReadIndex
;
}
/**
* Fills {@code holder} with information about the current sample, but does not write its data.
* Fills {@code holder} with information about the current sample, but does not write its data.
* The first entry in {@code offsetHolder} is filled with the absolute position of the sample's
* The first entry in {@code offsetHolder} is filled with the absolute position of the sample's
* data in the rolling buffer.
* data in the rolling buffer.
...
@@ -371,11 +428,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -371,11 +428,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
if
(
queueSize
==
0
)
{
if
(
queueSize
==
0
)
{
return
false
;
return
false
;
}
}
holder
.
timeUs
=
timesUs
[
readIndex
];
holder
.
timeUs
=
timesUs
[
re
lativeRe
adIndex
];
holder
.
size
=
sizes
[
readIndex
];
holder
.
size
=
sizes
[
re
lativeRe
adIndex
];
holder
.
flags
=
flags
[
readIndex
];
holder
.
flags
=
flags
[
re
lativeRe
adIndex
];
extrasHolder
.
offset
=
offsets
[
readIndex
];
extrasHolder
.
offset
=
offsets
[
re
lativeRe
adIndex
];
extrasHolder
.
encryptionKeyId
=
encryptionKeys
[
readIndex
];
extrasHolder
.
encryptionKeyId
=
encryptionKeys
[
re
lativeRe
adIndex
];
return
true
;
return
true
;
}
}
...
@@ -387,23 +444,25 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -387,23 +444,25 @@ import java.util.concurrent.ConcurrentLinkedQueue;
*/
*/
public
synchronized
long
moveToNextSample
()
{
public
synchronized
long
moveToNextSample
()
{
queueSize
--;
queueSize
--;
int
lastReadIndex
=
readIndex
++;
int
lastReadIndex
=
relativeReadIndex
++;
if
(
readIndex
==
capacity
)
{
absoluteReadIndex
++;
if
(
relativeReadIndex
==
capacity
)
{
// Wrap around.
// Wrap around.
readIndex
=
0
;
re
lativeRe
adIndex
=
0
;
}
}
return
queueSize
>
0
?
offsets
[
readIndex
]
:
(
sizes
[
lastReadIndex
]
+
offsets
[
lastReadIndex
]);
return
queueSize
>
0
?
offsets
[
relativeReadIndex
]
:
(
sizes
[
lastReadIndex
]
+
offsets
[
lastReadIndex
]);
}
}
// Called by the loading thread.
// Called by the loading thread.
public
synchronized
void
commitSample
(
long
timeUs
,
int
sampleFlags
,
long
offset
,
int
size
,
public
synchronized
void
commitSample
(
long
timeUs
,
int
sampleFlags
,
long
offset
,
int
size
,
byte
[]
encryptionKey
)
{
byte
[]
encryptionKey
)
{
timesUs
[
w
riteIndex
]
=
timeUs
;
timesUs
[
relativeW
riteIndex
]
=
timeUs
;
offsets
[
w
riteIndex
]
=
offset
;
offsets
[
relativeW
riteIndex
]
=
offset
;
sizes
[
w
riteIndex
]
=
size
;
sizes
[
relativeW
riteIndex
]
=
size
;
flags
[
w
riteIndex
]
=
sampleFlags
;
flags
[
relativeW
riteIndex
]
=
sampleFlags
;
encryptionKeys
[
w
riteIndex
]
=
encryptionKey
;
encryptionKeys
[
relativeW
riteIndex
]
=
encryptionKey
;
// Increment the write index.
// Increment the write index.
queueSize
++;
queueSize
++;
if
(
queueSize
==
capacity
)
{
if
(
queueSize
==
capacity
)
{
...
@@ -414,13 +473,13 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -414,13 +473,13 @@ import java.util.concurrent.ConcurrentLinkedQueue;
int
[]
newFlags
=
new
int
[
newCapacity
];
int
[]
newFlags
=
new
int
[
newCapacity
];
int
[]
newSizes
=
new
int
[
newCapacity
];
int
[]
newSizes
=
new
int
[
newCapacity
];
byte
[][]
newEncryptionKeys
=
new
byte
[
newCapacity
][];
byte
[][]
newEncryptionKeys
=
new
byte
[
newCapacity
][];
int
beforeWrap
=
capacity
-
readIndex
;
int
beforeWrap
=
capacity
-
re
lativeRe
adIndex
;
System
.
arraycopy
(
offsets
,
readIndex
,
newOffsets
,
0
,
beforeWrap
);
System
.
arraycopy
(
offsets
,
re
lativeRe
adIndex
,
newOffsets
,
0
,
beforeWrap
);
System
.
arraycopy
(
timesUs
,
readIndex
,
newTimesUs
,
0
,
beforeWrap
);
System
.
arraycopy
(
timesUs
,
re
lativeRe
adIndex
,
newTimesUs
,
0
,
beforeWrap
);
System
.
arraycopy
(
flags
,
readIndex
,
newFlags
,
0
,
beforeWrap
);
System
.
arraycopy
(
flags
,
re
lativeRe
adIndex
,
newFlags
,
0
,
beforeWrap
);
System
.
arraycopy
(
sizes
,
readIndex
,
newSizes
,
0
,
beforeWrap
);
System
.
arraycopy
(
sizes
,
re
lativeRe
adIndex
,
newSizes
,
0
,
beforeWrap
);
System
.
arraycopy
(
encryptionKeys
,
readIndex
,
newEncryptionKeys
,
0
,
beforeWrap
);
System
.
arraycopy
(
encryptionKeys
,
re
lativeRe
adIndex
,
newEncryptionKeys
,
0
,
beforeWrap
);
int
afterWrap
=
readIndex
;
int
afterWrap
=
re
lativeRe
adIndex
;
System
.
arraycopy
(
offsets
,
0
,
newOffsets
,
beforeWrap
,
afterWrap
);
System
.
arraycopy
(
offsets
,
0
,
newOffsets
,
beforeWrap
,
afterWrap
);
System
.
arraycopy
(
timesUs
,
0
,
newTimesUs
,
beforeWrap
,
afterWrap
);
System
.
arraycopy
(
timesUs
,
0
,
newTimesUs
,
beforeWrap
,
afterWrap
);
System
.
arraycopy
(
flags
,
0
,
newFlags
,
beforeWrap
,
afterWrap
);
System
.
arraycopy
(
flags
,
0
,
newFlags
,
beforeWrap
,
afterWrap
);
...
@@ -431,15 +490,15 @@ import java.util.concurrent.ConcurrentLinkedQueue;
...
@@ -431,15 +490,15 @@ import java.util.concurrent.ConcurrentLinkedQueue;
flags
=
newFlags
;
flags
=
newFlags
;
sizes
=
newSizes
;
sizes
=
newSizes
;
encryptionKeys
=
newEncryptionKeys
;
encryptionKeys
=
newEncryptionKeys
;
readIndex
=
0
;
re
lativeRe
adIndex
=
0
;
w
riteIndex
=
capacity
;
relativeW
riteIndex
=
capacity
;
queueSize
=
capacity
;
queueSize
=
capacity
;
capacity
=
newCapacity
;
capacity
=
newCapacity
;
}
else
{
}
else
{
w
riteIndex
++;
relativeW
riteIndex
++;
if
(
w
riteIndex
==
capacity
)
{
if
(
relativeW
riteIndex
==
capacity
)
{
// Wrap around.
// Wrap around.
w
riteIndex
=
0
;
relativeW
riteIndex
=
0
;
}
}
}
}
}
}
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsExtractorWrapper.java
View file @
da656e6f
...
@@ -125,13 +125,11 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
...
@@ -125,13 +125,11 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
}
}
/**
/**
* Releases the extractor, recycling any pending or incomplete samples to the sample pool.
* Clears queues for all tracks, returning all allocations to the buffer pool.
* <p>
* This method should not be called whilst {@link #read(ExtractorInput)} is also being invoked.
*/
*/
public
void
release
()
{
public
void
clear
()
{
for
(
int
i
=
0
;
i
<
sampleQueues
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
sampleQueues
.
size
();
i
++)
{
sampleQueues
.
valueAt
(
i
).
release
();
sampleQueues
.
valueAt
(
i
).
clear
();
}
}
}
}
...
@@ -140,7 +138,7 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
...
@@ -140,7 +138,7 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
*
*
* @return The largest timestamp, or {@link Long#MIN_VALUE} if no samples have been parsed.
* @return The largest timestamp, or {@link Long#MIN_VALUE} if no samples have been parsed.
*/
*/
public
long
getLargest
SampleTimestamp
()
{
public
long
getLargest
ParsedTimestampUs
()
{
long
largestParsedTimestampUs
=
Long
.
MIN_VALUE
;
long
largestParsedTimestampUs
=
Long
.
MIN_VALUE
;
for
(
int
i
=
0
;
i
<
sampleQueues
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
sampleQueues
.
size
();
i
++)
{
largestParsedTimestampUs
=
Math
.
max
(
largestParsedTimestampUs
,
largestParsedTimestampUs
=
Math
.
max
(
largestParsedTimestampUs
,
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java
View file @
da656e6f
...
@@ -261,7 +261,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
...
@@ -261,7 +261,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
}
else
if
(
loadingFinished
)
{
}
else
if
(
loadingFinished
)
{
return
TrackRenderer
.
END_OF_TRACK_US
;
return
TrackRenderer
.
END_OF_TRACK_US
;
}
else
{
}
else
{
long
largestSampleTimestamp
=
extractors
.
getLast
().
getLargest
SampleTimestamp
();
long
largestSampleTimestamp
=
extractors
.
getLast
().
getLargest
ParsedTimestampUs
();
return
largestSampleTimestamp
==
Long
.
MIN_VALUE
?
downstreamPositionUs
return
largestSampleTimestamp
==
Long
.
MIN_VALUE
?
downstreamPositionUs
:
largestSampleTimestamp
;
:
largestSampleTimestamp
;
}
}
...
@@ -333,7 +333,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
...
@@ -333,7 +333,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
HlsExtractorWrapper
extractor
=
extractors
.
getFirst
();
HlsExtractorWrapper
extractor
=
extractors
.
getFirst
();
while
(
extractors
.
size
()
>
1
&&
!
haveSamplesForEnabledTracks
(
extractor
))
{
while
(
extractors
.
size
()
>
1
&&
!
haveSamplesForEnabledTracks
(
extractor
))
{
// We're finished reading from the extractor for all tracks, and so can discard it.
// We're finished reading from the extractor for all tracks, and so can discard it.
extractors
.
removeFirst
().
release
();
extractors
.
removeFirst
().
clear
();
extractor
=
extractors
.
getFirst
();
extractor
=
extractors
.
getFirst
();
}
}
return
extractor
;
return
extractor
;
...
@@ -382,7 +382,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
...
@@ -382,7 +382,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
private
void
clearState
()
{
private
void
clearState
()
{
for
(
int
i
=
0
;
i
<
extractors
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
extractors
.
size
();
i
++)
{
extractors
.
get
(
i
).
release
();
extractors
.
get
(
i
).
clear
();
}
}
extractors
.
clear
();
extractors
.
clear
();
clearCurrentLoadable
();
clearCurrentLoadable
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment