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
334da7de
authored
Apr 01, 2019
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #5390 from zsmatyas:dev-v2
PiperOrigin-RevId: 241308265
parents
592b5eaf
fd4998bc
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
46 additions
and
13 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/Cea608Decoder.java
View file @
334da7de
...
@@ -25,11 +25,11 @@ import android.text.style.ForegroundColorSpan;
...
@@ -25,11 +25,11 @@ import android.text.style.ForegroundColorSpan;
import
android.text.style.StyleSpan
;
import
android.text.style.StyleSpan
;
import
android.text.style.UnderlineSpan
;
import
android.text.style.UnderlineSpan
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.text.Cue
;
import
com.google.android.exoplayer2.text.Cue
;
import
com.google.android.exoplayer2.text.Subtitle
;
import
com.google.android.exoplayer2.text.Subtitle
;
import
com.google.android.exoplayer2.text.SubtitleDecoder
;
import
com.google.android.exoplayer2.text.SubtitleDecoder
;
import
com.google.android.exoplayer2.text.SubtitleInputBuffer
;
import
com.google.android.exoplayer2.text.SubtitleInputBuffer
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
com.google.android.exoplayer2.util.ParsableByteArray
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
...
@@ -41,12 +41,16 @@ import java.util.List;
...
@@ -41,12 +41,16 @@ import java.util.List;
*/
*/
public
final
class
Cea608Decoder
extends
CeaDecoder
{
public
final
class
Cea608Decoder
extends
CeaDecoder
{
private
static
final
String
TAG
=
"Cea608Decoder"
;
private
static
final
int
CC_VALID_FLAG
=
0x04
;
private
static
final
int
CC_VALID_FLAG
=
0x04
;
private
static
final
int
CC_TYPE_FLAG
=
0x02
;
private
static
final
int
CC_TYPE_FLAG
=
0x02
;
private
static
final
int
CC_FIELD_FLAG
=
0x01
;
private
static
final
int
CC_FIELD_FLAG
=
0x01
;
private
static
final
int
NTSC_CC_FIELD_1
=
0x00
;
private
static
final
int
NTSC_CC_FIELD_1
=
0x00
;
private
static
final
int
NTSC_CC_FIELD_2
=
0x01
;
private
static
final
int
NTSC_CC_FIELD_2
=
0x01
;
private
static
final
int
NTSC_CC_CHANNEL_1
=
0x00
;
private
static
final
int
NTSC_CC_CHANNEL_2
=
0x01
;
private
static
final
int
CC_MODE_UNKNOWN
=
0
;
private
static
final
int
CC_MODE_UNKNOWN
=
0
;
private
static
final
int
CC_MODE_ROLL_UP
=
1
;
private
static
final
int
CC_MODE_ROLL_UP
=
1
;
...
@@ -217,6 +221,7 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -217,6 +221,7 @@ public final class Cea608Decoder extends CeaDecoder {
private
final
ParsableByteArray
ccData
;
private
final
ParsableByteArray
ccData
;
private
final
int
packetLength
;
private
final
int
packetLength
;
private
final
int
selectedField
;
private
final
int
selectedField
;
private
final
int
selectedChannel
;
private
final
ArrayList
<
CueBuilder
>
cueBuilders
;
private
final
ArrayList
<
CueBuilder
>
cueBuilders
;
private
CueBuilder
currentCueBuilder
;
private
CueBuilder
currentCueBuilder
;
...
@@ -230,22 +235,35 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -230,22 +235,35 @@ public final class Cea608Decoder extends CeaDecoder {
private
boolean
repeatableControlSet
;
private
boolean
repeatableControlSet
;
private
byte
repeatableControlCc1
;
private
byte
repeatableControlCc1
;
private
byte
repeatableControlCc2
;
private
byte
repeatableControlCc2
;
private
int
currentChannel
;
public
Cea608Decoder
(
String
mimeType
,
int
accessibilityChannel
)
{
public
Cea608Decoder
(
String
mimeType
,
int
accessibilityChannel
)
{
ccData
=
new
ParsableByteArray
();
ccData
=
new
ParsableByteArray
();
cueBuilders
=
new
ArrayList
<>();
cueBuilders
=
new
ArrayList
<>();
currentCueBuilder
=
new
CueBuilder
(
CC_MODE_UNKNOWN
,
DEFAULT_CAPTIONS_ROW_COUNT
);
currentCueBuilder
=
new
CueBuilder
(
CC_MODE_UNKNOWN
,
DEFAULT_CAPTIONS_ROW_COUNT
);
currentChannel
=
NTSC_CC_CHANNEL_1
;
packetLength
=
MimeTypes
.
APPLICATION_MP4CEA608
.
equals
(
mimeType
)
?
2
:
3
;
packetLength
=
MimeTypes
.
APPLICATION_MP4CEA608
.
equals
(
mimeType
)
?
2
:
3
;
switch
(
accessibilityChannel
)
{
switch
(
accessibilityChannel
)
{
case
1
:
selectedChannel
=
NTSC_CC_CHANNEL_1
;
selectedField
=
NTSC_CC_FIELD_1
;
break
;
case
2
:
selectedChannel
=
NTSC_CC_CHANNEL_2
;
selectedField
=
NTSC_CC_FIELD_1
;
break
;
case
3
:
case
3
:
selectedChannel
=
NTSC_CC_CHANNEL_1
;
selectedField
=
NTSC_CC_FIELD_2
;
break
;
case
4
:
case
4
:
selectedField
=
2
;
selectedChannel
=
NTSC_CC_CHANNEL_2
;
selectedField
=
NTSC_CC_FIELD_2
;
break
;
break
;
case
1
:
case
2
:
case
Format
.
NO_VALUE
:
default
:
default
:
selectedField
=
1
;
Log
.
w
(
TAG
,
"Invalid channel. Defaulting to CC1."
);
selectedChannel
=
NTSC_CC_CHANNEL_1
;
selectedField
=
NTSC_CC_FIELD_1
;
}
}
setCaptionMode
(
CC_MODE_UNKNOWN
);
setCaptionMode
(
CC_MODE_UNKNOWN
);
...
@@ -269,6 +287,7 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -269,6 +287,7 @@ public final class Cea608Decoder extends CeaDecoder {
repeatableControlSet
=
false
;
repeatableControlSet
=
false
;
repeatableControlCc1
=
0
;
repeatableControlCc1
=
0
;
repeatableControlCc2
=
0
;
repeatableControlCc2
=
0
;
currentChannel
=
NTSC_CC_CHANNEL_1
;
}
}
@Override
@Override
...
@@ -307,8 +326,7 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -307,8 +326,7 @@ public final class Cea608Decoder extends CeaDecoder {
continue
;
continue
;
}
}
if
((
selectedField
==
1
&&
(
ccHeader
&
CC_FIELD_FLAG
)
!=
NTSC_CC_FIELD_1
)
if
((
ccHeader
&
CC_FIELD_FLAG
)
!=
selectedField
)
{
||
(
selectedField
==
2
&&
(
ccHeader
&
CC_FIELD_FLAG
)
!=
NTSC_CC_FIELD_2
))
{
// Do not process packets not within the selected field.
// Do not process packets not within the selected field.
continue
;
continue
;
}
}
...
@@ -349,8 +367,9 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -349,8 +367,9 @@ public final class Cea608Decoder extends CeaDecoder {
// ccData1 - 0|0|0|1|C|0|0|1
// ccData1 - 0|0|0|1|C|0|0|1
// ccData2 - 0|0|1|1|X|X|X|X
// ccData2 - 0|0|1|1|X|X|X|X
if
(((
ccData1
&
0xF7
)
==
0x11
)
&&
((
ccData2
&
0xF0
)
==
0x30
))
{
if
(((
ccData1
&
0xF7
)
==
0x11
)
&&
((
ccData2
&
0xF0
)
==
0x30
))
{
// TODO: Make use of the channel toggle
if
(
getChannel
(
ccData1
)
==
selectedChannel
)
{
currentCueBuilder
.
append
(
getSpecialChar
(
ccData2
));
currentCueBuilder
.
append
(
getSpecialChar
(
ccData2
));
}
continue
;
continue
;
}
}
...
@@ -358,7 +377,7 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -358,7 +377,7 @@ public final class Cea608Decoder extends CeaDecoder {
// ccData1 - 0|0|0|1|C|0|1|S
// ccData1 - 0|0|0|1|C|0|1|S
// ccData2 - 0|0|1|X|X|X|X|X
// ccData2 - 0|0|1|X|X|X|X|X
if
(((
ccData1
&
0xF6
)
==
0x12
)
&&
(
ccData2
&
0xE0
)
==
0x20
)
{
if
(((
ccData1
&
0xF6
)
==
0x12
)
&&
(
ccData2
&
0xE0
)
==
0x20
)
{
// TODO: Make use of the channel toggle
if
(
getChannel
(
ccData1
)
==
selectedChannel
)
{
// Remove standard equivalent of the special extended char before appending new one
// Remove standard equivalent of the special extended char before appending new one
currentCueBuilder
.
backspace
();
currentCueBuilder
.
backspace
();
if
((
ccData1
&
0x01
)
==
0x00
)
{
if
((
ccData1
&
0x01
)
==
0x00
)
{
...
@@ -368,6 +387,7 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -368,6 +387,7 @@ public final class Cea608Decoder extends CeaDecoder {
// Extended Portuguese and German/Danish character set (S = 1).
// Extended Portuguese and German/Danish character set (S = 1).
currentCueBuilder
.
append
(
getExtendedPtDeChar
(
ccData2
));
currentCueBuilder
.
append
(
getExtendedPtDeChar
(
ccData2
));
}
}
}
continue
;
continue
;
}
}
...
@@ -378,6 +398,10 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -378,6 +398,10 @@ public final class Cea608Decoder extends CeaDecoder {
continue
;
continue
;
}
}
if
(
currentChannel
!=
selectedChannel
)
{
continue
;
}
// Basic North American character set.
// Basic North American character set.
currentCueBuilder
.
append
(
getChar
(
ccData1
));
currentCueBuilder
.
append
(
getChar
(
ccData1
));
if
((
ccData2
&
0xE0
)
!=
0x00
)
{
if
((
ccData2
&
0xE0
)
!=
0x00
)
{
...
@@ -393,6 +417,7 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -393,6 +417,7 @@ public final class Cea608Decoder extends CeaDecoder {
}
}
private
void
handleCtrl
(
byte
cc1
,
byte
cc2
,
boolean
repeatedControlPossible
)
{
private
void
handleCtrl
(
byte
cc1
,
byte
cc2
,
boolean
repeatedControlPossible
)
{
currentChannel
=
getChannel
(
cc1
);
// Most control commands are sent twice in succession to ensure they are received properly. We
// Most control commands are sent twice in succession to ensure they are received properly. We
// don't want to process duplicate commands, so if we see the same repeatable command twice in a
// don't want to process duplicate commands, so if we see the same repeatable command twice in a
// row then we ignore the second one.
// row then we ignore the second one.
...
@@ -410,6 +435,10 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -410,6 +435,10 @@ public final class Cea608Decoder extends CeaDecoder {
}
}
}
}
if
(
currentChannel
!=
selectedChannel
)
{
return
;
}
if
(
isMidrowCtrlCode
(
cc1
,
cc2
))
{
if
(
isMidrowCtrlCode
(
cc1
,
cc2
))
{
handleMidrowCtrl
(
cc2
);
handleMidrowCtrl
(
cc2
);
}
else
if
(
isPreambleAddressCode
(
cc1
,
cc2
))
{
}
else
if
(
isPreambleAddressCode
(
cc1
,
cc2
))
{
...
@@ -437,7 +466,6 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -437,7 +466,6 @@ public final class Cea608Decoder extends CeaDecoder {
// cc1 - 0|0|0|1|C|E|ROW
// cc1 - 0|0|0|1|C|E|ROW
// C is the channel toggle, E is the extended flag, and ROW is the encoded row
// C is the channel toggle, E is the extended flag, and ROW is the encoded row
int
row
=
ROW_INDICES
[
cc1
&
0x07
];
int
row
=
ROW_INDICES
[
cc1
&
0x07
];
// TODO: Make use of the channel toggle
// TODO: support the extended address and style
// TODO: support the extended address and style
// cc2 - 0|1|N|ATTRBTE|U
// cc2 - 0|1|N|ATTRBTE|U
...
@@ -621,6 +649,11 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -621,6 +649,11 @@ public final class Cea608Decoder extends CeaDecoder {
return
(
char
)
SPECIAL_PT_DE_CHARACTER_SET
[
index
];
return
(
char
)
SPECIAL_PT_DE_CHARACTER_SET
[
index
];
}
}
private
static
int
getChannel
(
byte
cc1
)
{
// cc1 - X|X|X|X|C|X|X|X
return
(
cc1
>>
3
)
&
0x1
;
}
private
static
boolean
isMidrowCtrlCode
(
byte
cc1
,
byte
cc2
)
{
private
static
boolean
isMidrowCtrlCode
(
byte
cc1
,
byte
cc2
)
{
// cc1 - 0|0|0|1|C|0|0|1
// cc1 - 0|0|0|1|C|0|0|1
// cc2 - 0|0|1|0|X|X|X|X
// cc2 - 0|0|1|0|X|X|X|X
...
@@ -640,9 +673,9 @@ public final class Cea608Decoder extends CeaDecoder {
...
@@ -640,9 +673,9 @@ public final class Cea608Decoder extends CeaDecoder {
}
}
private
static
boolean
isMiscCode
(
byte
cc1
,
byte
cc2
)
{
private
static
boolean
isMiscCode
(
byte
cc1
,
byte
cc2
)
{
// cc1 - 0|0|0|1|C|1|0|
0
// cc1 - 0|0|0|1|C|1|0|
F
// cc2 - 0|0|1|0|X|X|X|X
// cc2 - 0|0|1|0|X|X|X|X
return
((
cc1
&
0xF
7
)
==
0x14
)
&&
((
cc2
&
0xF0
)
==
0x20
);
return
((
cc1
&
0xF
6
)
==
0x14
)
&&
((
cc2
&
0xF0
)
==
0x20
);
}
}
private
static
boolean
isRepeatable
(
byte
cc1
)
{
private
static
boolean
isRepeatable
(
byte
cc1
)
{
...
...
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