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
83780198
authored
Sep 19, 2014
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Fix SmoothStreaming where audio FourCC is missing.
parent
b2fc944a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
38 additions
and
123 deletions
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifest.java
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifestParser.java
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingUtil.java
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifest.java
View file @
83780198
...
...
@@ -16,7 +16,6 @@
package
com
.
google
.
android
.
exoplayer
.
smoothstreaming
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
com.google.android.exoplayer.util.Util
;
import
android.net.Uri
;
...
...
@@ -103,12 +102,9 @@ public class SmoothStreamingManifest {
public
final
int
bitrate
;
// Audio-video
public
final
String
fourCC
;
public
final
byte
[][]
csd
;
public
final
int
profile
;
public
final
int
level
;
// Audio-video (derived)
public
final
String
mimeType
;
// Video-only
...
...
@@ -125,12 +121,12 @@ public class SmoothStreamingManifest {
public
final
int
nalUnitLengthField
;
public
final
String
content
;
public
TrackElement
(
int
index
,
int
bitrate
,
String
fourCC
,
byte
[][]
csd
,
int
profile
,
int
level
,
int
maxWidth
,
int
maxHeight
,
int
sampleRate
,
int
channels
,
int
packetSize
,
int
audioTag
,
int
bitPerSample
,
int
nalUnitLengthField
,
String
content
)
{
public
TrackElement
(
int
index
,
int
bitrate
,
String
mimeType
,
byte
[][]
csd
,
int
profile
,
int
level
,
int
maxWidth
,
int
maxHeight
,
int
sampleRate
,
int
channels
,
int
packetSize
,
int
audioTag
,
int
bitPerSample
,
int
nalUnitLengthField
,
String
content
)
{
this
.
index
=
index
;
this
.
bitrate
=
bitrate
;
this
.
fourCC
=
fourCC
;
this
.
mimeType
=
mimeType
;
this
.
csd
=
csd
;
this
.
profile
=
profile
;
this
.
level
=
level
;
...
...
@@ -143,19 +139,6 @@ public class SmoothStreamingManifest {
this
.
bitPerSample
=
bitPerSample
;
this
.
nalUnitLengthField
=
nalUnitLengthField
;
this
.
content
=
content
;
this
.
mimeType
=
fourCCToMimeType
(
fourCC
);
}
private
static
String
fourCCToMimeType
(
String
fourCC
)
{
if
(
fourCC
.
equalsIgnoreCase
(
"H264"
)
||
fourCC
.
equalsIgnoreCase
(
"AVC1"
)
||
fourCC
.
equalsIgnoreCase
(
"DAVC"
))
{
return
MimeTypes
.
VIDEO_H264
;
}
else
if
(
fourCC
.
equalsIgnoreCase
(
"AACL"
)
||
fourCC
.
equalsIgnoreCase
(
"AACH"
))
{
return
MimeTypes
.
AUDIO_AAC
;
}
else
if
(
fourCC
.
equalsIgnoreCase
(
"TTML"
))
{
return
MimeTypes
.
APPLICATION_TTML
;
}
return
null
;
}
}
...
...
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifestParser.java
View file @
83780198
...
...
@@ -22,6 +22,7 @@ import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.Trac
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.CodecSpecificDataUtil
;
import
com.google.android.exoplayer.util.ManifestParser
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
android.net.Uri
;
import
android.util.Base64
;
...
...
@@ -586,7 +587,7 @@ public class SmoothStreamingManifestParser implements ManifestParser<SmoothStrea
private
int
index
;
private
int
bitrate
;
private
String
fourCC
;
private
String
mimeType
;
private
int
profile
;
private
int
level
;
private
int
maxWidth
;
...
...
@@ -618,11 +619,14 @@ public class SmoothStreamingManifestParser implements ManifestParser<SmoothStrea
if
(
type
==
StreamElement
.
TYPE_VIDEO
)
{
maxHeight
=
parseRequiredInt
(
parser
,
KEY_MAX_HEIGHT
);
maxWidth
=
parseRequiredInt
(
parser
,
KEY_MAX_WIDTH
);
fourCC
=
parseRequiredString
(
parser
,
KEY_FOUR_CC
);
mimeType
=
fourCCToMimeType
(
parseRequiredString
(
parser
,
KEY_FOUR_CC
)
);
}
else
{
maxHeight
=
-
1
;
maxWidth
=
-
1
;
fourCC
=
parser
.
getAttributeValue
(
null
,
KEY_FOUR_CC
);
String
fourCC
=
parser
.
getAttributeValue
(
null
,
KEY_FOUR_CC
);
// If fourCC is missing and the stream type is audio, we assume AAC.
mimeType
=
fourCC
!=
null
?
fourCCToMimeType
(
fourCC
)
:
type
==
StreamElement
.
TYPE_AUDIO
?
MimeTypes
.
AUDIO_AAC
:
null
;
}
if
(
type
==
StreamElement
.
TYPE_AUDIO
)
{
...
...
@@ -658,17 +662,6 @@ public class SmoothStreamingManifestParser implements ManifestParser<SmoothStrea
}
}
private
byte
[]
hexStringToByteArray
(
String
hexString
)
{
int
length
=
hexString
.
length
();
byte
[]
data
=
new
byte
[
length
/
2
];
for
(
int
i
=
0
;
i
<
data
.
length
;
i
++)
{
int
stringOffset
=
i
*
2
;
data
[
i
]
=
(
byte
)
((
Character
.
digit
(
hexString
.
charAt
(
stringOffset
),
16
)
<<
4
)
+
Character
.
digit
(
hexString
.
charAt
(
stringOffset
+
1
),
16
));
}
return
data
;
}
@Override
public
void
parseText
(
XmlPullParser
parser
)
{
content
=
parser
.
getText
();
...
...
@@ -681,8 +674,33 @@ public class SmoothStreamingManifestParser implements ManifestParser<SmoothStrea
csdArray
=
new
byte
[
csd
.
size
()][];
csd
.
toArray
(
csdArray
);
}
return
new
TrackElement
(
index
,
bitrate
,
fourCC
,
csdArray
,
profile
,
level
,
maxWidth
,
maxHeight
,
samplingRate
,
channels
,
packetSize
,
audioTag
,
bitPerSample
,
nalUnitLengthField
,
content
);
return
new
TrackElement
(
index
,
bitrate
,
mimeType
,
csdArray
,
profile
,
level
,
maxWidth
,
maxHeight
,
samplingRate
,
channels
,
packetSize
,
audioTag
,
bitPerSample
,
nalUnitLengthField
,
content
);
}
private
static
String
fourCCToMimeType
(
String
fourCC
)
{
if
(
fourCC
.
equalsIgnoreCase
(
"H264"
)
||
fourCC
.
equalsIgnoreCase
(
"X264"
)
||
fourCC
.
equalsIgnoreCase
(
"AVC1"
)
||
fourCC
.
equalsIgnoreCase
(
"DAVC"
))
{
return
MimeTypes
.
VIDEO_H264
;
}
else
if
(
fourCC
.
equalsIgnoreCase
(
"AAC"
)
||
fourCC
.
equalsIgnoreCase
(
"AACL"
)
||
fourCC
.
equalsIgnoreCase
(
"AACH"
)
||
fourCC
.
equalsIgnoreCase
(
"AACP"
))
{
return
MimeTypes
.
AUDIO_AAC
;
}
else
if
(
fourCC
.
equalsIgnoreCase
(
"TTML"
))
{
return
MimeTypes
.
APPLICATION_TTML
;
}
return
null
;
}
private
static
byte
[]
hexStringToByteArray
(
String
hexString
)
{
int
length
=
hexString
.
length
();
byte
[]
data
=
new
byte
[
length
/
2
];
for
(
int
i
=
0
;
i
<
data
.
length
;
i
++)
{
int
stringOffset
=
i
*
2
;
data
[
i
]
=
(
byte
)
((
Character
.
digit
(
hexString
.
charAt
(
stringOffset
),
16
)
<<
4
)
+
Character
.
digit
(
hexString
.
charAt
(
stringOffset
+
1
),
16
));
}
return
data
;
}
}
...
...
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingUtil.java
deleted
100644 → 0
View file @
b2fc944a
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
smoothstreaming
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.StreamElement
;
import
com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.TrackElement
;
import
com.google.android.exoplayer.util.CodecSpecificDataUtil
;
import
android.util.Base64
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
public
class
SmoothStreamingUtil
{
private
SmoothStreamingUtil
()
{}
/**
* Builds a {@link MediaFormat} for the specified track of the specified {@link StreamElement}.
*
* @param element The stream element.
* @param track The index of the track for which to build the format.
* @return The format.
*/
public
static
MediaFormat
getMediaFormat
(
StreamElement
element
,
int
track
)
{
TrackElement
trackElement
=
element
.
tracks
[
track
];
String
mimeType
=
trackElement
.
mimeType
;
if
(
element
.
type
==
StreamElement
.
TYPE_VIDEO
)
{
MediaFormat
format
=
MediaFormat
.
createVideoFormat
(
mimeType
,
-
1
,
trackElement
.
maxWidth
,
trackElement
.
maxHeight
,
Arrays
.
asList
(
trackElement
.
csd
));
format
.
setMaxVideoDimensions
(
element
.
maxWidth
,
element
.
maxHeight
);
return
format
;
}
else
if
(
element
.
type
==
StreamElement
.
TYPE_AUDIO
)
{
List
<
byte
[]>
csd
;
if
(
trackElement
.
csd
!=
null
)
{
csd
=
Arrays
.
asList
(
trackElement
.
csd
);
}
else
{
csd
=
Collections
.
singletonList
(
CodecSpecificDataUtil
.
buildAudioSpecificConfig
(
trackElement
.
sampleRate
,
trackElement
.
numChannels
));
}
MediaFormat
format
=
MediaFormat
.
createAudioFormat
(
mimeType
,
-
1
,
trackElement
.
numChannels
,
trackElement
.
sampleRate
,
csd
);
return
format
;
}
// TODO: Do subtitles need a format? MediaFormat supports KEY_LANGUAGE.
return
null
;
}
public
static
byte
[]
getKeyId
(
byte
[]
initData
)
{
StringBuilder
initDataStringBuilder
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
initData
.
length
;
i
+=
2
)
{
initDataStringBuilder
.
append
((
char
)
initData
[
i
]);
}
String
initDataString
=
initDataStringBuilder
.
toString
();
String
keyIdString
=
initDataString
.
substring
(
initDataString
.
indexOf
(
"<KID>"
)
+
5
,
initDataString
.
indexOf
(
"</KID>"
));
byte
[]
keyId
=
Base64
.
decode
(
keyIdString
,
Base64
.
DEFAULT
);
swap
(
keyId
,
0
,
3
);
swap
(
keyId
,
1
,
2
);
swap
(
keyId
,
4
,
5
);
swap
(
keyId
,
6
,
7
);
return
keyId
;
}
private
static
void
swap
(
byte
[]
data
,
int
firstPosition
,
int
secondPosition
)
{
byte
temp
=
data
[
firstPosition
];
data
[
firstPosition
]
=
data
[
secondPosition
];
data
[
secondPosition
]
=
temp
;
}
}
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