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
08e1d356
authored
Jan 02, 2017
by
Julian Cable
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
add changed files for SSA from branch
parent
246a0dc8
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
65 additions
and
2 deletions
library/src/main/java/com/google/android/exoplayer2/Format.java
library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
library/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java
library/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java
library/src/main/java/com/google/android/exoplayer2/Format.java
View file @
08e1d356
...
@@ -188,6 +188,8 @@ public final class Format implements Parcelable {
...
@@ -188,6 +188,8 @@ public final class Format implements Parcelable {
private
int
hashCode
;
private
int
hashCode
;
private
MediaFormat
frameworkMediaFormat
;
private
MediaFormat
frameworkMediaFormat
;
private
byte
[]
header
=
new
byte
[
0
];
// Video.
// Video.
public
static
Format
createVideoContainerFormat
(
String
id
,
String
containerMimeType
,
public
static
Format
createVideoContainerFormat
(
String
id
,
String
containerMimeType
,
...
...
library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
View file @
08e1d356
...
@@ -15,6 +15,8 @@
...
@@ -15,6 +15,8 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
mkv
;
package
com
.
google
.
android
.
exoplayer2
.
extractor
.
mkv
;
import
android.content.Intent
;
import
android.util.Log
;
import
android.util.SparseArray
;
import
android.util.SparseArray
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.Format
;
...
@@ -30,6 +32,8 @@ import com.google.android.exoplayer2.extractor.MpegAudioHeader;
...
@@ -30,6 +32,8 @@ import com.google.android.exoplayer2.extractor.MpegAudioHeader;
import
com.google.android.exoplayer2.extractor.PositionHolder
;
import
com.google.android.exoplayer2.extractor.PositionHolder
;
import
com.google.android.exoplayer2.extractor.SeekMap
;
import
com.google.android.exoplayer2.extractor.SeekMap
;
import
com.google.android.exoplayer2.extractor.TrackOutput
;
import
com.google.android.exoplayer2.extractor.TrackOutput
;
import
com.google.android.exoplayer2.extractor.mp4.Track
;
import
com.google.android.exoplayer2.text.ssa.SSADecoder
;
import
com.google.android.exoplayer2.util.LongArray
;
import
com.google.android.exoplayer2.util.LongArray
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.NalUnitUtil
;
import
com.google.android.exoplayer2.util.NalUnitUtil
;
...
@@ -38,8 +42,13 @@ import com.google.android.exoplayer2.util.Util;
...
@@ -38,8 +42,13 @@ import com.google.android.exoplayer2.util.Util;
import
com.google.android.exoplayer2.video.AvcConfig
;
import
com.google.android.exoplayer2.video.AvcConfig
;
import
com.google.android.exoplayer2.video.HevcConfig
;
import
com.google.android.exoplayer2.video.HevcConfig
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InterruptedIOException
;
import
java.io.UnsupportedEncodingException
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteOrder
;
import
java.nio.ByteOrder
;
import
java.nio.charset.StandardCharsets
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
...
@@ -47,6 +56,12 @@ import java.util.List;
...
@@ -47,6 +56,12 @@ import java.util.List;
import
java.util.Locale
;
import
java.util.Locale
;
import
java.util.UUID
;
import
java.util.UUID
;
import
static
android
.
R
.
attr
.
format
;
import
static
android
.
R
.
attr
.
longClickable
;
import
static
android
.
R
.
attr
.
mimeType
;
import
static
android
.
R
.
attr
.
track
;
import
static
android
.
R
.
id
.
input
;
/**
/**
* Extracts data from a Matroska or WebM file.
* Extracts data from a Matroska or WebM file.
*/
*/
...
@@ -97,6 +112,7 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -97,6 +112,7 @@ public final class MatroskaExtractor implements Extractor {
private
static
final
String
CODEC_ID_ACM
=
"A_MS/ACM"
;
private
static
final
String
CODEC_ID_ACM
=
"A_MS/ACM"
;
private
static
final
String
CODEC_ID_PCM_INT_LIT
=
"A_PCM/INT/LIT"
;
private
static
final
String
CODEC_ID_PCM_INT_LIT
=
"A_PCM/INT/LIT"
;
private
static
final
String
CODEC_ID_SUBRIP
=
"S_TEXT/UTF8"
;
private
static
final
String
CODEC_ID_SUBRIP
=
"S_TEXT/UTF8"
;
private
static
final
String
CODEC_ID_ASS
=
"S_TEXT/ASS"
;
private
static
final
String
CODEC_ID_VOBSUB
=
"S_VOBSUB"
;
private
static
final
String
CODEC_ID_VOBSUB
=
"S_VOBSUB"
;
private
static
final
String
CODEC_ID_PGS
=
"S_HDMV/PGS"
;
private
static
final
String
CODEC_ID_PGS
=
"S_HDMV/PGS"
;
...
@@ -861,9 +877,9 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -861,9 +877,9 @@ public final class MatroskaExtractor implements Extractor {
if
(
id
==
ID_SIMPLE_BLOCK
)
{
if
(
id
==
ID_SIMPLE_BLOCK
)
{
// For SimpleBlock, we have metadata for each sample here.
// For SimpleBlock, we have metadata for each sample here.
while
(
blockLacingSampleIndex
<
blockLacingSampleCount
)
{
while
(
blockLacingSampleIndex
<
blockLacingSampleCount
)
{
writeSampleData
(
input
,
track
,
blockLacingSampleSizes
[
blockLacingSampleIndex
]);
long
sampleTimeUs
=
this
.
blockTimeUs
long
sampleTimeUs
=
this
.
blockTimeUs
+
(
blockLacingSampleIndex
*
track
.
defaultSampleDurationNs
)
/
1000
;
+
(
blockLacingSampleIndex
*
track
.
defaultSampleDurationNs
)
/
1000
;
writeSampleData
(
input
,
track
,
blockLacingSampleSizes
[
blockLacingSampleIndex
]);
commitSampleToOutput
(
track
,
sampleTimeUs
);
commitSampleToOutput
(
track
,
sampleTimeUs
);
blockLacingSampleIndex
++;
blockLacingSampleIndex
++;
}
}
...
@@ -884,6 +900,9 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -884,6 +900,9 @@ public final class MatroskaExtractor implements Extractor {
if
(
CODEC_ID_SUBRIP
.
equals
(
track
.
codecId
))
{
if
(
CODEC_ID_SUBRIP
.
equals
(
track
.
codecId
))
{
writeSubripSample
(
track
);
writeSubripSample
(
track
);
}
}
if
(
CODEC_ID_ASS
.
equals
(
track
.
codecId
))
{
writeSSASample
(
track
);
}
track
.
output
.
sampleMetadata
(
timeUs
,
blockFlags
,
sampleBytesWritten
,
0
,
track
.
encryptionKeyId
);
track
.
output
.
sampleMetadata
(
timeUs
,
blockFlags
,
sampleBytesWritten
,
0
,
track
.
encryptionKeyId
);
sampleRead
=
true
;
sampleRead
=
true
;
resetSample
();
resetSample
();
...
@@ -935,6 +954,12 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -935,6 +954,12 @@ public final class MatroskaExtractor implements Extractor {
// the correct end timecode, which we might not have yet.
// the correct end timecode, which we might not have yet.
return
;
return
;
}
}
if
(
CODEC_ID_ASS
.
equals
(
track
.
codecId
))
{
// Defer writing the data to the track output. We need to modify the sample data by setting
// the correct end timecode, which we might not have yet.
cacheSSASampleData
(
input
,
track
,
size
);
return
;
}
TrackOutput
output
=
track
.
output
;
TrackOutput
output
=
track
.
output
;
if
(!
sampleEncodingHandled
)
{
if
(!
sampleEncodingHandled
)
{
...
@@ -1076,6 +1101,26 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -1076,6 +1101,26 @@ public final class MatroskaExtractor implements Extractor {
}
}
}
}
private
void
cacheSSASampleData
(
ExtractorInput
input
,
Track
track
,
int
size
)
throws
IOException
,
InterruptedException
{
ParsableByteArray
ssaSample
=
new
ParsableByteArray
(
size
);
input
.
readFully
(
ssaSample
.
data
,
0
,
size
);
track
.
ssaSample
=
ssaSample
.
readString
(
size
);
}
private
void
writeSSASample
(
Track
track
)
{
StringBuffer
s
=
new
StringBuffer
();
if
(
track
.
ssaHeader
!=
null
)
{
// header contains the original format but the Matroska encoder changes this.
SSADecoder
.
writeMangledHeader
(
s
,
track
.
ssaHeader
);
}
SSADecoder
.
buildDialogue
(
s
,
track
.
ssaSample
,
blockDurationUs
);
ParsableByteArray
out
=
new
ParsableByteArray
(
s
.
toString
().
getBytes
());
track
.
output
.
sampleData
(
out
,
out
.
limit
());
sampleBytesWritten
+=
out
.
limit
();
}
private
void
writeSubripSample
(
Track
track
)
{
private
void
writeSubripSample
(
Track
track
)
{
setSubripSampleEndTimecode
(
subripSample
.
data
,
blockDurationUs
);
setSubripSampleEndTimecode
(
subripSample
.
data
,
blockDurationUs
);
// Note: If we ever want to support DRM protected subtitles then we'll need to output the
// Note: If we ever want to support DRM protected subtitles then we'll need to output the
...
@@ -1103,6 +1148,7 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -1103,6 +1148,7 @@ public final class MatroskaExtractor implements Extractor {
SUBRIP_TIMECODE_LENGTH
);
SUBRIP_TIMECODE_LENGTH
);
}
}
/**
/**
* Writes {@code length} bytes of sample data into {@code target} at {@code offset}, consisting of
* Writes {@code length} bytes of sample data into {@code target} at {@code offset}, consisting of
* pending {@link #sampleStrippedBytes} and any remaining data read from {@code input}.
* pending {@link #sampleStrippedBytes} and any remaining data read from {@code input}.
...
@@ -1231,6 +1277,7 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -1231,6 +1277,7 @@ public final class MatroskaExtractor implements Extractor {
||
CODEC_ID_ACM
.
equals
(
codecId
)
||
CODEC_ID_ACM
.
equals
(
codecId
)
||
CODEC_ID_PCM_INT_LIT
.
equals
(
codecId
)
||
CODEC_ID_PCM_INT_LIT
.
equals
(
codecId
)
||
CODEC_ID_SUBRIP
.
equals
(
codecId
)
||
CODEC_ID_SUBRIP
.
equals
(
codecId
)
||
CODEC_ID_ASS
.
equals
(
codecId
)
||
CODEC_ID_VOBSUB
.
equals
(
codecId
)
||
CODEC_ID_VOBSUB
.
equals
(
codecId
)
||
CODEC_ID_PGS
.
equals
(
codecId
);
||
CODEC_ID_PGS
.
equals
(
codecId
);
}
}
...
@@ -1335,6 +1382,8 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -1335,6 +1382,8 @@ public final class MatroskaExtractor implements Extractor {
public
boolean
flagForced
;
public
boolean
flagForced
;
public
boolean
flagDefault
=
true
;
public
boolean
flagDefault
=
true
;
private
String
language
=
"eng"
;
private
String
language
=
"eng"
;
public
byte
[]
ssaHeader
=
null
;
public
String
ssaSample
=
null
;
// Set when the output is initialized. nalUnitLengthFieldLength is only set for H264/H265.
// Set when the output is initialized. nalUnitLengthFieldLength is only set for H264/H265.
public
TrackOutput
output
;
public
TrackOutput
output
;
...
@@ -1453,6 +1502,10 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -1453,6 +1502,10 @@ public final class MatroskaExtractor implements Extractor {
case
CODEC_ID_SUBRIP:
case
CODEC_ID_SUBRIP:
mimeType
=
MimeTypes
.
APPLICATION_SUBRIP
;
mimeType
=
MimeTypes
.
APPLICATION_SUBRIP
;
break
;
break
;
case
CODEC_ID_ASS:
mimeType
=
MimeTypes
.
TEXT_SSA
;
ssaHeader
=
codecPrivate
;
break
;
case
CODEC_ID_VOBSUB:
case
CODEC_ID_VOBSUB:
mimeType
=
MimeTypes
.
APPLICATION_VOBSUB
;
mimeType
=
MimeTypes
.
APPLICATION_VOBSUB
;
initializationData
=
Collections
.
singletonList
(
codecPrivate
);
initializationData
=
Collections
.
singletonList
(
codecPrivate
);
...
@@ -1493,6 +1546,10 @@ public final class MatroskaExtractor implements Extractor {
...
@@ -1493,6 +1546,10 @@ public final class MatroskaExtractor implements Extractor {
||
MimeTypes
.
APPLICATION_PGS
.
equals
(
mimeType
))
{
||
MimeTypes
.
APPLICATION_PGS
.
equals
(
mimeType
))
{
format
=
Format
.
createImageSampleFormat
(
Integer
.
toString
(
trackId
),
mimeType
,
null
,
format
=
Format
.
createImageSampleFormat
(
Integer
.
toString
(
trackId
),
mimeType
,
null
,
Format
.
NO_VALUE
,
initializationData
,
language
,
drmInitData
);
Format
.
NO_VALUE
,
initializationData
,
language
,
drmInitData
);
}
else
if
(
MimeTypes
.
TEXT_SSA
.
equals
(
mimeType
))
{
format
=
Format
.
createTextSampleFormat
(
Integer
.
toString
(
trackId
),
mimeType
,
null
,
Format
.
NO_VALUE
,
selectionFlags
,
language
,
drmInitData
);
output
.
track
(
number
).
sampleData
(
new
ParsableByteArray
(
codecPrivate
),
codecPrivate
.
length
);
}
else
{
}
else
{
throw
new
ParserException
(
"Unexpected MIME type."
);
throw
new
ParserException
(
"Unexpected MIME type."
);
}
}
...
...
library/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java
View file @
08e1d356
...
@@ -56,6 +56,7 @@ public interface SubtitleDecoderFactory {
...
@@ -56,6 +56,7 @@ public interface SubtitleDecoderFactory {
* <li>WebVTT (MP4) ({@link Mp4WebvttDecoder})</li>
* <li>WebVTT (MP4) ({@link Mp4WebvttDecoder})</li>
* <li>TTML ({@link TtmlDecoder})</li>
* <li>TTML ({@link TtmlDecoder})</li>
* <li>SubRip ({@link SubripDecoder})</li>
* <li>SubRip ({@link SubripDecoder})</li>
* <li>AAS/SSA ({@link SSADecoder})</li>
* <li>TX3G ({@link Tx3gDecoder})</li>
* <li>TX3G ({@link Tx3gDecoder})</li>
* <li>Cea608 ({@link Cea608Decoder})</li>
* <li>Cea608 ({@link Cea608Decoder})</li>
* </ul>
* </ul>
...
@@ -99,6 +100,8 @@ public interface SubtitleDecoderFactory {
...
@@ -99,6 +100,8 @@ public interface SubtitleDecoderFactory {
return
Class
.
forName
(
"com.google.android.exoplayer2.text.webvtt.Mp4WebvttDecoder"
);
return
Class
.
forName
(
"com.google.android.exoplayer2.text.webvtt.Mp4WebvttDecoder"
);
case
MimeTypes
.
APPLICATION_SUBRIP
:
case
MimeTypes
.
APPLICATION_SUBRIP
:
return
Class
.
forName
(
"com.google.android.exoplayer2.text.subrip.SubripDecoder"
);
return
Class
.
forName
(
"com.google.android.exoplayer2.text.subrip.SubripDecoder"
);
case
MimeTypes
.
TEXT_SSA
:
return
Class
.
forName
(
"com.google.android.exoplayer2.text.ssa.SSADecoder"
);
case
MimeTypes
.
APPLICATION_TX3G
:
case
MimeTypes
.
APPLICATION_TX3G
:
return
Class
.
forName
(
"com.google.android.exoplayer2.text.tx3g.Tx3gDecoder"
);
return
Class
.
forName
(
"com.google.android.exoplayer2.text.tx3g.Tx3gDecoder"
);
case
MimeTypes
.
APPLICATION_CEA608
:
case
MimeTypes
.
APPLICATION_CEA608
:
...
...
library/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java
View file @
08e1d356
...
@@ -62,6 +62,7 @@ public final class MimeTypes {
...
@@ -62,6 +62,7 @@ public final class MimeTypes {
public
static
final
String
AUDIO_FLAC
=
BASE_TYPE_AUDIO
+
"/x-flac"
;
public
static
final
String
AUDIO_FLAC
=
BASE_TYPE_AUDIO
+
"/x-flac"
;
public
static
final
String
TEXT_VTT
=
BASE_TYPE_TEXT
+
"/vtt"
;
public
static
final
String
TEXT_VTT
=
BASE_TYPE_TEXT
+
"/vtt"
;
public
static
final
String
TEXT_SSA
=
BASE_TYPE_TEXT
+
"/x-ssa"
;
public
static
final
String
APPLICATION_MP4
=
BASE_TYPE_APPLICATION
+
"/mp4"
;
public
static
final
String
APPLICATION_MP4
=
BASE_TYPE_APPLICATION
+
"/mp4"
;
public
static
final
String
APPLICATION_WEBM
=
BASE_TYPE_APPLICATION
+
"/webm"
;
public
static
final
String
APPLICATION_WEBM
=
BASE_TYPE_APPLICATION
+
"/webm"
;
...
...
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