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
f7470c51
authored
Jan 20, 2020
by
ibaker
Committed by
Ian Baker
Jan 24, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Remove CEA package from null-checking blacklist
PiperOrigin-RevId: 290610312
parent
de3f04b7
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
49 additions
and
29 deletions
library/core/src/main/java/com/google/android/exoplayer2/text/cea/Cea608Decoder.java
library/core/src/main/java/com/google/android/exoplayer2/text/cea/Cea708Decoder.java
library/core/src/main/java/com/google/android/exoplayer2/text/cea/CeaDecoder.java
library/core/src/main/java/com/google/android/exoplayer2/text/cea/Cea608Decoder.java
View file @
f7470c51
...
...
@@ -24,17 +24,21 @@ import android.text.Spanned;
import
android.text.style.ForegroundColorSpan
;
import
android.text.style.StyleSpan
;
import
android.text.style.UnderlineSpan
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.text.Cue
;
import
com.google.android.exoplayer2.text.Subtitle
;
import
com.google.android.exoplayer2.text.SubtitleDecoder
;
import
com.google.android.exoplayer2.text.SubtitleInputBuffer
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
java.nio.ByteBuffer
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
org.checkerframework.checker.nullness.compatqual.NullableType
;
/**
* A {@link SubtitleDecoder} for CEA-608 (also known as "line 21 captions" and "EIA-608").
...
...
@@ -236,8 +240,8 @@ public final class Cea608Decoder extends CeaDecoder {
private
final
ArrayList
<
CueBuilder
>
cueBuilders
;
private
CueBuilder
currentCueBuilder
;
private
List
<
Cue
>
cues
;
private
List
<
Cue
>
lastCues
;
@Nullable
private
List
<
Cue
>
cues
;
@Nullable
private
List
<
Cue
>
lastCues
;
private
int
captionMode
;
private
int
captionRowCount
;
...
...
@@ -321,13 +325,14 @@ public final class Cea608Decoder extends CeaDecoder {
@Override
protected
Subtitle
createSubtitle
()
{
lastCues
=
cues
;
return
new
CeaSubtitle
(
cues
);
return
new
CeaSubtitle
(
Assertions
.
checkNotNull
(
cues
)
);
}
@SuppressWarnings
(
"ByteBufferBackingArray"
)
@Override
protected
void
decode
(
SubtitleInputBuffer
inputBuffer
)
{
ccData
.
reset
(
inputBuffer
.
data
.
array
(),
inputBuffer
.
data
.
limit
());
ByteBuffer
subtitleData
=
Assertions
.
checkNotNull
(
inputBuffer
.
data
);
ccData
.
reset
(
subtitleData
.
array
(),
subtitleData
.
limit
());
boolean
captionDataProcessed
=
false
;
while
(
ccData
.
bytesLeft
()
>=
packetLength
)
{
byte
ccHeader
=
packetLength
==
2
?
CC_IMPLICIT_DATA_HEADER
...
...
@@ -572,9 +577,9 @@ public final class Cea608Decoder extends CeaDecoder {
// preference, then middle alignment, then end alignment.
@Cue
.
AnchorType
int
positionAnchor
=
Cue
.
ANCHOR_TYPE_END
;
int
cueBuilderCount
=
cueBuilders
.
size
();
List
<
Cue
>
cueBuilderCues
=
new
ArrayList
<>(
cueBuilderCount
);
List
<
@NullableType
Cue
>
cueBuilderCues
=
new
ArrayList
<>(
cueBuilderCount
);
for
(
int
i
=
0
;
i
<
cueBuilderCount
;
i
++)
{
Cue
cue
=
cueBuilders
.
get
(
i
).
build
(
/* forcedPositionAnchor= */
Cue
.
TYPE_UNSET
);
@Nullable
Cue
cue
=
cueBuilders
.
get
(
i
).
build
(
/* forcedPositionAnchor= */
Cue
.
TYPE_UNSET
);
cueBuilderCues
.
add
(
cue
);
if
(
cue
!=
null
)
{
positionAnchor
=
Math
.
min
(
positionAnchor
,
cue
.
positionAnchor
);
...
...
@@ -584,10 +589,11 @@ public final class Cea608Decoder extends CeaDecoder {
// Skip null cues and rebuild any that don't have the preferred alignment.
List
<
Cue
>
displayCues
=
new
ArrayList
<>(
cueBuilderCount
);
for
(
int
i
=
0
;
i
<
cueBuilderCount
;
i
++)
{
Cue
cue
=
cueBuilderCues
.
get
(
i
);
@Nullable
Cue
cue
=
cueBuilderCues
.
get
(
i
);
if
(
cue
!=
null
)
{
if
(
cue
.
positionAnchor
!=
positionAnchor
)
{
cue
=
cueBuilders
.
get
(
i
).
build
(
positionAnchor
);
// The last time we built this cue it was non-null, it will be non-null this time too.
cue
=
Assertions
.
checkNotNull
(
cueBuilders
.
get
(
i
).
build
(
positionAnchor
));
}
displayCues
.
add
(
cue
);
}
...
...
@@ -745,7 +751,7 @@ public final class Cea608Decoder extends CeaDecoder {
return
(
cc1
&
0xF7
)
==
0x14
;
}
private
static
class
CueBuilder
{
private
static
final
class
CueBuilder
{
// 608 captions define a 15 row by 32 column screen grid. These constants convert from 608
// positions to normalized screen position.
...
...
@@ -767,7 +773,7 @@ public final class Cea608Decoder extends CeaDecoder {
rolledUpCaptions
=
new
ArrayList
<>();
captionStringBuilder
=
new
StringBuilder
();
reset
(
captionMode
);
setCaptionRowCount
(
captionRowCount
)
;
this
.
captionRowCount
=
captionRowCount
;
}
public
void
reset
(
int
captionMode
)
{
...
...
@@ -829,6 +835,7 @@ public final class Cea608Decoder extends CeaDecoder {
}
}
@Nullable
public
Cue
build
(
@Cue
.
AnchorType
int
forcedPositionAnchor
)
{
SpannableStringBuilder
cueString
=
new
SpannableStringBuilder
();
// Add any rolled up captions, separated by new lines.
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/cea/Cea708Decoder.java
View file @
f7470c51
...
...
@@ -37,9 +37,11 @@ import com.google.android.exoplayer2.util.Assertions;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.ParsableBitArray
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
java.nio.ByteBuffer
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
org.checkerframework.checker.nullness.qual.RequiresNonNull
;
/**
* A {@link SubtitleDecoder} for CEA-708 (also known as "EIA-708").
...
...
@@ -147,10 +149,10 @@ public final class Cea708Decoder extends CeaDecoder {
private
final
CueInfoBuilder
[]
cueInfoBuilders
;
private
CueInfoBuilder
currentCueInfoBuilder
;
private
List
<
Cue
>
cues
;
private
List
<
Cue
>
lastCues
;
@Nullable
private
List
<
Cue
>
cues
;
@Nullable
private
List
<
Cue
>
lastCues
;
private
DtvCcPacket
currentDtvCcPacket
;
@Nullable
private
DtvCcPacket
currentDtvCcPacket
;
private
int
currentWindow
;
// TODO: Retrieve isWideAspectRatio from initializationData and use it.
...
...
@@ -165,7 +167,6 @@ public final class Cea708Decoder extends CeaDecoder {
}
currentCueInfoBuilder
=
cueInfoBuilders
[
0
];
resetCueBuilders
();
}
@Override
...
...
@@ -192,15 +193,16 @@ public final class Cea708Decoder extends CeaDecoder {
@Override
protected
Subtitle
createSubtitle
()
{
lastCues
=
cues
;
return
new
CeaSubtitle
(
cues
);
return
new
CeaSubtitle
(
Assertions
.
checkNotNull
(
cues
)
);
}
@Override
protected
void
decode
(
SubtitleInputBuffer
inputBuffer
)
{
// Subtitle input buffers are non-direct and the position is zero, so calling array() is safe.
ByteBuffer
subtitleData
=
Assertions
.
checkNotNull
(
inputBuffer
.
data
);
@SuppressWarnings
(
"ByteBufferBackingArray"
)
byte
[]
inputBufferData
=
inputBuffer
.
d
ata
.
array
();
ccData
.
reset
(
inputBufferData
,
inputBuffer
.
d
ata
.
limit
());
byte
[]
inputBufferData
=
subtitleD
ata
.
array
();
ccData
.
reset
(
inputBufferData
,
subtitleD
ata
.
limit
());
while
(
ccData
.
bytesLeft
()
>=
3
)
{
int
ccTypeAndValid
=
(
ccData
.
readUnsignedByte
()
&
0x07
);
...
...
@@ -259,6 +261,7 @@ public final class Cea708Decoder extends CeaDecoder {
currentDtvCcPacket
=
null
;
}
@RequiresNonNull
(
"currentDtvCcPacket"
)
private
void
processCurrentPacket
()
{
if
(
currentDtvCcPacket
.
currentIndex
!=
(
currentDtvCcPacket
.
packetSize
*
2
-
1
))
{
Log
.
w
(
TAG
,
"DtvCcPacket ended prematurely; size is "
+
(
currentDtvCcPacket
.
packetSize
*
2
-
1
)
...
...
@@ -761,7 +764,10 @@ public final class Cea708Decoder extends CeaDecoder {
List
<
Cea708CueInfo
>
displayCueInfos
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
NUM_WINDOWS
;
i
++)
{
if
(!
cueInfoBuilders
[
i
].
isEmpty
()
&&
cueInfoBuilders
[
i
].
isVisible
())
{
displayCueInfos
.
add
(
cueInfoBuilders
[
i
].
build
());
@Nullable
Cea708CueInfo
cueInfo
=
cueInfoBuilders
[
i
].
build
();
if
(
cueInfo
!=
null
)
{
displayCueInfos
.
add
(
cueInfo
);
}
}
}
Collections
.
sort
(
...
...
@@ -1157,6 +1163,7 @@ public final class Cea708Decoder extends CeaDecoder {
return
new
SpannableString
(
spannableStringBuilder
);
}
@Nullable
public
Cea708CueInfo
build
()
{
if
(
isEmpty
())
{
// The cue is empty.
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/cea/CeaDecoder.java
View file @
f7470c51
...
...
@@ -16,6 +16,7 @@
package
com
.
google
.
android
.
exoplayer2
.
text
.
cea
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.text.Subtitle
;
...
...
@@ -24,6 +25,7 @@ import com.google.android.exoplayer2.text.SubtitleDecoderException;
import
com.google.android.exoplayer2.text.SubtitleInputBuffer
;
import
com.google.android.exoplayer2.text.SubtitleOutputBuffer
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Util
;
import
java.util.ArrayDeque
;
import
java.util.PriorityQueue
;
...
...
@@ -39,7 +41,7 @@ import java.util.PriorityQueue;
private
final
ArrayDeque
<
SubtitleOutputBuffer
>
availableOutputBuffers
;
private
final
PriorityQueue
<
CeaInputBuffer
>
queuedInputBuffers
;
private
CeaInputBuffer
dequeuedInputBuffer
;
@Nullable
private
CeaInputBuffer
dequeuedInputBuffer
;
private
long
playbackPositionUs
;
private
long
queuedInputBufferCount
;
...
...
@@ -64,6 +66,7 @@ import java.util.PriorityQueue;
}
@Override
@Nullable
public
SubtitleInputBuffer
dequeueInputBuffer
()
throws
SubtitleDecoderException
{
Assertions
.
checkState
(
dequeuedInputBuffer
==
null
);
if
(
availableInputBuffers
.
isEmpty
())
{
...
...
@@ -76,18 +79,20 @@ import java.util.PriorityQueue;
@Override
public
void
queueInputBuffer
(
SubtitleInputBuffer
inputBuffer
)
throws
SubtitleDecoderException
{
Assertions
.
checkArgument
(
inputBuffer
==
dequeuedInputBuffer
);
if
(
inputBuffer
.
isDecodeOnly
())
{
CeaInputBuffer
ceaInputBuffer
=
(
CeaInputBuffer
)
inputBuffer
;
if
(
ceaInputBuffer
.
isDecodeOnly
())
{
// We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow
// for decoding to begin mid-stream.
releaseInputBuffer
(
dequeued
InputBuffer
);
releaseInputBuffer
(
cea
InputBuffer
);
}
else
{
dequeued
InputBuffer
.
queuedInputBufferCount
=
queuedInputBufferCount
++;
queuedInputBuffers
.
add
(
dequeued
InputBuffer
);
cea
InputBuffer
.
queuedInputBufferCount
=
queuedInputBufferCount
++;
queuedInputBuffers
.
add
(
cea
InputBuffer
);
}
dequeuedInputBuffer
=
null
;
}
@Override
@Nullable
public
SubtitleOutputBuffer
dequeueOutputBuffer
()
throws
SubtitleDecoderException
{
if
(
availableOutputBuffers
.
isEmpty
())
{
return
null
;
...
...
@@ -96,13 +101,14 @@ import java.util.PriorityQueue;
// to the current playback position; processing input buffers for future content should
// be deferred until they would be applicable
while
(!
queuedInputBuffers
.
isEmpty
()
&&
queuedInputBuffers
.
peek
(
).
timeUs
<=
playbackPositionUs
)
{
CeaInputBuffer
inputBuffer
=
queuedInputBuffers
.
poll
(
);
&&
Util
.
castNonNull
(
queuedInputBuffers
.
peek
()
).
timeUs
<=
playbackPositionUs
)
{
CeaInputBuffer
inputBuffer
=
Util
.
castNonNull
(
queuedInputBuffers
.
poll
()
);
// If the input buffer indicates we've reached the end of the stream, we can
// return immediately with an output buffer propagating that
if
(
inputBuffer
.
isEndOfStream
())
{
SubtitleOutputBuffer
outputBuffer
=
availableOutputBuffers
.
pollFirst
();
// availableOutputBuffers.isEmpty() is checked at the top of the method, so this is safe.
SubtitleOutputBuffer
outputBuffer
=
Util
.
castNonNull
(
availableOutputBuffers
.
pollFirst
());
outputBuffer
.
addFlag
(
C
.
BUFFER_FLAG_END_OF_STREAM
);
releaseInputBuffer
(
inputBuffer
);
return
outputBuffer
;
...
...
@@ -116,7 +122,8 @@ import java.util.PriorityQueue;
// isn't accidentally prepended to the next subtitle
Subtitle
subtitle
=
createSubtitle
();
if
(!
inputBuffer
.
isDecodeOnly
())
{
SubtitleOutputBuffer
outputBuffer
=
availableOutputBuffers
.
pollFirst
();
// availableOutputBuffers.isEmpty() is checked at the top of the method, so this is safe.
SubtitleOutputBuffer
outputBuffer
=
Util
.
castNonNull
(
availableOutputBuffers
.
pollFirst
());
outputBuffer
.
setContent
(
inputBuffer
.
timeUs
,
subtitle
,
Format
.
OFFSET_SAMPLE_RELATIVE
);
releaseInputBuffer
(
inputBuffer
);
return
outputBuffer
;
...
...
@@ -125,7 +132,6 @@ import java.util.PriorityQueue;
releaseInputBuffer
(
inputBuffer
);
}
return
null
;
}
...
...
@@ -144,7 +150,7 @@ import java.util.PriorityQueue;
queuedInputBufferCount
=
0
;
playbackPositionUs
=
0
;
while
(!
queuedInputBuffers
.
isEmpty
())
{
releaseInputBuffer
(
queuedInputBuffers
.
poll
(
));
releaseInputBuffer
(
Util
.
castNonNull
(
queuedInputBuffers
.
poll
()
));
}
if
(
dequeuedInputBuffer
!=
null
)
{
releaseInputBuffer
(
dequeuedInputBuffer
);
...
...
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