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
553a1d2e
authored
Jul 18, 2014
by
ojw28
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #16 from google/dev
Add missing files.
parents
4228f2cf
bb5cfd52
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
463 additions
and
0 deletions
library/src/main/java/com/google/android/exoplayer/dash/DashSegmentIndex.java
library/src/main/java/com/google/android/exoplayer/dash/DashWrappingSegmentIndex.java
library/src/main/java/com/google/android/exoplayer/dash/mpd/SegmentBase.java
library/src/main/java/com/google/android/exoplayer/dash/DashSegmentIndex.java
0 → 100644
View file @
553a1d2e
/*
* 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
.
dash
;
import
com.google.android.exoplayer.dash.mpd.RangedUri
;
/**
* Indexes the segments within a media stream.
*
* TODO: Generalize to cover all chunk streaming modes (e.g. SmoothStreaming) if possible.
*/
public
interface
DashSegmentIndex
{
/**
* Returns the segment number of the segment containing a given media time.
*
* @param timeUs The time in microseconds.
* @return The segment number of the corresponding segment.
*/
int
getSegmentNum
(
long
timeUs
);
/**
* Returns the start time of a segment.
*
* @param segmentNum The segment number.
* @return The corresponding start time in microseconds.
*/
long
getTimeUs
(
int
segmentNum
);
/**
* Returns the duration of a segment.
*
* @param segmentNum The segment number.
* @return The duration of the segment, in microseconds.
*/
long
getDurationUs
(
int
segmentNum
);
/**
* Returns a {@link RangedUri} defining the location of a segment.
*
* @param segmentNum The segment number.
* @return The {@link RangedUri} defining the location of the data.
*/
RangedUri
getSegmentUrl
(
int
segmentNum
);
/**
* Returns the segment number of the first segment.
*
* @return The segment number of the first segment.
*/
int
getFirstSegmentNum
();
/**
* Returns the segment number of the last segment.
*
* @return The segment number of the last segment.
*/
int
getLastSegmentNum
();
}
library/src/main/java/com/google/android/exoplayer/dash/DashWrappingSegmentIndex.java
0 → 100644
View file @
553a1d2e
/*
* 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
.
dash
;
import
com.google.android.exoplayer.dash.mpd.RangedUri
;
import
com.google.android.exoplayer.parser.SegmentIndex
;
import
com.google.android.exoplayer.util.Util
;
import
android.net.Uri
;
/**
* An implementation of {@link DashSegmentIndex} that wraps a {@link SegmentIndex} parsed from a
* media stream.
*/
public
class
DashWrappingSegmentIndex
implements
DashSegmentIndex
{
private
final
SegmentIndex
segmentIndex
;
private
final
Uri
uri
;
private
final
long
indexAnchor
;
/**
* @param segmentIndex The {@link SegmentIndex} to wrap.
* @param uri The {@link Uri} where the data is located.
* @param indexAnchor The index anchor point. This value is added to the byte offsets specified
* in the wrapped {@link SegmentIndex}.
*/
public
DashWrappingSegmentIndex
(
SegmentIndex
segmentIndex
,
Uri
uri
,
long
indexAnchor
)
{
this
.
segmentIndex
=
segmentIndex
;
this
.
uri
=
uri
;
this
.
indexAnchor
=
indexAnchor
;
}
@Override
public
int
getFirstSegmentNum
()
{
return
0
;
}
@Override
public
int
getLastSegmentNum
()
{
return
segmentIndex
.
length
-
1
;
}
@Override
public
long
getTimeUs
(
int
segmentNum
)
{
return
segmentIndex
.
timesUs
[
segmentNum
];
}
@Override
public
long
getDurationUs
(
int
segmentNum
)
{
return
segmentIndex
.
durationsUs
[
segmentNum
];
}
@Override
public
RangedUri
getSegmentUrl
(
int
segmentNum
)
{
return
new
RangedUri
(
uri
,
null
,
indexAnchor
+
segmentIndex
.
offsets
[
segmentNum
],
segmentIndex
.
sizes
[
segmentNum
]);
}
@Override
public
int
getSegmentNum
(
long
timeUs
)
{
return
Util
.
binarySearchFloor
(
segmentIndex
.
timesUs
,
timeUs
,
true
,
true
);
}
}
library/src/main/java/com/google/android/exoplayer/dash/mpd/SegmentBase.java
0 → 100644
View file @
553a1d2e
/*
* 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
.
dash
.
mpd
;
import
android.net.Uri
;
import
java.util.List
;
/**
* An approximate representation of a SegmentBase manifest element.
*/
public
abstract
class
SegmentBase
{
/* package */
final
RangedUri
initialization
;
/* package */
final
long
timescale
;
/* package */
final
long
presentationTimeOffset
;
/**
* @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}.
*/
public
SegmentBase
(
RangedUri
initialization
,
long
timescale
,
long
presentationTimeOffset
)
{
this
.
initialization
=
initialization
;
this
.
timescale
=
timescale
;
this
.
presentationTimeOffset
=
presentationTimeOffset
;
}
/**
* Gets the {@link RangedUri} defining the location of initialization data for a given
* representation. May be null if no initialization data exists.
*
* @param representation The {@link Representation} for which initialization data is required.
* @return A {@link RangedUri} defining the location of the initialization data, or null.
*/
public
RangedUri
getInitialization
(
Representation
representation
)
{
return
initialization
;
}
/**
* A {@link SegmentBase} that defines a single segment.
*/
public
static
class
SingleSegmentBase
extends
SegmentBase
{
/**
* The uri of the segment.
*/
public
final
Uri
uri
;
/* package */
final
long
indexStart
;
/* package */
final
long
indexLength
;
/**
* @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 uri The uri of the segment.
* @param indexStart The byte offset of the index data in the segment.
* @param indexLength The length of the index data in bytes.
*/
public
SingleSegmentBase
(
RangedUri
initialization
,
long
timescale
,
long
presentationTimeOffset
,
Uri
uri
,
long
indexStart
,
long
indexLength
)
{
super
(
initialization
,
timescale
,
presentationTimeOffset
);
this
.
uri
=
uri
;
this
.
indexStart
=
indexStart
;
this
.
indexLength
=
indexLength
;
}
public
RangedUri
getIndex
()
{
return
new
RangedUri
(
uri
,
null
,
indexStart
,
indexLength
);
}
}
/**
* A {@link SegmentBase} that consists of multiple segments.
*/
public
abstract
static
class
MultiSegmentBase
extends
SegmentBase
{
/* package */
final
long
periodDurationMs
;
/* package */
final
int
startNumber
;
/* package */
final
long
duration
;
/* package */
final
List
<
SegmentTimelineElement
>
segmentTimeline
;
/**
* @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 periodDurationMs The duration of the enclosing period in milliseconds.
* @param startNumber The sequence number of the first segment.
* @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
periodDurationMs
,
int
startNumber
,
long
duration
,
List
<
SegmentTimelineElement
>
segmentTimeline
)
{
super
(
initialization
,
timescale
,
presentationTimeOffset
);
this
.
periodDurationMs
=
periodDurationMs
;
this
.
startNumber
=
startNumber
;
this
.
duration
=
duration
;
this
.
segmentTimeline
=
segmentTimeline
;
}
public
final
int
getSegmentNum
(
long
timeUs
)
{
// TODO: Optimize this
int
index
=
startNumber
;
while
(
index
+
1
<=
getLastSegmentNum
())
{
if
(
getSegmentTimeUs
(
index
+
1
)
<=
timeUs
)
{
index
++;
}
else
{
return
index
;
}
}
return
index
;
}
public
final
long
getSegmentDurationUs
(
int
sequenceNumber
)
{
if
(
segmentTimeline
!=
null
)
{
return
(
segmentTimeline
.
get
(
sequenceNumber
-
startNumber
).
duration
*
1000000
)
/
timescale
;
}
else
{
return
sequenceNumber
==
getLastSegmentNum
()
?
(
periodDurationMs
*
1000
)
-
getSegmentTimeUs
(
sequenceNumber
)
:
((
duration
*
1000000L
)
/
timescale
);
}
}
public
final
long
getSegmentTimeUs
(
int
sequenceNumber
)
{
long
unscaledSegmentTime
;
if
(
segmentTimeline
!=
null
)
{
unscaledSegmentTime
=
segmentTimeline
.
get
(
sequenceNumber
-
startNumber
).
startTime
-
presentationTimeOffset
;
}
else
{
unscaledSegmentTime
=
(
sequenceNumber
-
startNumber
)
*
duration
;
}
return
(
unscaledSegmentTime
*
1000000
)
/
timescale
;
}
public
abstract
RangedUri
getSegmentUrl
(
Representation
representation
,
int
index
);
public
int
getFirstSegmentNum
()
{
return
startNumber
;
}
public
abstract
int
getLastSegmentNum
();
}
/**
* A {@link MultiSegmentBase} that uses a SegmentList to define its segments.
*/
public
static
class
SegmentList
extends
MultiSegmentBase
{
/* package */
final
List
<
RangedUri
>
mediaSegments
;
/**
* @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 periodDurationMs The duration of the enclosing period in milliseconds.
* @param startNumber The sequence number of the first segment.
* @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 mediaSegments A list of {@link RangedUri}s indicating the locations of the segments.
*/
public
SegmentList
(
RangedUri
initialization
,
long
timescale
,
long
presentationTimeOffset
,
long
periodDurationMs
,
int
startNumber
,
long
duration
,
List
<
SegmentTimelineElement
>
segmentTimeline
,
List
<
RangedUri
>
mediaSegments
)
{
super
(
initialization
,
timescale
,
presentationTimeOffset
,
periodDurationMs
,
startNumber
,
duration
,
segmentTimeline
);
this
.
mediaSegments
=
mediaSegments
;
}
@Override
public
RangedUri
getSegmentUrl
(
Representation
representation
,
int
sequenceNumber
)
{
return
mediaSegments
.
get
(
sequenceNumber
-
startNumber
);
}
@Override
public
int
getLastSegmentNum
()
{
return
startNumber
+
mediaSegments
.
size
()
-
1
;
}
}
/**
* A {@link MultiSegmentBase} that uses a SegmentTemplate to define its segments.
*/
public
static
class
SegmentTemplate
extends
MultiSegmentBase
{
/* package */
final
UrlTemplate
initializationTemplate
;
/* package */
final
UrlTemplate
mediaTemplate
;
private
final
Uri
baseUrl
;
/**
* @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 periodDurationMs The duration of the enclosing period in milliseconds.
* @param startNumber The sequence number of the first segment.
* @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.
* @param baseUrl A url to use as the base for relative urls generated by the templates.
*/
public
SegmentTemplate
(
RangedUri
initialization
,
long
timescale
,
long
presentationTimeOffset
,
long
periodDurationMs
,
int
startNumber
,
long
duration
,
List
<
SegmentTimelineElement
>
segmentTimeline
,
UrlTemplate
initializationTemplate
,
UrlTemplate
mediaTemplate
,
Uri
baseUrl
)
{
super
(
initialization
,
timescale
,
presentationTimeOffset
,
periodDurationMs
,
startNumber
,
duration
,
segmentTimeline
);
this
.
initializationTemplate
=
initializationTemplate
;
this
.
mediaTemplate
=
mediaTemplate
;
this
.
baseUrl
=
baseUrl
;
}
@Override
public
RangedUri
getInitialization
(
Representation
representation
)
{
if
(
initializationTemplate
!=
null
)
{
String
urlString
=
initializationTemplate
.
buildUri
(
representation
.
format
.
id
,
0
,
representation
.
format
.
bitrate
,
0
);
return
new
RangedUri
(
baseUrl
,
urlString
,
0
,
-
1
);
}
else
{
return
super
.
getInitialization
(
representation
);
}
}
@Override
public
RangedUri
getSegmentUrl
(
Representation
representation
,
int
sequenceNumber
)
{
long
time
=
0
;
if
(
segmentTimeline
!=
null
)
{
time
=
segmentTimeline
.
get
(
sequenceNumber
-
startNumber
).
startTime
;
}
else
{
time
=
(
sequenceNumber
-
startNumber
)
*
duration
;
}
String
uriString
=
mediaTemplate
.
buildUri
(
representation
.
format
.
id
,
sequenceNumber
,
representation
.
format
.
bitrate
,
time
);
return
new
RangedUri
(
baseUrl
,
uriString
,
0
,
-
1
);
}
@Override
public
int
getLastSegmentNum
()
{
if
(
segmentTimeline
!=
null
)
{
return
segmentTimeline
.
size
()
+
startNumber
-
1
;
}
else
{
long
durationMs
=
(
duration
*
1000
)
/
timescale
;
return
startNumber
+
(
int
)
(
periodDurationMs
/
durationMs
);
}
}
}
/**
* Represents a timeline segment from the MPD's SegmentTimeline list.
*/
public
static
class
SegmentTimelineElement
{
/* package */
long
startTime
;
/* package */
long
duration
;
/**
* @param startTime The start time of the element. The value in seconds is the division of this
* value and the {@code timescale} of the enclosing element.
* @param duration The duration of the element. The value in seconds is the division of this
* value and the {@code timescale} of the enclosing element.
*/
public
SegmentTimelineElement
(
long
startTime
,
long
duration
)
{
this
.
startTime
=
startTime
;
this
.
duration
=
duration
;
}
}
}
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