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
5b02f92d
authored
Jun 10, 2019
by
sr1990
Committed by
sanil
Jun 10, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
[Patch V2] Support signalling of last segment number via supplemental descriptor in mpd
parent
2091aa5c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
100 additions
and
37 deletions
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
View file @
5b02f92d
...
...
@@ -42,7 +42,6 @@ import com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk;
import
com.google.android.exoplayer2.source.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler
;
import
com.google.android.exoplayer2.source.dash.manifest.AdaptationSet
;
import
com.google.android.exoplayer2.source.dash.manifest.DashManifest
;
import
com.google.android.exoplayer2.source.dash.manifest.Descriptor
;
import
com.google.android.exoplayer2.source.dash.manifest.RangedUri
;
import
com.google.android.exoplayer2.source.dash.manifest.Representation
;
import
com.google.android.exoplayer2.trackselection.TrackSelection
;
...
...
@@ -326,35 +325,10 @@ public class DefaultDashChunkSource implements DashChunkSource {
return
;
}
List
<
Descriptor
>
listDescriptors
;
Integer
lastSegmentNumberSchemeIdUri
=
Integer
.
MAX_VALUE
;
String
sampleMimeType
=
trackSelection
.
getFormat
(
periodIndex
).
sampleMimeType
;
if
(
sampleMimeType
.
contains
(
"video"
)
||
sampleMimeType
.
contains
(
"audio"
))
{
int
track_type
=
sampleMimeType
.
contains
(
"video"
)?
C
.
TRACK_TYPE_VIDEO
:
C
.
TRACK_TYPE_AUDIO
;
if
(!
manifest
.
getPeriod
(
periodIndex
).
adaptationSets
.
get
(
manifest
.
getPeriod
(
periodIndex
)
.
getAdaptationSetIndex
(
track_type
)).
supplementalProperties
.
isEmpty
())
{
listDescriptors
=
manifest
.
getPeriod
(
periodIndex
).
adaptationSets
.
get
(
manifest
.
getPeriod
(
periodIndex
).
getAdaptationSetIndex
(
track_type
))
.
supplementalProperties
;
for
(
Descriptor
descriptor:
listDescriptors
)
{
if
(
descriptor
.
schemeIdUri
.
equalsIgnoreCase
(
"http://dashif.org/guidelines/last-segment-number"
))
{
lastSegmentNumberSchemeIdUri
=
Integer
.
valueOf
(
descriptor
.
value
);
}
}
}
}
long
firstAvailableSegmentNum
=
representationHolder
.
getFirstAvailableSegmentNum
(
manifest
,
periodIndex
,
nowUnixTimeUs
);
long
lastAvailableSegmentNum
=
Math
.
min
(
representationHolder
.
getLastAvailableSegmentNum
(
manifest
,
periodIndex
,
nowUnixTimeUs
),
lastSegmentNumberSchemeIdUri
);
representationHolder
.
getLastAvailableSegmentNum
(
manifest
,
periodIndex
,
nowUnixTimeUs
);
updateLiveEdgeTimeUs
(
representationHolder
,
lastAvailableSegmentNum
);
long
segmentNum
=
...
...
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java
View file @
5b02f92d
...
...
@@ -242,7 +242,7 @@ public class DashManifestParser extends DefaultHandler
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"SegmentList"
))
{
segmentBase
=
parseSegmentList
(
xpp
,
null
);
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"SegmentTemplate"
))
{
segmentBase
=
parseSegmentTemplate
(
xpp
,
null
);
segmentBase
=
parseSegmentTemplate
(
xpp
,
null
,
null
);
}
else
{
maybeSkipTag
(
xpp
);
}
...
...
@@ -323,7 +323,8 @@ public class DashManifestParser extends DefaultHandler
language
,
roleDescriptors
,
accessibilityDescriptors
,
segmentBase
);
segmentBase
,
supplementalProperties
);
contentType
=
checkContentTypeConsistency
(
contentType
,
getContentType
(
representationInfo
.
format
));
representationInfos
.
add
(
representationInfo
);
...
...
@@ -332,7 +333,7 @@ public class DashManifestParser extends DefaultHandler
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"SegmentList"
))
{
segmentBase
=
parseSegmentList
(
xpp
,
(
SegmentList
)
segmentBase
);
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"SegmentTemplate"
))
{
segmentBase
=
parseSegmentTemplate
(
xpp
,
(
SegmentTemplate
)
segmentBase
);
segmentBase
=
parseSegmentTemplate
(
xpp
,
(
SegmentTemplate
)
segmentBase
,
supplementalProperties
);
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"InbandEventStream"
))
{
inbandEventStreams
.
add
(
parseDescriptor
(
xpp
,
"InbandEventStream"
));
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
))
{
...
...
@@ -485,7 +486,8 @@ public class DashManifestParser extends DefaultHandler
String
adaptationSetLanguage
,
List
<
Descriptor
>
adaptationSetRoleDescriptors
,
List
<
Descriptor
>
adaptationSetAccessibilityDescriptors
,
SegmentBase
segmentBase
)
SegmentBase
segmentBase
,
ArrayList
<
Descriptor
>
parentSupplementalProperties
)
throws
XmlPullParserException
,
IOException
{
String
id
=
xpp
.
getAttributeValue
(
null
,
"id"
);
int
bandwidth
=
parseInt
(
xpp
,
"bandwidth"
,
Format
.
NO_VALUE
);
...
...
@@ -517,7 +519,8 @@ public class DashManifestParser extends DefaultHandler
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"SegmentList"
))
{
segmentBase
=
parseSegmentList
(
xpp
,
(
SegmentList
)
segmentBase
);
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"SegmentTemplate"
))
{
segmentBase
=
parseSegmentTemplate
(
xpp
,
(
SegmentTemplate
)
segmentBase
);
segmentBase
=
parseSegmentTemplate
(
xpp
,
(
SegmentTemplate
)
segmentBase
,
parentSupplementalProperties
);
}
else
if
(
XmlPullParserUtil
.
isStartTag
(
xpp
,
"ContentProtection"
))
{
Pair
<
String
,
SchemeData
>
contentProtection
=
parseContentProtection
(
xpp
);
if
(
contentProtection
.
first
!=
null
)
{
...
...
@@ -756,7 +759,8 @@ public class DashManifestParser extends DefaultHandler
startNumber
,
duration
,
timeline
,
segments
);
}
protected
SegmentTemplate
parseSegmentTemplate
(
XmlPullParser
xpp
,
SegmentTemplate
parent
)
protected
SegmentTemplate
parseSegmentTemplate
(
XmlPullParser
xpp
,
SegmentTemplate
parent
,
ArrayList
<
Descriptor
>
parentSupplementalProperties
)
throws
XmlPullParserException
,
IOException
{
long
timescale
=
parseLong
(
xpp
,
"timescale"
,
parent
!=
null
?
parent
.
timescale
:
1
);
long
presentationTimeOffset
=
parseLong
(
xpp
,
"presentationTimeOffset"
,
...
...
@@ -788,7 +792,8 @@ public class DashManifestParser extends DefaultHandler
}
return
buildSegmentTemplate
(
initialization
,
timescale
,
presentationTimeOffset
,
startNumber
,
duration
,
timeline
,
initializationTemplate
,
mediaTemplate
);
startNumber
,
duration
,
timeline
,
initializationTemplate
,
mediaTemplate
,
parentSupplementalProperties
);
}
protected
SegmentTemplate
buildSegmentTemplate
(
...
...
@@ -799,9 +804,21 @@ public class DashManifestParser extends DefaultHandler
long
duration
,
List
<
SegmentTimelineElement
>
timeline
,
UrlTemplate
initializationTemplate
,
UrlTemplate
mediaTemplate
)
{
UrlTemplate
mediaTemplate
,
ArrayList
<
Descriptor
>
supplementalProperties
)
{
if
(
supplementalProperties
!=
null
)
{
for
(
Descriptor
descriptor
:
supplementalProperties
)
{
if
(
descriptor
.
schemeIdUri
.
equalsIgnoreCase
(
"http://dashif.org/guidelines/last-segment-number"
))
{
return
new
SegmentTemplate
(
initialization
,
timescale
,
presentationTimeOffset
,
startNumber
,
Integer
.
valueOf
(
descriptor
.
value
),
duration
,
timeline
,
initializationTemplate
,
mediaTemplate
);
}
}
}
return
new
SegmentTemplate
(
initialization
,
timescale
,
presentationTimeOffset
,
startNumber
,
duration
,
timeline
,
initializationTemplate
,
mediaTemplate
);
startNumber
,
duration
,
timeline
,
initializationTemplate
,
mediaTemplate
);
}
/**
...
...
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/SegmentBase.java
View file @
5b02f92d
...
...
@@ -102,6 +102,7 @@ public abstract class SegmentBase {
/* package */
final
long
startNumber
;
/* package */
final
long
duration
;
/* package */
final
List
<
SegmentTimelineElement
>
segmentTimeline
;
/* package */
final
int
endNumber
;
/**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data
...
...
@@ -128,6 +129,38 @@ public abstract class SegmentBase {
this
.
startNumber
=
startNumber
;
this
.
duration
=
duration
;
this
.
segmentTimeline
=
segmentTimeline
;
this
.
endNumber
=
C
.
INDEX_UNSET
;
}
/**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data
* exists.
* @param timescale The timescale in units per second.
* @param presentationTimeOffset The presentation time offset. The value in seconds is the
* division of this value and {@code timescale}.
* @param startNumber The sequence number of the first segment.
* @param endNumber The sequence number of the last segment specified by SupplementalProperty
* schemeIdUri="http://dashif.org/guidelines/last-segment-number"
* @param duration The duration of each segment in the case of fixed duration segments. The
* value in seconds is the division of this value and {@code timescale}. If {@code
* segmentTimeline} is non-null then this parameter is ignored.
* @param segmentTimeline A segment timeline corresponding to the segments. If null, then
* segments are assumed to be of fixed duration as specified by the {@code duration}
* parameter.
*/
public
MultiSegmentBase
(
RangedUri
initialization
,
long
timescale
,
long
presentationTimeOffset
,
long
startNumber
,
int
endNumber
,
long
duration
,
List
<
SegmentTimelineElement
>
segmentTimeline
)
{
super
(
initialization
,
timescale
,
presentationTimeOffset
);
this
.
startNumber
=
startNumber
;
this
.
duration
=
duration
;
this
.
segmentTimeline
=
segmentTimeline
;
this
.
endNumber
=
endNumber
;
}
/** @see DashSegmentIndex#getSegmentNum(long, long) */
...
...
@@ -312,6 +345,43 @@ public abstract class SegmentBase {
this
.
mediaTemplate
=
mediaTemplate
;
}
/**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data
* exists. The value of this parameter is ignored if {@code initializationTemplate} is
* non-null.
* @param timescale The timescale in units per second.
* @param presentationTimeOffset The presentation time offset. The value in seconds is the
* division of this value and {@code timescale}.
* @param startNumber The sequence number of the first segment.
* @param endNumber The sequence number of the last segment specified by SupplementalProperty
* schemeIdUri="http://dashif.org/guidelines/last-segment-number"
* @param duration The duration of each segment in the case of fixed duration segments. The
* value in seconds is the division of this value and {@code timescale}. If {@code
* segmentTimeline} is non-null then this parameter is ignored.
* @param segmentTimeline A segment timeline corresponding to the segments. If null, then
* segments are assumed to be of fixed duration as specified by the {@code duration}
* parameter.
* @param initializationTemplate A template defining the location of initialization data, if
* such data exists. If non-null then the {@code initialization} parameter is ignored. If
* null then {@code initialization} will be used.
* @param mediaTemplate A template defining the location of each media segment.
*/
public
SegmentTemplate
(
RangedUri
initialization
,
long
timescale
,
long
presentationTimeOffset
,
long
startNumber
,
int
endNumber
,
long
duration
,
List
<
SegmentTimelineElement
>
segmentTimeline
,
UrlTemplate
initializationTemplate
,
UrlTemplate
mediaTemplate
)
{
super
(
initialization
,
timescale
,
presentationTimeOffset
,
startNumber
,
endNumber
,
duration
,
segmentTimeline
);
this
.
initializationTemplate
=
initializationTemplate
;
this
.
mediaTemplate
=
mediaTemplate
;
}
@Override
public
RangedUri
getInitialization
(
Representation
representation
)
{
if
(
initializationTemplate
!=
null
)
{
...
...
@@ -338,7 +408,9 @@ public abstract class SegmentBase {
@Override
public
int
getSegmentCount
(
long
periodDurationUs
)
{
if
(
segmentTimeline
!=
null
)
{
if
(
endNumber
!=
C
.
INDEX_UNSET
)
{
return
endNumber
;
}
else
if
(
segmentTimeline
!=
null
)
{
return
segmentTimeline
.
size
();
}
else
if
(
periodDurationUs
!=
C
.
TIME_UNSET
)
{
long
durationUs
=
(
duration
*
C
.
MICROS_PER_SECOND
)
/
timescale
;
...
...
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