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
01a4cf98
authored
Oct 31, 2019
by
bachinger
Committed by
Oliver Woodman
Nov 05, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
add default methods isSingleWindow and getInitialTimeline to MediaSource interface
PiperOrigin-RevId: 277695826
parent
df251ad1
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
352 additions
and
25 deletions
library/core/src/main/java/com/google/android/exoplayer2/Timeline.java
library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java
library/core/src/main/java/com/google/android/exoplayer2/source/LoopingMediaSource.java
library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaSource.java
library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java
library/core/src/test/java/com/google/android/exoplayer2/TimelineTest.java
testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java
library/core/src/main/java/com/google/android/exoplayer2/Timeline.java
View file @
01a4cf98
...
...
@@ -19,6 +19,7 @@ import android.util.Pair;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.source.ads.AdPlaybackState
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Util
;
/**
* A flexible representation of the structure of media. A timeline is able to represent the
...
...
@@ -278,6 +279,48 @@ public abstract class Timeline {
return
positionInFirstPeriodUs
;
}
@Override
public
boolean
equals
(
@Nullable
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
!
getClass
().
equals
(
obj
.
getClass
()))
{
return
false
;
}
Window
that
=
(
Window
)
obj
;
return
Util
.
areEqual
(
uid
,
that
.
uid
)
&&
Util
.
areEqual
(
tag
,
that
.
tag
)
&&
Util
.
areEqual
(
manifest
,
that
.
manifest
)
&&
presentationStartTimeMs
==
that
.
presentationStartTimeMs
&&
windowStartTimeMs
==
that
.
windowStartTimeMs
&&
isSeekable
==
that
.
isSeekable
&&
isDynamic
==
that
.
isDynamic
&&
isLive
==
that
.
isLive
&&
defaultPositionUs
==
that
.
defaultPositionUs
&&
durationUs
==
that
.
durationUs
&&
firstPeriodIndex
==
that
.
firstPeriodIndex
&&
lastPeriodIndex
==
that
.
lastPeriodIndex
&&
positionInFirstPeriodUs
==
that
.
positionInFirstPeriodUs
;
}
@Override
public
int
hashCode
()
{
int
result
=
7
;
result
=
31
*
result
+
uid
.
hashCode
();
result
=
31
*
result
+
(
tag
==
null
?
0
:
tag
.
hashCode
());
result
=
31
*
result
+
(
manifest
==
null
?
0
:
manifest
.
hashCode
());
result
=
31
*
result
+
(
int
)
(
presentationStartTimeMs
^
(
presentationStartTimeMs
>>>
32
));
result
=
31
*
result
+
(
int
)
(
windowStartTimeMs
^
(
windowStartTimeMs
>>>
32
));
result
=
31
*
result
+
(
isSeekable
?
1
:
0
);
result
=
31
*
result
+
(
isDynamic
?
1
:
0
);
result
=
31
*
result
+
(
isLive
?
1
:
0
);
result
=
31
*
result
+
(
int
)
(
defaultPositionUs
^
(
defaultPositionUs
>>>
32
));
result
=
31
*
result
+
(
int
)
(
durationUs
^
(
durationUs
>>>
32
));
result
=
31
*
result
+
firstPeriodIndex
;
result
=
31
*
result
+
lastPeriodIndex
;
result
=
31
*
result
+
(
int
)
(
positionInFirstPeriodUs
^
(
positionInFirstPeriodUs
>>>
32
));
return
result
;
}
}
/**
...
...
@@ -534,6 +577,34 @@ public abstract class Timeline {
return
adPlaybackState
.
adResumePositionUs
;
}
@Override
public
boolean
equals
(
@Nullable
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
!
getClass
().
equals
(
obj
.
getClass
()))
{
return
false
;
}
Period
that
=
(
Period
)
obj
;
return
Util
.
areEqual
(
id
,
that
.
id
)
&&
Util
.
areEqual
(
uid
,
that
.
uid
)
&&
windowIndex
==
that
.
windowIndex
&&
durationUs
==
that
.
durationUs
&&
positionInWindowUs
==
that
.
positionInWindowUs
&&
Util
.
areEqual
(
adPlaybackState
,
that
.
adPlaybackState
);
}
@Override
public
int
hashCode
()
{
int
result
=
7
;
result
=
31
*
result
+
(
id
==
null
?
0
:
id
.
hashCode
());
result
=
31
*
result
+
(
uid
==
null
?
0
:
uid
.
hashCode
());
result
=
31
*
result
+
windowIndex
;
result
=
31
*
result
+
(
int
)
(
durationUs
^
(
durationUs
>>>
32
));
result
=
31
*
result
+
(
int
)
(
positionInWindowUs
^
(
positionInWindowUs
>>>
32
));
result
=
31
*
result
+
(
adPlaybackState
==
null
?
0
:
adPlaybackState
.
hashCode
());
return
result
;
}
}
/** An empty timeline. */
...
...
library/core/src/main/java/com/google/android/exoplayer2/source/ConcatenatingMediaSource.java
View file @
01a4cf98
...
...
@@ -139,6 +139,23 @@ public final class ConcatenatingMediaSource extends CompositeMediaSource<MediaSo
addMediaSources
(
Arrays
.
asList
(
mediaSources
));
}
@Override
public
synchronized
Timeline
getInitialTimeline
()
{
ShuffleOrder
shuffleOrder
=
this
.
shuffleOrder
.
getLength
()
!=
mediaSourcesPublic
.
size
()
?
this
.
shuffleOrder
.
cloneAndClear
()
.
cloneAndInsert
(
/* insertionIndex= */
0
,
/* insertionCount= */
mediaSourcesPublic
.
size
())
:
this
.
shuffleOrder
;
return
new
ConcatenatedTimeline
(
mediaSourcesPublic
,
shuffleOrder
,
isAtomic
);
}
@Override
public
boolean
isSingleWindow
()
{
return
false
;
}
/**
* Appends a {@link MediaSource} to the playlist.
*
...
...
library/core/src/main/java/com/google/android/exoplayer2/source/LoopingMediaSource.java
View file @
01a4cf98
...
...
@@ -35,7 +35,7 @@ import java.util.Map;
*/
public
final
class
LoopingMediaSource
extends
CompositeMediaSource
<
Void
>
{
private
final
M
ediaSource
child
Source
;
private
final
M
askingMediaSource
maskingMedia
Source
;
private
final
int
loopCount
;
private
final
Map
<
MediaPeriodId
,
MediaPeriodId
>
childMediaPeriodIdToMediaPeriodId
;
private
final
Map
<
MediaPeriod
,
MediaPeriodId
>
mediaPeriodToChildMediaPeriodId
;
...
...
@@ -58,7 +58,7 @@ public final class LoopingMediaSource extends CompositeMediaSource<Void> {
*/
public
LoopingMediaSource
(
MediaSource
childSource
,
int
loopCount
)
{
Assertions
.
checkArgument
(
loopCount
>
0
);
this
.
childSource
=
childSource
;
this
.
maskingMediaSource
=
new
MaskingMediaSource
(
childSource
,
/* useLazyPreparation= */
false
)
;
this
.
loopCount
=
loopCount
;
childMediaPeriodIdToMediaPeriodId
=
new
HashMap
<>();
mediaPeriodToChildMediaPeriodId
=
new
HashMap
<>();
...
...
@@ -67,32 +67,45 @@ public final class LoopingMediaSource extends CompositeMediaSource<Void> {
@Override
@Nullable
public
Object
getTag
()
{
return
childSource
.
getTag
();
return
maskingMediaSource
.
getTag
();
}
@Nullable
@Override
public
Timeline
getInitialTimeline
()
{
return
loopCount
!=
Integer
.
MAX_VALUE
?
new
LoopingTimeline
(
maskingMediaSource
.
getTimeline
(),
loopCount
)
:
new
InfinitelyLoopingTimeline
(
maskingMediaSource
.
getTimeline
());
}
@Override
public
boolean
isSingleWindow
()
{
return
false
;
}
@Override
protected
void
prepareSourceInternal
(
@Nullable
TransferListener
mediaTransferListener
)
{
super
.
prepareSourceInternal
(
mediaTransferListener
);
prepareChildSource
(
/* id= */
null
,
child
Source
);
prepareChildSource
(
/* id= */
null
,
maskingMedia
Source
);
}
@Override
public
MediaPeriod
createPeriod
(
MediaPeriodId
id
,
Allocator
allocator
,
long
startPositionUs
)
{
if
(
loopCount
==
Integer
.
MAX_VALUE
)
{
return
child
Source
.
createPeriod
(
id
,
allocator
,
startPositionUs
);
return
maskingMedia
Source
.
createPeriod
(
id
,
allocator
,
startPositionUs
);
}
Object
childPeriodUid
=
LoopingTimeline
.
getChildPeriodUidFromConcatenatedUid
(
id
.
periodUid
);
MediaPeriodId
childMediaPeriodId
=
id
.
copyWithPeriodUid
(
childPeriodUid
);
childMediaPeriodIdToMediaPeriodId
.
put
(
childMediaPeriodId
,
id
);
MediaPeriod
mediaPeriod
=
child
Source
.
createPeriod
(
childMediaPeriodId
,
allocator
,
startPositionUs
);
maskingMedia
Source
.
createPeriod
(
childMediaPeriodId
,
allocator
,
startPositionUs
);
mediaPeriodToChildMediaPeriodId
.
put
(
mediaPeriod
,
childMediaPeriodId
);
return
mediaPeriod
;
}
@Override
public
void
releasePeriod
(
MediaPeriod
mediaPeriod
)
{
child
Source
.
releasePeriod
(
mediaPeriod
);
maskingMedia
Source
.
releasePeriod
(
mediaPeriod
);
MediaPeriodId
childMediaPeriodId
=
mediaPeriodToChildMediaPeriodId
.
remove
(
mediaPeriod
);
if
(
childMediaPeriodId
!=
null
)
{
childMediaPeriodIdToMediaPeriodId
.
remove
(
childMediaPeriodId
);
...
...
library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaSource.java
View file @
01a4cf98
...
...
@@ -43,6 +43,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
@Nullable
private
EventDispatcher
unpreparedMaskingMediaPeriodEventDispatcher
;
private
boolean
hasStartedPreparing
;
private
boolean
isPrepared
;
private
boolean
hasRealTimeline
;
/**
* Creates the masking media source.
...
...
@@ -54,14 +55,22 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
*/
public
MaskingMediaSource
(
MediaSource
mediaSource
,
boolean
useLazyPreparation
)
{
this
.
mediaSource
=
mediaSource
;
this
.
useLazyPreparation
=
useLazyPreparation
;
this
.
useLazyPreparation
=
useLazyPreparation
&&
mediaSource
.
isSingleWindow
()
;
window
=
new
Timeline
.
Window
();
period
=
new
Timeline
.
Period
();
timeline
=
MaskingTimeline
.
createWithDummyTimeline
(
mediaSource
.
getTag
());
Timeline
initialTimeline
=
mediaSource
.
getInitialTimeline
();
if
(
initialTimeline
!=
null
)
{
timeline
=
MaskingTimeline
.
createWithRealTimeline
(
initialTimeline
,
/* firstWindowUid= */
null
,
/* firstPeriodUid= */
null
);
hasRealTimeline
=
true
;
}
else
{
timeline
=
MaskingTimeline
.
createWithDummyTimeline
(
mediaSource
.
getTag
());
}
}
/** Returns the {@link Timeline}. */
public
Timeline
getTimeline
()
{
public
synchronized
Timeline
getTimeline
()
{
return
timeline
;
}
...
...
@@ -129,14 +138,16 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
}
@Override
protected
void
onChildSourceInfoRefreshed
(
protected
synchronized
void
onChildSourceInfoRefreshed
(
Void
id
,
MediaSource
mediaSource
,
Timeline
newTimeline
)
{
if
(
isPrepared
)
{
timeline
=
timeline
.
cloneWithUpdatedTimeline
(
newTimeline
);
}
else
if
(
newTimeline
.
isEmpty
())
{
timeline
=
MaskingTimeline
.
createWithRealTimeline
(
newTimeline
,
Window
.
SINGLE_WINDOW_UID
,
MaskingTimeline
.
DUMMY_EXTERNAL_PERIOD_UID
);
hasRealTimeline
?
timeline
.
cloneWithUpdatedTimeline
(
newTimeline
)
:
MaskingTimeline
.
createWithRealTimeline
(
newTimeline
,
Window
.
SINGLE_WINDOW_UID
,
MaskingTimeline
.
DUMMY_EXTERNAL_PERIOD_UID
);
}
else
{
// Determine first period and the start position.
// This will be:
...
...
@@ -164,7 +175,10 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
window
,
period
,
/* windowIndex= */
0
,
windowStartPositionUs
);
Object
periodUid
=
periodPosition
.
first
;
long
periodPositionUs
=
periodPosition
.
second
;
timeline
=
MaskingTimeline
.
createWithRealTimeline
(
newTimeline
,
windowUid
,
periodUid
);
timeline
=
hasRealTimeline
?
timeline
.
cloneWithUpdatedTimeline
(
newTimeline
)
:
MaskingTimeline
.
createWithRealTimeline
(
newTimeline
,
windowUid
,
periodUid
);
if
(
unpreparedMaskingMediaPeriod
!=
null
)
{
MaskingMediaPeriod
maskingPeriod
=
unpreparedMaskingMediaPeriod
;
maskingPeriod
.
overridePreparePositionUs
(
periodPositionUs
);
...
...
@@ -173,6 +187,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
maskingPeriod
.
createPeriod
(
idInSource
);
}
}
hasRealTimeline
=
true
;
isPrepared
=
true
;
refreshSourceInfo
(
this
.
timeline
);
}
...
...
@@ -193,13 +208,15 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
}
private
Object
getInternalPeriodUid
(
Object
externalPeriodUid
)
{
return
externalPeriodUid
.
equals
(
MaskingTimeline
.
DUMMY_EXTERNAL_PERIOD_UID
)
return
timeline
.
replacedInternalPeriodUid
!=
null
&&
externalPeriodUid
.
equals
(
MaskingTimeline
.
DUMMY_EXTERNAL_PERIOD_UID
)
?
timeline
.
replacedInternalPeriodUid
:
externalPeriodUid
;
}
private
Object
getExternalPeriodUid
(
Object
internalPeriodUid
)
{
return
timeline
.
replacedInternalPeriodUid
.
equals
(
internalPeriodUid
)
return
timeline
.
replacedInternalPeriodUid
!=
null
&&
timeline
.
replacedInternalPeriodUid
.
equals
(
internalPeriodUid
)
?
MaskingTimeline
.
DUMMY_EXTERNAL_PERIOD_UID
:
internalPeriodUid
;
}
...
...
@@ -212,8 +229,8 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
public
static
final
Object
DUMMY_EXTERNAL_PERIOD_UID
=
new
Object
();
private
final
Object
replacedInternalWindowUid
;
private
final
Object
replacedInternalPeriodUid
;
@Nullable
private
final
Object
replacedInternalWindowUid
;
@Nullable
private
final
Object
replacedInternalPeriodUid
;
/**
* Returns an instance with a dummy timeline using the provided window tag.
...
...
@@ -236,12 +253,14 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
* assigned {@link #DUMMY_EXTERNAL_PERIOD_UID}.
*/
public
static
MaskingTimeline
createWithRealTimeline
(
Timeline
timeline
,
Object
firstWindowUid
,
Object
firstPeriodUid
)
{
Timeline
timeline
,
@Nullable
Object
firstWindowUid
,
@Nullable
Object
firstPeriodUid
)
{
return
new
MaskingTimeline
(
timeline
,
firstWindowUid
,
firstPeriodUid
);
}
private
MaskingTimeline
(
Timeline
timeline
,
Object
replacedInternalWindowUid
,
Object
replacedInternalPeriodUid
)
{
Timeline
timeline
,
@Nullable
Object
replacedInternalWindowUid
,
@Nullable
Object
replacedInternalPeriodUid
)
{
super
(
timeline
);
this
.
replacedInternalWindowUid
=
replacedInternalWindowUid
;
this
.
replacedInternalPeriodUid
=
replacedInternalPeriodUid
;
...
...
@@ -273,7 +292,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
@Override
public
Period
getPeriod
(
int
periodIndex
,
Period
period
,
boolean
setIds
)
{
timeline
.
getPeriod
(
periodIndex
,
period
,
setIds
);
if
(
Util
.
areEqual
(
period
.
uid
,
replacedInternalPeriodUid
))
{
if
(
Util
.
areEqual
(
period
.
uid
,
replacedInternalPeriodUid
)
&&
setIds
)
{
period
.
uid
=
DUMMY_EXTERNAL_PERIOD_UID
;
}
return
period
;
...
...
@@ -282,7 +301,9 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
@Override
public
int
getIndexOfPeriod
(
Object
uid
)
{
return
timeline
.
getIndexOfPeriod
(
DUMMY_EXTERNAL_PERIOD_UID
.
equals
(
uid
)
?
replacedInternalPeriodUid
:
uid
);
DUMMY_EXTERNAL_PERIOD_UID
.
equals
(
uid
)
&&
replacedInternalPeriodUid
!=
null
?
replacedInternalPeriodUid
:
uid
);
}
@Override
...
...
@@ -333,8 +354,8 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
@Override
public
Period
getPeriod
(
int
periodIndex
,
Period
period
,
boolean
setIds
)
{
return
period
.
set
(
/* id= */
0
,
/* uid= */
MaskingTimeline
.
DUMMY_EXTERNAL_PERIOD_UID
,
/* id= */
setIds
?
0
:
null
,
/* uid= */
setIds
?
MaskingTimeline
.
DUMMY_EXTERNAL_PERIOD_UID
:
null
,
/* windowIndex= */
0
,
/* durationUs = */
C
.
TIME_UNSET
,
/* positionInWindowUs= */
0
);
...
...
library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java
View file @
01a4cf98
...
...
@@ -228,6 +228,33 @@ public interface MediaSource {
*/
void
removeEventListener
(
MediaSourceEventListener
eventListener
);
/**
* Returns the initial dummy timeline that is returned immediately when the real timeline is not
* yet known, or null to let the player create an initial timeline.
*
* <p>The initial timeline must use the same uids for windows and periods that the real timeline
* will use. It also must provide windows which are marked as dynamic to indicate that the window
* is expected to change when the real timeline arrives.
*
* <p>Any media source which has multiple windows should typically provide such an initial
* timeline to make sure the player reports the correct number of windows immediately.
*/
@Nullable
default
Timeline
getInitialTimeline
()
{
return
null
;
}
/**
* Returns true if the media source is guaranteed to never have zero or more than one window.
*
* <p>The default implementation returns {@code true}.
*
* @return true if the source has exactly one window.
*/
default
boolean
isSingleWindow
()
{
return
true
;
}
/** Returns the tag set on the media source, or null if none was set. */
@Nullable
default
Object
getTag
()
{
...
...
library/core/src/test/java/com/google/android/exoplayer2/TimelineTest.java
View file @
01a4cf98
...
...
@@ -15,6 +15,8 @@
*/
package
com
.
google
.
android
.
exoplayer2
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.testutil.FakeTimeline
;
import
com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition
;
...
...
@@ -58,4 +60,148 @@ public class TimelineTest {
TimelineAsserts
.
assertNextWindowIndices
(
timeline
,
Player
.
REPEAT_MODE_ONE
,
false
,
0
);
TimelineAsserts
.
assertNextWindowIndices
(
timeline
,
Player
.
REPEAT_MODE_ALL
,
false
,
0
);
}
@Test
public
void
testWindowEquals
()
{
Timeline
.
Window
window
=
new
Timeline
.
Window
();
assertThat
(
window
).
isEqualTo
(
new
Timeline
.
Window
());
Timeline
.
Window
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
tag
=
new
Object
();
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
manifest
=
new
Object
();
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
presentationStartTimeMs
=
C
.
TIME_UNSET
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
windowStartTimeMs
=
C
.
TIME_UNSET
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
isSeekable
=
true
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
isDynamic
=
true
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
isLive
=
true
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
defaultPositionUs
=
C
.
TIME_UNSET
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
durationUs
=
C
.
TIME_UNSET
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
firstPeriodIndex
=
1
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
lastPeriodIndex
=
1
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
otherWindow
=
new
Timeline
.
Window
();
otherWindow
.
positionInFirstPeriodUs
=
C
.
TIME_UNSET
;
assertThat
(
window
).
isNotEqualTo
(
otherWindow
);
window
.
uid
=
new
Object
();
window
.
tag
=
new
Object
();
window
.
manifest
=
new
Object
();
window
.
presentationStartTimeMs
=
C
.
TIME_UNSET
;
window
.
windowStartTimeMs
=
C
.
TIME_UNSET
;
window
.
isSeekable
=
true
;
window
.
isDynamic
=
true
;
window
.
isLive
=
true
;
window
.
defaultPositionUs
=
C
.
TIME_UNSET
;
window
.
durationUs
=
C
.
TIME_UNSET
;
window
.
firstPeriodIndex
=
1
;
window
.
lastPeriodIndex
=
1
;
window
.
positionInFirstPeriodUs
=
C
.
TIME_UNSET
;
otherWindow
=
otherWindow
.
set
(
window
.
uid
,
window
.
tag
,
window
.
manifest
,
window
.
presentationStartTimeMs
,
window
.
windowStartTimeMs
,
window
.
isSeekable
,
window
.
isDynamic
,
window
.
isLive
,
window
.
defaultPositionUs
,
window
.
durationUs
,
window
.
firstPeriodIndex
,
window
.
lastPeriodIndex
,
window
.
positionInFirstPeriodUs
);
assertThat
(
window
).
isEqualTo
(
otherWindow
);
}
@Test
public
void
testWindowHashCode
()
{
Timeline
.
Window
window
=
new
Timeline
.
Window
();
Timeline
.
Window
otherWindow
=
new
Timeline
.
Window
();
assertThat
(
window
.
hashCode
()).
isEqualTo
(
otherWindow
.
hashCode
());
window
.
tag
=
new
Object
();
assertThat
(
window
.
hashCode
()).
isNotEqualTo
(
otherWindow
.
hashCode
());
otherWindow
.
tag
=
window
.
tag
;
assertThat
(
window
.
hashCode
()).
isEqualTo
(
otherWindow
.
hashCode
());
}
@Test
public
void
testPeriodEquals
()
{
Timeline
.
Period
period
=
new
Timeline
.
Period
();
assertThat
(
period
).
isEqualTo
(
new
Timeline
.
Period
());
Timeline
.
Period
otherPeriod
=
new
Timeline
.
Period
();
otherPeriod
.
id
=
new
Object
();
assertThat
(
period
).
isNotEqualTo
(
otherPeriod
);
otherPeriod
=
new
Timeline
.
Period
();
otherPeriod
.
uid
=
new
Object
();
assertThat
(
period
).
isNotEqualTo
(
otherPeriod
);
otherPeriod
=
new
Timeline
.
Period
();
otherPeriod
.
windowIndex
=
12
;
assertThat
(
period
).
isNotEqualTo
(
otherPeriod
);
otherPeriod
=
new
Timeline
.
Period
();
otherPeriod
.
durationUs
=
11L
;
assertThat
(
period
).
isNotEqualTo
(
otherPeriod
);
otherPeriod
=
new
Timeline
.
Period
();
period
.
id
=
new
Object
();
period
.
uid
=
new
Object
();
period
.
windowIndex
=
1
;
period
.
durationUs
=
123L
;
otherPeriod
=
otherPeriod
.
set
(
period
.
id
,
period
.
uid
,
period
.
windowIndex
,
period
.
durationUs
,
/* positionInWindowUs= */
0
);
assertThat
(
period
).
isEqualTo
(
otherPeriod
);
}
@Test
public
void
testPeriodHashCode
()
{
Timeline
.
Period
period
=
new
Timeline
.
Period
();
Timeline
.
Period
otherPeriod
=
new
Timeline
.
Period
();
assertThat
(
period
.
hashCode
()).
isEqualTo
(
otherPeriod
.
hashCode
());
period
.
windowIndex
=
12
;
assertThat
(
period
.
hashCode
()).
isNotEqualTo
(
otherPeriod
.
hashCode
());
otherPeriod
.
windowIndex
=
period
.
windowIndex
;
assertThat
(
period
.
hashCode
()).
isEqualTo
(
otherPeriod
.
hashCode
());
}
}
testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java
View file @
01a4cf98
...
...
@@ -40,6 +40,7 @@ public final class FakeTimeline extends Timeline {
public
final
Object
id
;
public
final
boolean
isSeekable
;
public
final
boolean
isDynamic
;
public
final
boolean
isLive
;
public
final
long
durationUs
;
public
final
AdPlaybackState
adPlaybackState
;
...
...
@@ -99,10 +100,41 @@ public final class FakeTimeline extends Timeline {
boolean
isDynamic
,
long
durationUs
,
AdPlaybackState
adPlaybackState
)
{
this
(
periodCount
,
id
,
isSeekable
,
isDynamic
,
/* isLive= */
isDynamic
,
durationUs
,
adPlaybackState
);
}
/**
* Creates a window definition with ad groups.
*
* @param periodCount The number of periods in the window. Each period get an equal slice of the
* total window duration.
* @param id The UID of the window.
* @param isSeekable Whether the window is seekable.
* @param isDynamic Whether the window is dynamic.
* @param isLive Whether the window is live.
* @param durationUs The duration of the window in microseconds.
* @param adPlaybackState The ad playback state.
*/
public
TimelineWindowDefinition
(
int
periodCount
,
Object
id
,
boolean
isSeekable
,
boolean
isDynamic
,
boolean
isLive
,
long
durationUs
,
AdPlaybackState
adPlaybackState
)
{
this
.
periodCount
=
periodCount
;
this
.
id
=
id
;
this
.
isSeekable
=
isSeekable
;
this
.
isDynamic
=
isDynamic
;
this
.
isLive
=
isLive
;
this
.
durationUs
=
durationUs
;
this
.
adPlaybackState
=
adPlaybackState
;
}
...
...
@@ -189,7 +221,7 @@ public final class FakeTimeline extends Timeline {
/* windowStartTimeMs= */
C
.
TIME_UNSET
,
windowDefinition
.
isSeekable
,
windowDefinition
.
isDynamic
,
/* isLive= */
windowDefinition
.
isDynamic
,
windowDefinition
.
isLive
,
/* defaultPositionUs= */
0
,
windowDefinition
.
durationUs
,
periodOffsets
[
windowIndex
],
...
...
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