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
1a9bf018
authored
Apr 22, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add frame rate to Format for use in format selection (when known).
parent
a7e2b719
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
77 additions
and
43 deletions
library/src/main/java/com/google/android/exoplayer/SmoothFrameReleaseTimeHelper.java
library/src/main/java/com/google/android/exoplayer/chunk/Format.java
library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescriptionParser.java
library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java
library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlParser.java
library/src/test/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java
library/src/test/java/com/google/android/exoplayer/dash/mpd/RepresentationTest.java
library/src/main/java/com/google/android/exoplayer/SmoothFrameReleaseTimeHelper.java
View file @
1a9bf018
...
@@ -107,7 +107,7 @@ public class SmoothFrameReleaseTimeHelper implements FrameReleaseTimeHelper, Fra
...
@@ -107,7 +107,7 @@ public class SmoothFrameReleaseTimeHelper implements FrameReleaseTimeHelper, Fra
if
(
frameCount
>=
MIN_FRAMES_FOR_ADJUSTMENT
)
{
if
(
frameCount
>=
MIN_FRAMES_FOR_ADJUSTMENT
)
{
// We're synced and have waited the required number of frames to apply an adjustment.
// We're synced and have waited the required number of frames to apply an adjustment.
// Calculate the average frame time across all the frames we've seen since the last sync.
// Calculate the average frame time across all the frames we've seen since the last sync.
// This will typically give us a framerate at a finer granularity than the frame times
// This will typically give us a frame
rate at a finer granularity than the frame times
// themselves (which often only have millisecond granularity).
// themselves (which often only have millisecond granularity).
long
averageFrameTimeNs
=
(
unadjustedFrameTimeNs
-
syncFrameTimeNs
)
/
frameCount
;
long
averageFrameTimeNs
=
(
unadjustedFrameTimeNs
-
syncFrameTimeNs
)
/
frameCount
;
// Project the adjusted frame time forward using the average.
// Project the adjusted frame time forward using the average.
...
...
library/src/main/java/com/google/android/exoplayer/chunk/Format.java
View file @
1a9bf018
...
@@ -47,34 +47,39 @@ public class Format {
...
@@ -47,34 +47,39 @@ public class Format {
public
final
String
mimeType
;
public
final
String
mimeType
;
/**
/**
* The
codecs used to decode the format, or {@code null} if they are not specifie
d.
* The
average bandwidth in bits per secon
d.
*/
*/
public
final
String
codecs
;
public
final
int
bitrate
;
/**
/**
* The width of the video in pixels, or -1
for non-video formats
.
* The width of the video in pixels, or -1
if unknown or not applicable
.
*/
*/
public
final
int
width
;
public
final
int
width
;
/**
/**
* The height of the video in pixels, or -1
for non-video formats
.
* The height of the video in pixels, or -1
if unknown or not applicable
.
*/
*/
public
final
int
height
;
public
final
int
height
;
/**
/**
* The number of audio channels, or -1 for non-audio formats.
* The video frame rate in frames per second, or -1 if unknown or not applicable.
*/
public
final
float
frameRate
;
/**
* The number of audio channels, or -1 if unknown or not applicable.
*/
*/
public
final
int
numChannels
;
public
final
int
numChannels
;
/**
/**
* The audio sampling rate in Hz, or -1
for non-audio formats
.
* The audio sampling rate in Hz, or -1
if unknown or not applicable
.
*/
*/
public
final
int
audioSamplingRate
;
public
final
int
audioSamplingRate
;
/**
/**
* The
average bandwidth in bits per second
.
* The
codecs used to decode the format. Can be {@code null} if unknown
.
*/
*/
public
final
int
bitrate
;
public
final
String
codecs
;
/**
/**
* The language of the format. Can be null if unknown.
* The language of the format. Can be null if unknown.
...
@@ -87,50 +92,58 @@ public class Format {
...
@@ -87,50 +92,58 @@ public class Format {
/**
/**
* @param id The format identifier.
* @param id The format identifier.
* @param mimeType The format mime type.
* @param mimeType The format mime type.
* @param width The width of the video in pixels, or -1 for non-video formats.
* @param width The width of the video in pixels, or -1 if unknown or not applicable.
* @param height The height of the video in pixels, or -1 for non-video formats.
* @param height The height of the video in pixels, or -1 if unknown or not applicable.
* @param numChannels The number of audio channels, or -1 for non-audio formats.
* @param frameRate The frame rate of the video in frames per second, or -1 if unknown or not
* @param audioSamplingRate The audio sampling rate in Hz, or -1 for non-audio formats.
* applicable.
* @param numChannels The number of audio channels, or -1 if unknown or not applicable.
* @param audioSamplingRate The audio sampling rate in Hz, or -1 if unknown or not applicable.
* @param bitrate The average bandwidth of the format in bits per second.
* @param bitrate The average bandwidth of the format in bits per second.
*/
*/
public
Format
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
int
numChannels
,
public
Format
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
float
frameRate
,
int
numChannels
,
int
audioSamplingRate
,
int
bitrate
)
{
int
audioSamplingRate
,
int
bitrate
)
{
this
(
id
,
mimeType
,
width
,
height
,
numChannels
,
audioSamplingRate
,
bitrate
,
null
,
null
);
this
(
id
,
mimeType
,
width
,
height
,
frameRate
,
numChannels
,
audioSamplingRate
,
bitrate
,
null
);
}
}
/**
/**
* @param id The format identifier.
* @param id The format identifier.
* @param mimeType The format mime type.
* @param mimeType The format mime type.
* @param width The width of the video in pixels, or -1 for non-video formats.
* @param width The width of the video in pixels, or -1 if unknown or not applicable.
* @param height The height of the video in pixels, or -1 for non-video formats.
* @param height The height of the video in pixels, or -1 if unknown or not applicable.
* @param numChannels The number of audio channels, or -1 for non-audio formats.
* @param frameRate The frame rate of the video in frames per second, or -1 if unknown or not
* @param audioSamplingRate The audio sampling rate in Hz, or -1 for non-audio formats.
* applicable.
* @param numChannels The number of audio channels, or -1 if unknown or not applicable.
* @param audioSamplingRate The audio sampling rate in Hz, or -1 if unknown or not applicable.
* @param bitrate The average bandwidth of the format in bits per second.
* @param bitrate The average bandwidth of the format in bits per second.
* @param language The language of the format.
* @param language The language of the format.
*/
*/
public
Format
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
int
numChannels
,
public
Format
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
float
frameRate
,
int
numChannels
,
int
audioSamplingRate
,
int
bitrate
,
String
language
)
{
int
audioSamplingRate
,
int
bitrate
,
String
language
)
{
this
(
id
,
mimeType
,
width
,
height
,
numChannels
,
audioSamplingRate
,
bitrate
,
language
,
null
);
this
(
id
,
mimeType
,
width
,
height
,
frameRate
,
numChannels
,
audioSamplingRate
,
bitrate
,
language
,
null
);
}
}
/**
/**
* @param id The format identifier.
* @param id The format identifier.
* @param mimeType The format mime type.
* @param mimeType The format mime type.
* @param width The width of the video in pixels, or -1 for non-video formats.
* @param width The width of the video in pixels, or -1 if unknown or not applicable.
* @param height The height of the video in pixels, or -1 for non-video formats.
* @param height The height of the video in pixels, or -1 if unknown or not applicable.
* @param numChannels The number of audio channels, or -1 for non-audio formats.
* @param frameRate The frame rate of the video in frames per second, or -1 if unknown or not
* @param audioSamplingRate The audio sampling rate in Hz, or -1 for non-audio formats.
* applicable.
* @param numChannels The number of audio channels, or -1 if unknown or not applicable.
* @param audioSamplingRate The audio sampling rate in Hz, or -1 if unknown or not applicable.
* @param bitrate The average bandwidth of the format in bits per second.
* @param bitrate The average bandwidth of the format in bits per second.
* @param language The language of the format.
* @param language The language of the format.
* @param codecs The codecs used to decode the format.
* @param codecs The codecs used to decode the format.
*/
*/
public
Format
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
int
numChannels
,
public
Format
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
float
frameRate
,
int
numChannels
,
int
audioSamplingRate
,
int
bitrate
,
String
language
,
String
codecs
)
{
int
audioSamplingRate
,
int
bitrate
,
String
language
,
String
codecs
)
{
this
.
id
=
Assertions
.
checkNotNull
(
id
);
this
.
id
=
Assertions
.
checkNotNull
(
id
);
this
.
mimeType
=
mimeType
;
this
.
mimeType
=
mimeType
;
this
.
width
=
width
;
this
.
width
=
width
;
this
.
height
=
height
;
this
.
height
=
height
;
this
.
frameRate
=
frameRate
;
this
.
numChannels
=
numChannels
;
this
.
numChannels
=
numChannels
;
this
.
audioSamplingRate
=
audioSamplingRate
;
this
.
audioSamplingRate
=
audioSamplingRate
;
this
.
bitrate
=
bitrate
;
this
.
bitrate
=
bitrate
;
...
...
library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescriptionParser.java
View file @
1a9bf018
...
@@ -41,6 +41,8 @@ import java.util.ArrayList;
...
@@ -41,6 +41,8 @@ import java.util.ArrayList;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.Comparator
;
import
java.util.List
;
import
java.util.List
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
/**
* A parser of media presentation description files.
* A parser of media presentation description files.
...
@@ -48,6 +50,8 @@ import java.util.List;
...
@@ -48,6 +50,8 @@ import java.util.List;
public
class
MediaPresentationDescriptionParser
extends
DefaultHandler
public
class
MediaPresentationDescriptionParser
extends
DefaultHandler
implements
NetworkLoadable
.
Parser
<
MediaPresentationDescription
>
{
implements
NetworkLoadable
.
Parser
<
MediaPresentationDescription
>
{
private
static
final
Pattern
FRAME_RATE_PATTERN
=
Pattern
.
compile
(
"(\\d+)(?:/(\\d+))??"
);
private
final
String
contentId
;
private
final
String
contentId
;
private
final
XmlPullParserFactory
xmlParserFactory
;
private
final
XmlPullParserFactory
xmlParserFactory
;
...
@@ -296,6 +300,22 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
...
@@ -296,6 +300,22 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
int
audioSamplingRate
=
parseInt
(
xpp
,
"audioSamplingRate"
);
int
audioSamplingRate
=
parseInt
(
xpp
,
"audioSamplingRate"
);
int
width
=
parseInt
(
xpp
,
"width"
);
int
width
=
parseInt
(
xpp
,
"width"
);
int
height
=
parseInt
(
xpp
,
"height"
);
int
height
=
parseInt
(
xpp
,
"height"
);
float
frameRate
=
-
1
;
String
frameRateAttribute
=
xpp
.
getAttributeValue
(
null
,
"frameRate"
);
if
(
frameRateAttribute
!=
null
)
{
Matcher
frameRateMatcher
=
FRAME_RATE_PATTERN
.
matcher
(
frameRateAttribute
);
if
(
frameRateMatcher
.
matches
())
{
int
numerator
=
Integer
.
parseInt
(
frameRateMatcher
.
group
(
1
));
String
denominatorString
=
frameRateMatcher
.
group
(
2
);
if
(!
TextUtils
.
isEmpty
(
denominatorString
))
{
frameRate
=
(
float
)
numerator
/
Integer
.
parseInt
(
denominatorString
);
}
else
{
frameRate
=
numerator
;
}
}
}
mimeType
=
parseString
(
xpp
,
"mimeType"
,
mimeType
);
mimeType
=
parseString
(
xpp
,
"mimeType"
,
mimeType
);
String
codecs
=
parseString
(
xpp
,
"codecs"
,
null
);
String
codecs
=
parseString
(
xpp
,
"codecs"
,
null
);
...
@@ -318,16 +338,16 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
...
@@ -318,16 +338,16 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
}
}
}
while
(!
isEndTag
(
xpp
,
"Representation"
));
}
while
(!
isEndTag
(
xpp
,
"Representation"
));
Format
format
=
buildFormat
(
id
,
mimeType
,
width
,
height
,
numChannels
,
audioSamplingRate
,
Format
format
=
buildFormat
(
id
,
mimeType
,
width
,
height
,
frameRate
,
numChannels
,
bandwidth
,
language
,
codecs
);
audioSamplingRate
,
bandwidth
,
language
,
codecs
);
return
buildRepresentation
(
periodStartMs
,
periodDurationMs
,
contentId
,
-
1
,
format
,
return
buildRepresentation
(
periodStartMs
,
periodDurationMs
,
contentId
,
-
1
,
format
,
segmentBase
!=
null
?
segmentBase
:
new
SingleSegmentBase
(
baseUrl
));
segmentBase
!=
null
?
segmentBase
:
new
SingleSegmentBase
(
baseUrl
));
}
}
protected
Format
buildFormat
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
int
numChannels
,
protected
Format
buildFormat
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
float
frameRate
,
int
audioSamplingRate
,
int
bandwidth
,
String
language
,
String
codecs
)
{
int
numChannels
,
int
audioSamplingRate
,
int
bandwidth
,
String
language
,
String
codecs
)
{
return
new
Format
(
id
,
mimeType
,
width
,
height
,
numChannels
,
audioSamplingRate
,
bandwidth
,
return
new
Format
(
id
,
mimeType
,
width
,
height
,
frameRate
,
numChannels
,
audioSamplingRate
,
language
,
codecs
);
bandwidth
,
language
,
codecs
);
}
}
protected
Representation
buildRepresentation
(
long
periodStartMs
,
long
periodDurationMs
,
protected
Representation
buildRepresentation
(
long
periodStartMs
,
long
periodDurationMs
,
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
View file @
1a9bf018
...
@@ -676,7 +676,7 @@ public class HlsChunkSource {
...
@@ -676,7 +676,7 @@ public class HlsChunkSource {
public
HlsFormat
(
String
id
,
int
width
,
int
height
,
int
bitrate
,
String
codecs
,
public
HlsFormat
(
String
id
,
int
width
,
int
height
,
int
bitrate
,
String
codecs
,
int
variantIndex
)
{
int
variantIndex
)
{
super
(
id
,
MimeTypes
.
APPLICATION_M3U8
,
width
,
height
,
-
1
,
-
1
,
bitrate
,
null
,
codecs
);
super
(
id
,
MimeTypes
.
APPLICATION_M3U8
,
width
,
height
,
-
1
,
-
1
,
-
1
,
bitrate
,
null
,
codecs
);
this
.
variantIndex
=
variantIndex
;
this
.
variantIndex
=
variantIndex
;
}
}
...
...
library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingChunkSource.java
View file @
1a9bf018
...
@@ -417,7 +417,7 @@ public class SmoothStreamingChunkSource implements ChunkSource {
...
@@ -417,7 +417,7 @@ public class SmoothStreamingChunkSource implements ChunkSource {
public
SmoothStreamingFormat
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
public
SmoothStreamingFormat
(
String
id
,
String
mimeType
,
int
width
,
int
height
,
int
numChannels
,
int
audioSamplingRate
,
int
bitrate
,
int
trackIndex
)
{
int
numChannels
,
int
audioSamplingRate
,
int
bitrate
,
int
trackIndex
)
{
super
(
id
,
mimeType
,
width
,
height
,
numChannels
,
audioSamplingRate
,
bitrate
);
super
(
id
,
mimeType
,
width
,
height
,
-
1
,
numChannels
,
audioSamplingRate
,
bitrate
);
this
.
trackIndex
=
trackIndex
;
this
.
trackIndex
=
trackIndex
;
}
}
...
...
library/src/main/java/com/google/android/exoplayer/text/ttml/TtmlParser.java
View file @
1a9bf018
...
@@ -232,8 +232,8 @@ public class TtmlParser implements SubtitleParser {
...
@@ -232,8 +232,8 @@ public class TtmlParser implements SubtitleParser {
* <a href="http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression">timeExpression</a>
* <a href="http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression">timeExpression</a>
*
*
* @param time A string that includes the time expression.
* @param time A string that includes the time expression.
* @param frameRate The framerate of the stream.
* @param frameRate The frame
rate of the stream.
* @param subframeRate The sub-framerate of the stream
* @param subframeRate The sub-frame
rate of the stream
* @param tickRate The tick rate of the stream.
* @param tickRate The tick rate of the stream.
* @return The parsed timestamp in microseconds.
* @return The parsed timestamp in microseconds.
* @throws ParserException If the given string does not contain a valid time expression.
* @throws ParserException If the given string does not contain a valid time expression.
...
...
library/src/test/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java
View file @
1a9bf018
...
@@ -65,11 +65,12 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
...
@@ -65,11 +65,12 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
private
static
final
int
TALL_HEIGHT
=
200
;
private
static
final
int
TALL_HEIGHT
=
200
;
private
static
final
int
WIDE_WIDTH
=
400
;
private
static
final
int
WIDE_WIDTH
=
400
;
private
static
final
Format
REGULAR_VIDEO
=
new
Format
(
"1"
,
"video/mp4"
,
480
,
240
,
-
1
,
-
1
,
1000
);
private
static
final
Format
REGULAR_VIDEO
=
private
static
final
Format
TALL_VIDEO
=
new
Format
(
"2"
,
"video/mp4"
,
100
,
TALL_HEIGHT
,
-
1
,
-
1
,
new
Format
(
"1"
,
"video/mp4"
,
480
,
240
,
-
1
,
-
1
,
-
1
,
1000
);
1000
);
private
static
final
Format
TALL_VIDEO
=
private
static
final
Format
WIDE_VIDEO
=
new
Format
(
"3"
,
"video/mp4"
,
WIDE_WIDTH
,
50
,
-
1
,
-
1
,
new
Format
(
"2"
,
"video/mp4"
,
100
,
TALL_HEIGHT
,
-
1
,
-
1
,
-
1
,
1000
);
1000
);
private
static
final
Format
WIDE_VIDEO
=
new
Format
(
"3"
,
"video/mp4"
,
WIDE_WIDTH
,
50
,
-
1
,
-
1
,
-
1
,
1000
);
@Mock
private
DataSource
mockDataSource
;
@Mock
private
DataSource
mockDataSource
;
@Mock
private
ManifestFetcher
<
MediaPresentationDescription
>
mockManifestFetcher
;
@Mock
private
ManifestFetcher
<
MediaPresentationDescription
>
mockManifestFetcher
;
...
...
library/src/test/java/com/google/android/exoplayer/dash/mpd/RepresentationTest.java
View file @
1a9bf018
...
@@ -29,12 +29,12 @@ public class RepresentationTest extends TestCase {
...
@@ -29,12 +29,12 @@ public class RepresentationTest extends TestCase {
public
void
testGetCacheKey
()
{
public
void
testGetCacheKey
()
{
String
uri
=
"http://www.google.com"
;
String
uri
=
"http://www.google.com"
;
SegmentBase
base
=
new
SingleSegmentBase
(
new
RangedUri
(
uri
,
null
,
0
,
1
),
1
,
0
,
uri
,
1
,
1
);
SegmentBase
base
=
new
SingleSegmentBase
(
new
RangedUri
(
uri
,
null
,
0
,
1
),
1
,
0
,
uri
,
1
,
1
);
Format
format
=
new
Format
(
"0"
,
MimeTypes
.
VIDEO_MP4
,
1920
,
1080
,
0
,
0
,
2500000
);
Format
format
=
new
Format
(
"0"
,
MimeTypes
.
VIDEO_MP4
,
1920
,
1080
,
-
1
,
0
,
0
,
2500000
);
Representation
representation
=
Representation
.
newInstance
(-
1
,
-
1
,
"test_stream_1"
,
3
,
Representation
representation
=
Representation
.
newInstance
(-
1
,
-
1
,
"test_stream_1"
,
3
,
format
,
base
);
format
,
base
);
assertEquals
(
"test_stream_1.0.3"
,
representation
.
getCacheKey
());
assertEquals
(
"test_stream_1.0.3"
,
representation
.
getCacheKey
());
format
=
new
Format
(
"150"
,
MimeTypes
.
VIDEO_MP4
,
1920
,
1080
,
0
,
0
,
2500000
);
format
=
new
Format
(
"150"
,
MimeTypes
.
VIDEO_MP4
,
1920
,
1080
,
-
1
,
0
,
0
,
2500000
);
representation
=
Representation
.
newInstance
(-
1
,
-
1
,
"test_stream_1"
,
-
1
,
format
,
base
);
representation
=
Representation
.
newInstance
(-
1
,
-
1
,
"test_stream_1"
,
-
1
,
format
,
base
);
assertEquals
(
"test_stream_1.150.-1"
,
representation
.
getCacheKey
());
assertEquals
(
"test_stream_1.150.-1"
,
representation
.
getCacheKey
());
}
}
...
...
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