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
0c5d4702
authored
Nov 03, 2019
by
Arnold Szabo
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Correct SSA overlapping subtitle decoding, add tests
parent
925a7fd0
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
109 additions
and
31 deletions
library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java
library/core/src/test/assets/ssa/overlap
library/core/src/test/java/com/google/android/exoplayer2/text/ssa/SsaDecoderTest.java
library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java
View file @
0c5d4702
...
@@ -226,44 +226,68 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
...
@@ -226,44 +226,68 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
cue
=
new
Cue
(
text
);
cue
=
new
Cue
(
text
);
}
}
int
startTimeIndex
=
insertToCueTimes
(
cueTimesUs
,
startTimeUs
);
int
startTimeIndex
=
0
;
boolean
startTimeFound
=
false
;
// Search the insertion index for startTimeUs in cueTimesUs
for
(
int
i
=
cueTimesUs
.
size
()
-
1
;
i
>=
0
;
i
--)
{
if
(
cueTimesUs
.
get
(
i
)
==
startTimeUs
)
{
startTimeIndex
=
i
;
startTimeFound
=
true
;
break
;
}
List
<
Cue
>
startCueList
=
new
ArrayList
<>();
if
(
cueTimesUs
.
get
(
i
)
<
startTimeUs
)
{
if
(
startTimeIndex
!=
0
)
{
startTimeIndex
=
i
+
1
;
startCueList
.
addAll
(
cues
.
get
(
startTimeIndex
-
1
));
break
;
}
}
}
cues
.
add
(
startTimeIndex
,
startCueList
);
if
(
endTimeUs
!=
C
.
TIME_UNSET
)
{
if
(
startTimeIndex
==
0
)
{
int
endTimeIndex
=
insertToCueTimes
(
cueTimesUs
,
endTimeUs
);
// Handle first cue
List
<
Cue
>
endList
=
new
ArrayList
<>(
cues
.
get
(
endTimeIndex
-
1
));
cueTimesUs
.
add
(
startTimeIndex
,
startTimeUs
);
cues
.
add
(
endTimeIndex
,
endList
);
cues
.
add
(
startTimeIndex
,
new
ArrayList
<>());
}
else
{
int
i
=
startTimeIndex
;
if
(!
startTimeFound
)
{
do
{
// Add the startTimeUs only if it wasn't found in cueTimesUs
cues
.
get
(
i
).
add
(
cue
);
cueTimesUs
.
add
(
startTimeIndex
,
startTimeUs
);
i
++;
// Copy over cues from left
}
while
(
i
!=
endTimeIndex
);
List
<
Cue
>
startCueList
=
new
ArrayList
<>(
cues
.
get
(
startTimeIndex
-
1
));
cues
.
add
(
startTimeIndex
,
startCueList
);
}
}
}
}
/**
int
endTimeIndex
=
0
;
* Insert the given cue time into the given array keeping the array sorted.
if
(
endTimeUs
!=
C
.
TIME_UNSET
)
{
*
boolean
endTimeFound
=
false
;
* @param cueTimes The array with sorted cue times
* @param timeUs The cue time to be inserted
// Search the insertion index for endTimeUs in cueTimesUs
* @return The index where the cue time was inserted
for
(
int
i
=
cueTimesUs
.
size
()
-
1
;
i
>=
0
;
i
--)
{
*/
if
(
cueTimesUs
.
get
(
i
)
==
endTimeUs
)
{
private
static
int
insertToCueTimes
(
List
<
Long
>
cueTimes
,
long
timeUs
)
{
endTimeIndex
=
i
;
for
(
int
i
=
cueTimes
.
size
()
-
1
;
i
>=
0
;
i
--)
{
endTimeFound
=
true
;
if
(
cueTimes
.
get
(
i
)
<=
timeUs
)
{
break
;
cueTimes
.
add
(
i
+
1
,
timeUs
);
}
return
i
+
1
;
if
(
cueTimesUs
.
get
(
i
)
<
endTimeUs
)
{
endTimeIndex
=
i
+
1
;
break
;
}
}
if
(!
endTimeFound
)
{
// Add the endTimeUs only if it wasn't found in cueTimesUs
cueTimesUs
.
add
(
endTimeIndex
,
endTimeUs
);
// Copy over cues from left
cues
.
add
(
endTimeIndex
,
new
ArrayList
<>(
cues
.
get
(
endTimeIndex
-
1
)));
}
}
}
}
cueTimes
.
add
(
0
,
timeUs
);
// Iterate on cues from startTimeIndex until endTimeIndex, add the current cue
return
0
;
int
i
=
startTimeIndex
;
do
{
cues
.
get
(
i
).
add
(
cue
);
i
++;
}
while
(
i
<
endTimeIndex
);
}
}
/**
/**
...
...
library/core/src/test/assets/ssa/overlap
0 → 100644
View file @
0c5d4702
[Script Info]
Title: SomeTitle
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Open Sans Semibold,36,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,1.7,0,2,0,0,28,1
[Events]
Format: Layer, Start, End, Style, Name, Text
Dialogue: 0,0:00:01.00,0:00:04.23,Default,Olly,Subtitle A
Dialogue: 0,0:00:02.00,0:00:05.23,Default,Olly,Subtitle B
Dialogue: 0,0:00:06.00,0:00:08.44,Default,Olly,Subtitle C
Dialogue: 0,0:00:08.44,0:00:09.44,Default,Olly,Subtitle D
Dialogue: 0,0:00:08.44,0:00:09.44,Default,Olly,Subtitle E
Dialogue: 0,0:00:10.72,0:00:15.65,Default,Olly,Subtitle F
Dialogue: 0,0:00:13.22,0:00:14.22,Default,Olly,Subtitle G
library/core/src/test/java/com/google/android/exoplayer2/text/ssa/SsaDecoderTest.java
View file @
0c5d4702
...
@@ -32,6 +32,7 @@ public final class SsaDecoderTest {
...
@@ -32,6 +32,7 @@ public final class SsaDecoderTest {
private
static
final
String
EMPTY
=
"ssa/empty"
;
private
static
final
String
EMPTY
=
"ssa/empty"
;
private
static
final
String
TYPICAL
=
"ssa/typical"
;
private
static
final
String
TYPICAL
=
"ssa/typical"
;
private
static
final
String
OVERLAP
=
"ssa/overlap"
;
private
static
final
String
TYPICAL_HEADER_ONLY
=
"ssa/typical_header"
;
private
static
final
String
TYPICAL_HEADER_ONLY
=
"ssa/typical_header"
;
private
static
final
String
TYPICAL_DIALOGUE_ONLY
=
"ssa/typical_dialogue"
;
private
static
final
String
TYPICAL_DIALOGUE_ONLY
=
"ssa/typical_dialogue"
;
private
static
final
String
TYPICAL_FORMAT_ONLY
=
"ssa/typical_format"
;
private
static
final
String
TYPICAL_FORMAT_ONLY
=
"ssa/typical_format"
;
...
@@ -61,6 +62,37 @@ public final class SsaDecoderTest {
...
@@ -61,6 +62,37 @@ public final class SsaDecoderTest {
}
}
@Test
@Test
public
void
testDecodeOverlap
()
throws
IOException
{
SsaDecoder
decoder
=
new
SsaDecoder
();
byte
[]
bytes
=
TestUtil
.
getByteArray
(
ApplicationProvider
.
getApplicationContext
(),
OVERLAP
);
Subtitle
subtitle
=
decoder
.
decode
(
bytes
,
bytes
.
length
,
false
);
assertThat
(
subtitle
.
getEventTime
(
0
)).
isEqualTo
(
1000000
);
assertThat
(
subtitle
.
getEventTime
(
1
)).
isEqualTo
(
2000000
);
assertThat
(
subtitle
.
getEventTime
(
2
)).
isEqualTo
(
4230000
);
assertThat
(
subtitle
.
getEventTime
(
3
)).
isEqualTo
(
5230000
);
assertThat
(
subtitle
.
getEventTime
(
4
)).
isEqualTo
(
6000000
);
assertThat
(
subtitle
.
getEventTime
(
5
)).
isEqualTo
(
8440000
);
assertThat
(
subtitle
.
getEventTime
(
6
)).
isEqualTo
(
9440000
);
assertThat
(
subtitle
.
getEventTime
(
7
)).
isEqualTo
(
10720000
);
assertThat
(
subtitle
.
getEventTime
(
8
)).
isEqualTo
(
13220000
);
assertThat
(
subtitle
.
getEventTime
(
9
)).
isEqualTo
(
14220000
);
assertThat
(
subtitle
.
getEventTime
(
10
)).
isEqualTo
(
15650000
);
assertThat
(
subtitle
.
getCues
(
1000010
).
size
()).
isEqualTo
(
1
);
assertThat
(
subtitle
.
getCues
(
2000010
).
size
()).
isEqualTo
(
2
);
assertThat
(
subtitle
.
getCues
(
4230010
).
size
()).
isEqualTo
(
1
);
assertThat
(
subtitle
.
getCues
(
5230010
).
size
()).
isEqualTo
(
0
);
assertThat
(
subtitle
.
getCues
(
6000010
).
size
()).
isEqualTo
(
1
);
assertThat
(
subtitle
.
getCues
(
8440010
).
size
()).
isEqualTo
(
2
);
assertThat
(
subtitle
.
getCues
(
9440010
).
size
()).
isEqualTo
(
0
);
assertThat
(
subtitle
.
getCues
(
10720010
).
size
()).
isEqualTo
(
1
);
assertThat
(
subtitle
.
getCues
(
13220010
).
size
()).
isEqualTo
(
2
);
assertThat
(
subtitle
.
getCues
(
14220010
).
size
()).
isEqualTo
(
1
);
assertThat
(
subtitle
.
getCues
(
15650010
).
size
()).
isEqualTo
(
0
);
}
@Test
public
void
testDecodeTypicalWithInitializationData
()
throws
IOException
{
public
void
testDecodeTypicalWithInitializationData
()
throws
IOException
{
byte
[]
headerBytes
=
byte
[]
headerBytes
=
TestUtil
.
getByteArray
(
ApplicationProvider
.
getApplicationContext
(),
TYPICAL_HEADER_ONLY
);
TestUtil
.
getByteArray
(
ApplicationProvider
.
getApplicationContext
(),
TYPICAL_HEADER_ONLY
);
...
@@ -107,10 +139,16 @@ public final class SsaDecoderTest {
...
@@ -107,10 +139,16 @@ public final class SsaDecoderTest {
assertThat
(
subtitle
.
getEventTime
(
1
)).
isEqualTo
(
2340000
);
assertThat
(
subtitle
.
getEventTime
(
1
)).
isEqualTo
(
2340000
);
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
1
)).
get
(
0
).
text
.
toString
())
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
1
)).
get
(
0
).
text
.
toString
())
.
isEqualTo
(
"This is the first subtitle."
);
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
1
)).
get
(
1
).
text
.
toString
())
.
isEqualTo
(
"This is the second subtitle \nwith a newline \nand another."
);
.
isEqualTo
(
"This is the second subtitle \nwith a newline \nand another."
);
assertThat
(
subtitle
.
getEventTime
(
2
)).
isEqualTo
(
4560000
);
assertThat
(
subtitle
.
getEventTime
(
2
)).
isEqualTo
(
4560000
);
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
2
)).
get
(
0
).
text
.
toString
())
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
1
)).
get
(
0
).
text
.
toString
())
.
isEqualTo
(
"This is the first subtitle."
);
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
1
)).
get
(
1
).
text
.
toString
())
.
isEqualTo
(
"This is the second subtitle \nwith a newline \nand another."
);
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
2
)).
get
(
2
).
text
.
toString
())
.
isEqualTo
(
"This is the third subtitle, with a comma."
);
.
isEqualTo
(
"This is the third subtitle, with a comma."
);
}
}
...
...
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