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
e670b1d0
authored
Oct 14, 2019
by
ibaker
Committed by
Oliver Woodman
Oct 14, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Remove HlsMediaChunk from null-checking blacklist
PiperOrigin-RevId: 274566133
parent
d36abf96
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
48 additions
and
14 deletions
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java
View file @
e670b1d0
...
@@ -23,6 +23,7 @@ import com.google.android.exoplayer2.drm.DrmInitData;
...
@@ -23,6 +23,7 @@ import com.google.android.exoplayer2.drm.DrmInitData;
import
com.google.android.exoplayer2.extractor.DefaultExtractorInput
;
import
com.google.android.exoplayer2.extractor.DefaultExtractorInput
;
import
com.google.android.exoplayer2.extractor.Extractor
;
import
com.google.android.exoplayer2.extractor.Extractor
;
import
com.google.android.exoplayer2.extractor.ExtractorInput
;
import
com.google.android.exoplayer2.extractor.ExtractorInput
;
import
com.google.android.exoplayer2.extractor.PositionHolder
;
import
com.google.android.exoplayer2.metadata.Metadata
;
import
com.google.android.exoplayer2.metadata.Metadata
;
import
com.google.android.exoplayer2.metadata.id3.Id3Decoder
;
import
com.google.android.exoplayer2.metadata.id3.Id3Decoder
;
import
com.google.android.exoplayer2.metadata.id3.PrivFrame
;
import
com.google.android.exoplayer2.metadata.id3.PrivFrame
;
...
@@ -30,6 +31,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk;
...
@@ -30,6 +31,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist
;
import
com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
com.google.android.exoplayer2.util.TimestampAdjuster
;
import
com.google.android.exoplayer2.util.TimestampAdjuster
;
import
com.google.android.exoplayer2.util.UriUtil
;
import
com.google.android.exoplayer2.util.UriUtil
;
...
@@ -39,6 +41,9 @@ import java.io.IOException;
...
@@ -39,6 +41,9 @@ import java.io.IOException;
import
java.math.BigInteger
;
import
java.math.BigInteger
;
import
java.util.List
;
import
java.util.List
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
org.checkerframework.checker.nullness.qual.EnsuresNonNull
;
import
org.checkerframework.checker.nullness.qual.MonotonicNonNull
;
import
org.checkerframework.checker.nullness.qual.RequiresNonNull
;
/**
/**
* An HLS {@link MediaChunk}.
* An HLS {@link MediaChunk}.
...
@@ -93,7 +98,9 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -93,7 +98,9 @@ import java.util.concurrent.atomic.AtomicInteger;
/* key= */
null
);
/* key= */
null
);
boolean
mediaSegmentEncrypted
=
mediaSegmentKey
!=
null
;
boolean
mediaSegmentEncrypted
=
mediaSegmentKey
!=
null
;
byte
[]
mediaSegmentIv
=
byte
[]
mediaSegmentIv
=
mediaSegmentEncrypted
?
getEncryptionIvArray
(
mediaSegment
.
encryptionIV
)
:
null
;
mediaSegmentEncrypted
?
getEncryptionIvArray
(
Assertions
.
checkNotNull
(
mediaSegment
.
encryptionIV
))
:
null
;
DataSource
mediaDataSource
=
buildDataSource
(
dataSource
,
mediaSegmentKey
,
mediaSegmentIv
);
DataSource
mediaDataSource
=
buildDataSource
(
dataSource
,
mediaSegmentKey
,
mediaSegmentIv
);
// Init segment.
// Init segment.
...
@@ -104,7 +111,9 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -104,7 +111,9 @@ import java.util.concurrent.atomic.AtomicInteger;
if
(
initSegment
!=
null
)
{
if
(
initSegment
!=
null
)
{
initSegmentEncrypted
=
initSegmentKey
!=
null
;
initSegmentEncrypted
=
initSegmentKey
!=
null
;
byte
[]
initSegmentIv
=
byte
[]
initSegmentIv
=
initSegmentEncrypted
?
getEncryptionIvArray
(
initSegment
.
encryptionIV
)
:
null
;
initSegmentEncrypted
?
getEncryptionIvArray
(
Assertions
.
checkNotNull
(
initSegment
.
encryptionIV
))
:
null
;
Uri
initSegmentUri
=
UriUtil
.
resolveToUri
(
mediaPlaylist
.
baseUri
,
initSegment
.
url
);
Uri
initSegmentUri
=
UriUtil
.
resolveToUri
(
mediaPlaylist
.
baseUri
,
initSegment
.
url
);
initDataSpec
=
initDataSpec
=
new
DataSpec
(
new
DataSpec
(
...
@@ -170,6 +179,7 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -170,6 +179,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public
static
final
String
PRIV_TIMESTAMP_FRAME_OWNER
=
public
static
final
String
PRIV_TIMESTAMP_FRAME_OWNER
=
"com.apple.streaming.transportStreamTimestamp"
;
"com.apple.streaming.transportStreamTimestamp"
;
private
static
final
PositionHolder
DUMMY_POSITION_HOLDER
=
new
PositionHolder
();
private
static
final
AtomicInteger
uidSource
=
new
AtomicInteger
();
private
static
final
AtomicInteger
uidSource
=
new
AtomicInteger
();
...
@@ -186,8 +196,12 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -186,8 +196,12 @@ import java.util.concurrent.atomic.AtomicInteger;
/** The url of the playlist from which this chunk was obtained. */
/** The url of the playlist from which this chunk was obtained. */
public
final
Uri
playlistUrl
;
public
final
Uri
playlistUrl
;
@Nullable
private
final
DataSource
initDataSource
;
// These should be final, but can't be due to
@Nullable
private
final
DataSpec
initDataSpec
;
// https://github.com/typetools/checker-framework/issues/2215
@MonotonicNonNull
private
DataSource
initDataSource
;
@MonotonicNonNull
private
DataSpec
initDataSpec
;
@MonotonicNonNull
private
Extractor
previousExtractor
;
private
final
boolean
isMasterTimestampSource
;
private
final
boolean
isMasterTimestampSource
;
private
final
boolean
hasGapTag
;
private
final
boolean
hasGapTag
;
private
final
TimestampAdjuster
timestampAdjuster
;
private
final
TimestampAdjuster
timestampAdjuster
;
...
@@ -195,15 +209,14 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -195,15 +209,14 @@ import java.util.concurrent.atomic.AtomicInteger;
private
final
HlsExtractorFactory
extractorFactory
;
private
final
HlsExtractorFactory
extractorFactory
;
@Nullable
private
final
List
<
Format
>
muxedCaptionFormats
;
@Nullable
private
final
List
<
Format
>
muxedCaptionFormats
;
@Nullable
private
final
DrmInitData
drmInitData
;
@Nullable
private
final
DrmInitData
drmInitData
;
@Nullable
private
final
Extractor
previousExtractor
;
private
final
Id3Decoder
id3Decoder
;
private
final
Id3Decoder
id3Decoder
;
private
final
ParsableByteArray
scratchId3Data
;
private
final
ParsableByteArray
scratchId3Data
;
private
final
boolean
mediaSegmentEncrypted
;
private
final
boolean
mediaSegmentEncrypted
;
private
final
boolean
initSegmentEncrypted
;
private
final
boolean
initSegmentEncrypted
;
private
Extractor
extractor
;
@MonotonicNonNull
private
Extractor
extractor
;
private
boolean
isExtractorReusable
;
private
boolean
isExtractorReusable
;
private
HlsSampleStreamWrapper
output
;
@MonotonicNonNull
private
HlsSampleStreamWrapper
output
;
// nextLoadPosition refers to the init segment if initDataLoadRequired is true.
// nextLoadPosition refers to the init segment if initDataLoadRequired is true.
// Otherwise, nextLoadPosition refers to the media segment.
// Otherwise, nextLoadPosition refers to the media segment.
private
int
nextLoadPosition
;
private
int
nextLoadPosition
;
...
@@ -217,13 +230,13 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -217,13 +230,13 @@ import java.util.concurrent.atomic.AtomicInteger;
DataSpec
dataSpec
,
DataSpec
dataSpec
,
Format
format
,
Format
format
,
boolean
mediaSegmentEncrypted
,
boolean
mediaSegmentEncrypted
,
DataSource
initDataSource
,
@Nullable
DataSource
initDataSource
,
@Nullable
DataSpec
initDataSpec
,
@Nullable
DataSpec
initDataSpec
,
boolean
initSegmentEncrypted
,
boolean
initSegmentEncrypted
,
Uri
playlistUrl
,
Uri
playlistUrl
,
@Nullable
List
<
Format
>
muxedCaptionFormats
,
@Nullable
List
<
Format
>
muxedCaptionFormats
,
int
trackSelectionReason
,
int
trackSelectionReason
,
Object
trackSelectionData
,
@Nullable
Object
trackSelectionData
,
long
startTimeUs
,
long
startTimeUs
,
long
endTimeUs
,
long
endTimeUs
,
long
chunkMediaSequence
,
long
chunkMediaSequence
,
...
@@ -247,8 +260,12 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -247,8 +260,12 @@ import java.util.concurrent.atomic.AtomicInteger;
chunkMediaSequence
);
chunkMediaSequence
);
this
.
mediaSegmentEncrypted
=
mediaSegmentEncrypted
;
this
.
mediaSegmentEncrypted
=
mediaSegmentEncrypted
;
this
.
discontinuitySequenceNumber
=
discontinuitySequenceNumber
;
this
.
discontinuitySequenceNumber
=
discontinuitySequenceNumber
;
this
.
initDataSource
=
initDataSource
;
// Workaround for https://github.com/typetools/checker-framework/issues/2215
if
(
initDataSpec
!=
null
)
{
this
.
initDataSpec
=
initDataSpec
;
this
.
initDataSpec
=
initDataSpec
;
this
.
initDataSource
=
Assertions
.
checkNotNull
(
initDataSource
);
initDataLoadRequired
=
true
;
}
this
.
initSegmentEncrypted
=
initSegmentEncrypted
;
this
.
initSegmentEncrypted
=
initSegmentEncrypted
;
this
.
playlistUrl
=
playlistUrl
;
this
.
playlistUrl
=
playlistUrl
;
this
.
isMasterTimestampSource
=
isMasterTimestampSource
;
this
.
isMasterTimestampSource
=
isMasterTimestampSource
;
...
@@ -257,11 +274,13 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -257,11 +274,13 @@ import java.util.concurrent.atomic.AtomicInteger;
this
.
extractorFactory
=
extractorFactory
;
this
.
extractorFactory
=
extractorFactory
;
this
.
muxedCaptionFormats
=
muxedCaptionFormats
;
this
.
muxedCaptionFormats
=
muxedCaptionFormats
;
this
.
drmInitData
=
drmInitData
;
this
.
drmInitData
=
drmInitData
;
// Workaround for https://github.com/typetools/checker-framework/issues/2215
if
(
previousExtractor
!=
null
)
{
this
.
previousExtractor
=
previousExtractor
;
this
.
previousExtractor
=
previousExtractor
;
}
this
.
id3Decoder
=
id3Decoder
;
this
.
id3Decoder
=
id3Decoder
;
this
.
scratchId3Data
=
scratchId3Data
;
this
.
scratchId3Data
=
scratchId3Data
;
this
.
shouldSpliceIn
=
shouldSpliceIn
;
this
.
shouldSpliceIn
=
shouldSpliceIn
;
initDataLoadRequired
=
initDataSpec
!=
null
;
uid
=
uidSource
.
getAndIncrement
();
uid
=
uidSource
.
getAndIncrement
();
}
}
...
@@ -289,6 +308,8 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -289,6 +308,8 @@ import java.util.concurrent.atomic.AtomicInteger;
@Override
@Override
public
void
load
()
throws
IOException
,
InterruptedException
{
public
void
load
()
throws
IOException
,
InterruptedException
{
// output == null means init() hasn't been called.
Assertions
.
checkNotNull
(
output
);
if
(
extractor
==
null
&&
previousExtractor
!=
null
)
{
if
(
extractor
==
null
&&
previousExtractor
!=
null
)
{
extractor
=
previousExtractor
;
extractor
=
previousExtractor
;
isExtractorReusable
=
true
;
isExtractorReusable
=
true
;
...
@@ -306,15 +327,20 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -306,15 +327,20 @@ import java.util.concurrent.atomic.AtomicInteger;
// Internal methods.
// Internal methods.
@RequiresNonNull
(
"output"
)
private
void
maybeLoadInitData
()
throws
IOException
,
InterruptedException
{
private
void
maybeLoadInitData
()
throws
IOException
,
InterruptedException
{
if
(!
initDataLoadRequired
)
{
if
(!
initDataLoadRequired
)
{
return
;
return
;
}
}
// initDataLoadRequired => initDataSource != null && initDataSpec != null
Assertions
.
checkNotNull
(
initDataSource
);
Assertions
.
checkNotNull
(
initDataSpec
);
feedDataToExtractor
(
initDataSource
,
initDataSpec
,
initSegmentEncrypted
);
feedDataToExtractor
(
initDataSource
,
initDataSpec
,
initSegmentEncrypted
);
nextLoadPosition
=
0
;
nextLoadPosition
=
0
;
initDataLoadRequired
=
false
;
initDataLoadRequired
=
false
;
}
}
@RequiresNonNull
(
"output"
)
private
void
loadMedia
()
throws
IOException
,
InterruptedException
{
private
void
loadMedia
()
throws
IOException
,
InterruptedException
{
if
(!
isMasterTimestampSource
)
{
if
(!
isMasterTimestampSource
)
{
timestampAdjuster
.
waitUntilInitialized
();
timestampAdjuster
.
waitUntilInitialized
();
...
@@ -330,6 +356,7 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -330,6 +356,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* concludes (because of a thrown exception or because the operation finishes), the number of fed
* concludes (because of a thrown exception or because the operation finishes), the number of fed
* bytes is written to {@code nextLoadPosition}.
* bytes is written to {@code nextLoadPosition}.
*/
*/
@RequiresNonNull
(
"output"
)
private
void
feedDataToExtractor
(
private
void
feedDataToExtractor
(
DataSource
dataSource
,
DataSpec
dataSpec
,
boolean
dataIsEncrypted
)
DataSource
dataSource
,
DataSpec
dataSpec
,
boolean
dataIsEncrypted
)
throws
IOException
,
InterruptedException
{
throws
IOException
,
InterruptedException
{
...
@@ -354,7 +381,7 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -354,7 +381,7 @@ import java.util.concurrent.atomic.AtomicInteger;
try
{
try
{
int
result
=
Extractor
.
RESULT_CONTINUE
;
int
result
=
Extractor
.
RESULT_CONTINUE
;
while
(
result
==
Extractor
.
RESULT_CONTINUE
&&
!
loadCanceled
)
{
while
(
result
==
Extractor
.
RESULT_CONTINUE
&&
!
loadCanceled
)
{
result
=
extractor
.
read
(
input
,
/* seekPosition= */
null
);
result
=
extractor
.
read
(
input
,
DUMMY_POSITION_HOLDER
);
}
}
}
finally
{
}
finally
{
nextLoadPosition
=
(
int
)
(
input
.
getPosition
()
-
dataSpec
.
absoluteStreamPosition
);
nextLoadPosition
=
(
int
)
(
input
.
getPosition
()
-
dataSpec
.
absoluteStreamPosition
);
...
@@ -364,6 +391,8 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -364,6 +391,8 @@ import java.util.concurrent.atomic.AtomicInteger;
}
}
}
}
@RequiresNonNull
(
"output"
)
@EnsuresNonNull
(
"extractor"
)
private
DefaultExtractorInput
prepareExtraction
(
DataSource
dataSource
,
DataSpec
dataSpec
)
private
DefaultExtractorInput
prepareExtraction
(
DataSource
dataSource
,
DataSpec
dataSpec
)
throws
IOException
,
InterruptedException
{
throws
IOException
,
InterruptedException
{
long
bytesToRead
=
dataSource
.
open
(
dataSpec
);
long
bytesToRead
=
dataSource
.
open
(
dataSpec
);
...
@@ -483,10 +512,15 @@ import java.util.concurrent.atomic.AtomicInteger;
...
@@ -483,10 +512,15 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
/**
* If the segment is fully encrypted, returns an {@link Aes128DataSource} that wraps the original
* If the segment is fully encrypted, returns an {@link Aes128DataSource} that wraps the original
* in order to decrypt the loaded data. Else returns the original.
* in order to decrypt the loaded data. Else returns the original.
*
* <p>{@code fullSegmentEncryptionKey} & {@code encryptionIv} can either both be null, or neither.
*/
*/
private
static
DataSource
buildDataSource
(
DataSource
dataSource
,
byte
[]
fullSegmentEncryptionKey
,
private
static
DataSource
buildDataSource
(
byte
[]
encryptionIv
)
{
DataSource
dataSource
,
@Nullable
byte
[]
fullSegmentEncryptionKey
,
@Nullable
byte
[]
encryptionIv
)
{
if
(
fullSegmentEncryptionKey
!=
null
)
{
if
(
fullSegmentEncryptionKey
!=
null
)
{
Assertions
.
checkNotNull
(
encryptionIv
);
return
new
Aes128DataSource
(
dataSource
,
fullSegmentEncryptionKey
,
encryptionIv
);
return
new
Aes128DataSource
(
dataSource
,
fullSegmentEncryptionKey
,
encryptionIv
);
}
}
return
dataSource
;
return
dataSource
;
...
...
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