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
e4194fc8
authored
Apr 05, 2023
by
bachinger
Committed by
Marc Baechinger
Apr 05, 2023
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Make period durations of FakeMultiPeriodLiveTimeline configurable
PiperOrigin-RevId: 522046876
parent
5442c33a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
433 additions
and
172 deletions
libraries/common/src/test/java/androidx/media3/common/TimelineTest.java
libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MediaPeriodQueueTest.java
libraries/exoplayer_ima/src/test/java/androidx/media3/exoplayer/ima/ImaUtilTest.java
libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMultiPeriodLiveTimeline.java
libraries/test_utils/src/test/java/androidx/media3/test/utils/FakeMultiPeriodLiveTimelineTest.java
libraries/common/src/test/java/androidx/media3/common/TimelineTest.java
View file @
e4194fc8
...
@@ -15,6 +15,8 @@
...
@@ -15,6 +15,8 @@
*/
*/
package
androidx
.
media3
.
common
;
package
androidx
.
media3
.
common
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_MS
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_MS
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
android.os.Bundle
;
import
android.os.Bundle
;
...
@@ -436,10 +438,13 @@ public class TimelineTest {
...
@@ -436,10 +438,13 @@ public class TimelineTest {
public
void
periodIsLivePostrollPlaceholder_recognizesLivePostrollPlaceholder
()
{
public
void
periodIsLivePostrollPlaceholder_recognizesLivePostrollPlaceholder
()
{
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
60_000_000
,
/* liveWindowDurationUs= */
60_000_000
,
/* nowUs= */
60_000_000
,
/* nowUs= */
60_000_000
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
true
,
/* populateAds= */
true
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
...
libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MediaPeriodQueueTest.java
View file @
e4194fc8
...
@@ -15,8 +15,11 @@
...
@@ -15,8 +15,11 @@
*/
*/
package
androidx
.
media3
.
exoplayer
;
package
androidx
.
media3
.
exoplayer
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
msToUs
;
import
static
androidx
.
media3
.
test
.
utils
.
ExoPlayerTestRunner
.
AUDIO_FORMAT
;
import
static
androidx
.
media3
.
test
.
utils
.
ExoPlayerTestRunner
.
AUDIO_FORMAT
;
import
static
androidx
.
media3
.
test
.
utils
.
ExoPlayerTestRunner
.
VIDEO_FORMAT
;
import
static
androidx
.
media3
.
test
.
utils
.
ExoPlayerTestRunner
.
VIDEO_FORMAT
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_MS
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_MS
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeTimeline
.
TimelineWindowDefinition
.
DEFAULT_WINDOW_DURATION_US
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeTimeline
.
TimelineWindowDefinition
.
DEFAULT_WINDOW_DURATION_US
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeTimeline
.
TimelineWindowDefinition
.
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeTimeline
.
TimelineWindowDefinition
.
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
...
@@ -430,15 +433,18 @@ public final class MediaPeriodQueueTest {
...
@@ -430,15 +433,18 @@ public final class MediaPeriodQueueTest {
@Test
@Test
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
public
void
getNextMediaPeriodInfo_multiPeriodTimelineWithNoAdsAndNoPostrollPlaceholder
()
{
public
void
getNextMediaPeriodInfo_multiPeriodTimelineWithNoAdsAndNoPostrollPlaceholder
()
{
long
contentPeriodDurationUs
=
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_US
;
long
contentPeriodDurationUs
=
msToUs
(
PERIOD_DURATION_MS
)
;
long
adPeriodDurationUs
=
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_US
;
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
)
;
// Multi period timeline without ad playback state.
// Multi period timeline without ad playback state.
FakeMultiPeriodLiveTimeline
multiPeriodLiveTimeline
=
FakeMultiPeriodLiveTimeline
multiPeriodLiveTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
60_000_000
,
/* liveWindowDurationUs= */
60_000_000
,
/* nowUs= */
110_000_000
,
/* nowUs= */
110_000_000
,
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -497,15 +503,18 @@ public final class MediaPeriodQueueTest {
...
@@ -497,15 +503,18 @@ public final class MediaPeriodQueueTest {
@Test
@Test
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
public
void
getNextMediaPeriodInfo_multiPeriodTimelineWithPostrollPlaceHolder
()
{
public
void
getNextMediaPeriodInfo_multiPeriodTimelineWithPostrollPlaceHolder
()
{
long
contentPeriodDurationUs
=
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_US
;
long
contentPeriodDurationUs
=
msToUs
(
PERIOD_DURATION_MS
)
;
long
adPeriodDurationUs
=
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_US
;
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
)
;
// Multi period timeline without ad playback state.
// Multi period timeline without ad playback state.
FakeMultiPeriodLiveTimeline
multiPeriodLiveTimeline
=
FakeMultiPeriodLiveTimeline
multiPeriodLiveTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
60_000_000
,
/* liveWindowDurationUs= */
60_000_000
,
/* nowUs= */
110_000_000
,
/* nowUs= */
110_000_000
,
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -564,14 +573,17 @@ public final class MediaPeriodQueueTest {
...
@@ -564,14 +573,17 @@ public final class MediaPeriodQueueTest {
@Test
@Test
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
public
void
getNextMediaPeriodInfo_multiPeriodTimelineWithAdsAndWithPostRollPlaceHolder
()
{
public
void
getNextMediaPeriodInfo_multiPeriodTimelineWithAdsAndWithPostRollPlaceHolder
()
{
long
contentPeriodDurationUs
=
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_US
;
long
contentPeriodDurationUs
=
msToUs
(
PERIOD_DURATION_MS
)
;
long
adPeriodDurationUs
=
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_US
;
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
)
;
FakeMultiPeriodLiveTimeline
multiPeriodLiveTimeline
=
FakeMultiPeriodLiveTimeline
multiPeriodLiveTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
60_000_000
,
/* liveWindowDurationUs= */
60_000_000
,
/* nowUs= */
110_000_000
,
/* nowUs= */
110_000_000
,
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
true
,
/* populateAds= */
true
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -646,13 +658,16 @@ public final class MediaPeriodQueueTest {
...
@@ -646,13 +658,16 @@ public final class MediaPeriodQueueTest {
@Test
@Test
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
public
void
getNextMediaPeriodInfo_multiPeriodTimelineWithPlayedAdsAndWithPostRollPlaceHolder
()
{
public
void
getNextMediaPeriodInfo_multiPeriodTimelineWithPlayedAdsAndWithPostRollPlaceHolder
()
{
long
contentPeriodDurationUs
=
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_US
;
long
contentPeriodDurationUs
=
msToUs
(
PERIOD_DURATION_MS
)
;
FakeMultiPeriodLiveTimeline
multiPeriodLiveTimeline
=
FakeMultiPeriodLiveTimeline
multiPeriodLiveTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
60_000_000
,
/* liveWindowDurationUs= */
60_000_000
,
/* nowUs= */
110_000_000
,
/* nowUs= */
110_000_000
,
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
true
,
/* populateAds= */
true
,
/* playedAds= */
true
);
/* playedAds= */
true
);
...
...
libraries/exoplayer_ima/src/test/java/androidx/media3/exoplayer/ima/ImaUtilTest.java
View file @
e4194fc8
...
@@ -20,6 +20,7 @@ import static androidx.media3.common.AdPlaybackState.AD_STATE_ERROR;
...
@@ -20,6 +20,7 @@ import static androidx.media3.common.AdPlaybackState.AD_STATE_ERROR;
import
static
androidx
.
media3
.
common
.
AdPlaybackState
.
AD_STATE_PLAYED
;
import
static
androidx
.
media3
.
common
.
AdPlaybackState
.
AD_STATE_PLAYED
;
import
static
androidx
.
media3
.
common
.
AdPlaybackState
.
AD_STATE_SKIPPED
;
import
static
androidx
.
media3
.
common
.
AdPlaybackState
.
AD_STATE_SKIPPED
;
import
static
androidx
.
media3
.
common
.
AdPlaybackState
.
AD_STATE_UNAVAILABLE
;
import
static
androidx
.
media3
.
common
.
AdPlaybackState
.
AD_STATE_UNAVAILABLE
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
msToUs
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
addLiveAdBreak
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
addLiveAdBreak
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
getAdGroupAndIndexInLiveMultiPeriodTimeline
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
getAdGroupAndIndexInLiveMultiPeriodTimeline
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
getAdGroupAndIndexInVodMultiPeriodTimeline
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
getAdGroupAndIndexInVodMultiPeriodTimeline
;
...
@@ -28,7 +29,8 @@ import static androidx.media3.exoplayer.ima.ImaUtil.maybeCorrectPreviouslyUnknow
...
@@ -28,7 +29,8 @@ import static androidx.media3.exoplayer.ima.ImaUtil.maybeCorrectPreviouslyUnknow
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
secToUsRounded
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
secToUsRounded
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
splitAdGroup
;
import
static
androidx
.
media3
.
exoplayer
.
ima
.
ImaUtil
.
splitAdGroup
;
import
static
androidx
.
media3
.
exoplayer
.
source
.
ads
.
ServerSideAdInsertionUtil
.
addAdGroupToAdPlaybackState
;
import
static
androidx
.
media3
.
exoplayer
.
source
.
ads
.
ServerSideAdInsertionUtil
.
addAdGroupToAdPlaybackState
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_US
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_MS
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_MS
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeTimeline
.
TimelineWindowDefinition
.
DEFAULT_WINDOW_DURATION_US
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeTimeline
.
TimelineWindowDefinition
.
DEFAULT_WINDOW_DURATION_US
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeTimeline
.
TimelineWindowDefinition
.
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeTimeline
.
TimelineWindowDefinition
.
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
...
@@ -560,7 +562,7 @@ public class ImaUtilTest {
...
@@ -560,7 +562,7 @@ public class ImaUtilTest {
@Test
@Test
public
void
public
void
splitAdPlaybackStateForPeriods_liveAdGroupStartedAndMovedOutOfWindow_splitCorrectly
()
{
splitAdPlaybackStateForPeriods_liveAdGroupStartedAndMovedOutOfWindow_splitCorrectly
()
{
long
adPeriodDurationUs
=
AD_PERIOD_DURATION_US
;
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
)
;
AdPlaybackState
adPlaybackState
=
AdPlaybackState
adPlaybackState
=
new
AdPlaybackState
(
/* adsId= */
"adsId"
,
C
.
TIME_END_OF_SOURCE
)
new
AdPlaybackState
(
/* adsId= */
"adsId"
,
C
.
TIME_END_OF_SOURCE
)
.
withIsServerSideInserted
(
/* adGroupIndex= */
0
,
true
);
.
withIsServerSideInserted
(
/* adGroupIndex= */
0
,
true
);
...
@@ -568,10 +570,13 @@ public class ImaUtilTest {
...
@@ -568,10 +570,13 @@ public class ImaUtilTest {
// Period durations: content=30_000_000, ad=10_000_000
// Period durations: content=30_000_000, ad=10_000_000
FakeMultiPeriodLiveTimeline
liveTimeline
=
FakeMultiPeriodLiveTimeline
liveTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
100_000_000
,
/* liveWindowDurationUs= */
100_000_000
,
/* nowUs= */
150_000_000
,
/* nowUs= */
150_000_000
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -851,6 +856,7 @@ public class ImaUtilTest {
...
@@ -851,6 +856,7 @@ public class ImaUtilTest {
@Test
@Test
public
void
public
void
splitAdPlaybackStateForPeriods_fullAdGroupAtBeginOfWindow_adPeriodsCorrectlyDetected
()
{
splitAdPlaybackStateForPeriods_fullAdGroupAtBeginOfWindow_adPeriodsCorrectlyDetected
()
{
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
AdPlaybackState
adPlaybackState
=
AdPlaybackState
adPlaybackState
=
new
AdPlaybackState
(
/* adsId= */
"adsId"
,
C
.
TIME_END_OF_SOURCE
)
new
AdPlaybackState
(
/* adsId= */
"adsId"
,
C
.
TIME_END_OF_SOURCE
)
.
withIsServerSideInserted
(
/* adGroupIndex= */
0
,
true
);
.
withIsServerSideInserted
(
/* adGroupIndex= */
0
,
true
);
...
@@ -858,10 +864,13 @@ public class ImaUtilTest {
...
@@ -858,10 +864,13 @@ public class ImaUtilTest {
// Period durations: content=30_000_000, ad=10_000_000
// Period durations: content=30_000_000, ad=10_000_000
FakeMultiPeriodLiveTimeline
liveTimeline
=
FakeMultiPeriodLiveTimeline
liveTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
30_000_000
,
/* liveWindowDurationUs= */
30_000_000
,
/* nowUs= */
59_999_999
,
/* nowUs= */
59_999_999
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -869,9 +878,9 @@ public class ImaUtilTest {
...
@@ -869,9 +878,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
30_000_000
,
/* currentContentPeriodPositionUs= */
30_000_000
,
AD_PERIOD_DURATION_US
,
adPeriodDurationUs
,
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
2
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
2
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
2
,
/* totalAdsInAdPod= */
2
,
adPlaybackState
);
adPlaybackState
);
...
@@ -968,9 +977,9 @@ public class ImaUtilTest {
...
@@ -968,9 +977,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
80_000_000
,
/* currentContentPeriodPositionUs= */
80_000_000
,
AD_PERIOD_DURATION_US
-
1000L
,
// SDK fallback duration.
adPeriodDurationUs
-
1000L
,
// SDK fallback duration.
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
2
*
AD_PERIOD_DURATION_US
-
1001L
,
/* totalAdDurationUs= */
2
*
adPeriodDurationUs
-
1001L
,
/* totalAdsInAdPod= */
2
,
/* totalAdsInAdPod= */
2
,
adPlaybackState
);
adPlaybackState
);
splitAdPlaybackStates
=
ImaUtil
.
splitAdPlaybackStateForPeriods
(
adPlaybackState
,
liveTimeline
);
splitAdPlaybackStates
=
ImaUtil
.
splitAdPlaybackStateForPeriods
(
adPlaybackState
,
liveTimeline
);
...
@@ -984,7 +993,7 @@ public class ImaUtilTest {
...
@@ -984,7 +993,7 @@ public class ImaUtilTest {
AdPlaybackState
.
AdGroup
actualAdGroup
=
AdPlaybackState
.
AdGroup
actualAdGroup
=
splitAdPlaybackStates
.
get
(
"uid-4[a]"
).
getAdGroup
(
/* adGroupIndex= */
0
);
splitAdPlaybackStates
.
get
(
"uid-4[a]"
).
getAdGroup
(
/* adGroupIndex= */
0
);
assertThat
(
actualAdGroup
.
count
).
isEqualTo
(
1
);
assertThat
(
actualAdGroup
.
count
).
isEqualTo
(
1
);
assertThat
(
actualAdGroup
.
durationsUs
[
0
]).
isEqualTo
(
AD_PERIOD_DURATION_US
-
1000L
);
assertThat
(
actualAdGroup
.
durationsUs
[
0
]).
isEqualTo
(
adPeriodDurationUs
-
1000L
);
// Advance to make the window overlap 1 microsecond into the second ad period. Assert whether
// Advance to make the window overlap 1 microsecond into the second ad period. Assert whether
// both ad periods, including the last with unknown duration, are correctly marked as ad.
// both ad periods, including the last with unknown duration, are correctly marked as ad.
...
@@ -999,11 +1008,11 @@ public class ImaUtilTest {
...
@@ -999,11 +1008,11 @@ public class ImaUtilTest {
assertThat
(
splitAdPlaybackStates
.
get
(
"uid-4[a]"
).
adGroupCount
).
isEqualTo
(
2
);
assertThat
(
splitAdPlaybackStates
.
get
(
"uid-4[a]"
).
adGroupCount
).
isEqualTo
(
2
);
actualAdGroup
=
splitAdPlaybackStates
.
get
(
"uid-4[a]"
).
getAdGroup
(
/* adGroupIndex= */
0
);
actualAdGroup
=
splitAdPlaybackStates
.
get
(
"uid-4[a]"
).
getAdGroup
(
/* adGroupIndex= */
0
);
assertThat
(
actualAdGroup
.
count
).
isEqualTo
(
1
);
assertThat
(
actualAdGroup
.
count
).
isEqualTo
(
1
);
assertThat
(
actualAdGroup
.
durationsUs
[
0
]).
isEqualTo
(
AD_PERIOD_DURATION_US
);
assertThat
(
actualAdGroup
.
durationsUs
[
0
]).
isEqualTo
(
adPeriodDurationUs
);
assertThat
(
splitAdPlaybackStates
.
get
(
"uid-5[a]"
).
adGroupCount
).
isEqualTo
(
2
);
assertThat
(
splitAdPlaybackStates
.
get
(
"uid-5[a]"
).
adGroupCount
).
isEqualTo
(
2
);
actualAdGroup
=
splitAdPlaybackStates
.
get
(
"uid-5[a]"
).
getAdGroup
(
/* adGroupIndex= */
0
);
actualAdGroup
=
splitAdPlaybackStates
.
get
(
"uid-5[a]"
).
getAdGroup
(
/* adGroupIndex= */
0
);
assertThat
(
actualAdGroup
.
count
).
isEqualTo
(
1
);
assertThat
(
actualAdGroup
.
count
).
isEqualTo
(
1
);
assertThat
(
actualAdGroup
.
durationsUs
[
0
]).
isEqualTo
(
AD_PERIOD_DURATION_US
-
1L
);
// SDK fallback.
assertThat
(
actualAdGroup
.
durationsUs
[
0
]).
isEqualTo
(
adPeriodDurationUs
-
1L
);
// SDK fallback.
}
}
@Test
@Test
...
@@ -1033,6 +1042,7 @@ public class ImaUtilTest {
...
@@ -1033,6 +1042,7 @@ public class ImaUtilTest {
@Test
@Test
public
void
maybeCorrectPreviouslyUnknownAdDuration_singleAdInAdGroup_adDurationCorrected
()
{
public
void
maybeCorrectPreviouslyUnknownAdDuration_singleAdInAdGroup_adDurationCorrected
()
{
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
long
liveWindowDurationUs
=
60_000_000L
;
long
liveWindowDurationUs
=
60_000_000L
;
long
nowUs
=
110_234_567L
;
long
nowUs
=
110_234_567L
;
AdPlaybackState
adPlaybackState
=
AdPlaybackState
adPlaybackState
=
...
@@ -1053,10 +1063,13 @@ public class ImaUtilTest {
...
@@ -1053,10 +1063,13 @@ public class ImaUtilTest {
/* adDurationsUs...= */
123
);
/* adDurationsUs...= */
123
);
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
liveWindowDurationUs
,
liveWindowDurationUs
,
nowUs
,
nowUs
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1070,13 +1083,14 @@ public class ImaUtilTest {
...
@@ -1070,13 +1083,14 @@ public class ImaUtilTest {
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
1
).
timeUs
).
isEqualTo
(
90_000_000L
);
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
1
).
timeUs
).
isEqualTo
(
90_000_000L
);
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
1
).
durationsUs
)
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
1
).
durationsUs
)
.
asList
()
.
asList
()
.
containsExactly
(
AD_PERIOD_DURATION_US
);
.
containsExactly
(
adPeriodDurationUs
);
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
1
).
contentResumeOffsetUs
)
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
1
).
contentResumeOffsetUs
)
.
isEqualTo
(
AD_PERIOD_DURATION_US
);
.
isEqualTo
(
adPeriodDurationUs
);
}
}
@Test
@Test
public
void
maybeCorrectPreviouslyUnknownAdDuration_multipleAdsInAdGroup_adDurationCorrected
()
{
public
void
maybeCorrectPreviouslyUnknownAdDuration_multipleAdsInAdGroup_adDurationCorrected
()
{
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
long
liveWindowDurationUs
=
60_000_000L
;
long
liveWindowDurationUs
=
60_000_000L
;
long
nowUs
=
110_234_567L
;
long
nowUs
=
110_234_567L
;
AdPlaybackState
adPlaybackState
=
AdPlaybackState
adPlaybackState
=
...
@@ -1086,15 +1100,18 @@ public class ImaUtilTest {
...
@@ -1086,15 +1100,18 @@ public class ImaUtilTest {
adPlaybackState
,
adPlaybackState
,
/* fromPositionUs= */
80_000_000L
,
/* fromPositionUs= */
80_000_000L
,
/* contentResumeOffsetUs= */
10_000_123L
,
/* contentResumeOffsetUs= */
10_000_123L
,
/* adDurationsUs...= */
AD_PERIOD_DURATION_US
,
/* adDurationsUs...= */
adPeriodDurationUs
,
123L
);
123L
);
// Content timeline: [content, ad, ad, content]
// Content timeline: [content, ad, ad, content]
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
liveWindowDurationUs
,
liveWindowDurationUs
,
nowUs
,
nowUs
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1104,9 +1121,9 @@ public class ImaUtilTest {
...
@@ -1104,9 +1121,9 @@ public class ImaUtilTest {
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
0
).
timeUs
).
isEqualTo
(
80_000_000L
);
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
0
).
timeUs
).
isEqualTo
(
80_000_000L
);
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
0
).
durationsUs
)
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
0
).
durationsUs
)
.
asList
()
.
asList
()
.
containsExactly
(
AD_PERIOD_DURATION_US
,
AD_PERIOD_DURATION_US
);
.
containsExactly
(
adPeriodDurationUs
,
adPeriodDurationUs
);
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
0
).
contentResumeOffsetUs
)
assertThat
(
adPlaybackState
.
getAdGroup
(
/* adGroupIndex= */
0
).
contentResumeOffsetUs
)
.
isEqualTo
(
2
*
AD_PERIOD_DURATION_US
);
.
isEqualTo
(
2
*
adPeriodDurationUs
);
}
}
@Test
@Test
...
@@ -1128,10 +1145,13 @@ public class ImaUtilTest {
...
@@ -1128,10 +1145,13 @@ public class ImaUtilTest {
/* adDurationsUs...= */
123
);
/* adDurationsUs...= */
123
);
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
60_000_000L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* nowUs= */
160_000_000L
,
/* nowUs= */
160_000_000L
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1150,10 +1170,17 @@ public class ImaUtilTest {
...
@@ -1150,10 +1170,17 @@ public class ImaUtilTest {
// Content and ad period in window at the beginning: [c, a, a]
// Content and ad period in window at the beginning: [c, a, a]
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
50_000_000L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* nowUs= */
50_000_000L
,
/* nowUs= */
50_000_000L
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1271,14 +1298,16 @@ public class ImaUtilTest {
...
@@ -1271,14 +1298,16 @@ public class ImaUtilTest {
}
}
@Test
@Test
public
void
public
void
maybeCorrectPreviouslyUnknownAdDuration_singleContentPeriodTimeline_doNothing
()
{
maybeCorrectPreviouslyUnknownAdDuration_singleContentPeriodTimeline_adPlaybackStateNotChanged
()
{
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
30_000_000L
,
/* liveWindowDurationUs= */
30_000_000L
,
/* nowUs= */
80_000_000L
,
/* nowUs= */
80_000_000L
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1308,10 +1337,13 @@ public class ImaUtilTest {
...
@@ -1308,10 +1337,13 @@ public class ImaUtilTest {
maybeCorrectPreviouslyUnknownAdDuration_singleAdPeriodTimeline_doesNotOverrideWithTimeUnset
()
{
maybeCorrectPreviouslyUnknownAdDuration_singleAdPeriodTimeline_doesNotOverrideWithTimeUnset
()
{
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
10_000_000L
,
/* liveWindowDurationUs= */
10_000_000L
,
/* nowUs= */
90_000_000L
,
/* nowUs= */
90_000_000L
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1608,13 +1640,20 @@ public class ImaUtilTest {
...
@@ -1608,13 +1640,20 @@ public class ImaUtilTest {
@Test
@Test
public
void
public
void
getAdGroupAndIndexInLiveMultiPeriodTimeline_calledForPeriodsAfterUnplayedAdGroup_correctAdGroupIndexAndAdIndexInAdGroup
()
{
getAdGroupAndIndexInLiveMultiPeriodTimeline_calledForPeriodsAfterUnplayedAdGroup_correctAdGroupIndexAndAdIndexInAdGroup
()
{
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
// Content live window with content and ad periods: c, [a, c, a, a, a, c, a], a, a
// Content live window with content and ad periods: c, [a, c, a, a, a, c, a], a, a
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
100_000_000
,
/* liveWindowDurationUs= */
100_000_000
,
/* nowUs= */
159_000_123
,
/* nowUs= */
159_000_123
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1623,9 +1662,9 @@ public class ImaUtilTest {
...
@@ -1623,9 +1662,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
50_000_000
,
/* currentContentPeriodPositionUs= */
50_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
adPeriodDurationUs
,
/* totalAdsInAdPod= */
1
,
/* totalAdsInAdPod= */
1
,
adPlaybackState
);
adPlaybackState
);
...
@@ -1642,25 +1681,25 @@ public class ImaUtilTest {
...
@@ -1642,25 +1681,25 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
90_000_000
,
/* currentContentPeriodPositionUs= */
90_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
100_000_000
,
/* currentContentPeriodPositionUs= */
100_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
2
,
/* adPositionInAdPod= */
2
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
110_000_000
,
/* currentContentPeriodPositionUs= */
110_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
3
,
/* adPositionInAdPod= */
3
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
...
@@ -1699,9 +1738,9 @@ public class ImaUtilTest {
...
@@ -1699,9 +1738,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
150_000_000
,
/* currentContentPeriodPositionUs= */
150_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
2
,
/* adPositionInAdPod= */
2
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
...
@@ -1717,13 +1756,20 @@ public class ImaUtilTest {
...
@@ -1717,13 +1756,20 @@ public class ImaUtilTest {
@Test
@Test
public
void
public
void
getAdGroupAndIndexInLiveMultiPeriodTimeline_calledForPeriodsBeforeUnplayedAdGroup_throwsWhenCalledForNonAdPeriods
()
{
getAdGroupAndIndexInLiveMultiPeriodTimeline_calledForPeriodsBeforeUnplayedAdGroup_throwsWhenCalledForNonAdPeriods
()
{
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
// Content live window with content and ad periods: c, [a, c, a, a, a, c, a], a, a
// Content live window with content and ad periods: c, [a, c, a, a, a, c, a], a, a
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
100_000_000
,
/* liveWindowDurationUs= */
100_000_000
,
/* nowUs= */
159_000_123
,
/* nowUs= */
159_000_123
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1732,9 +1778,9 @@ public class ImaUtilTest {
...
@@ -1732,9 +1778,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
50_000_000
,
/* currentContentPeriodPositionUs= */
50_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
adPeriodDurationUs
,
/* totalAdsInAdPod= */
1
,
/* totalAdsInAdPod= */
1
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
...
@@ -1742,25 +1788,25 @@ public class ImaUtilTest {
...
@@ -1742,25 +1788,25 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
90_000_000
,
/* currentContentPeriodPositionUs= */
90_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
100_000_000
,
/* currentContentPeriodPositionUs= */
100_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
2
,
/* adPositionInAdPod= */
2
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
110_000_000
,
/* currentContentPeriodPositionUs= */
110_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
3
,
/* adPositionInAdPod= */
3
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
AdPlaybackState
finalAdPlaybackState
=
adPlaybackState
;
AdPlaybackState
finalAdPlaybackState
=
adPlaybackState
;
...
@@ -1783,9 +1829,9 @@ public class ImaUtilTest {
...
@@ -1783,9 +1829,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
150_000_000
,
/* currentContentPeriodPositionUs= */
150_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
2
,
/* adPositionInAdPod= */
2
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
AdPlaybackState
anotherFinalAdPlaybackState
=
adPlaybackState
;
AdPlaybackState
anotherFinalAdPlaybackState
=
adPlaybackState
;
...
@@ -1803,13 +1849,20 @@ public class ImaUtilTest {
...
@@ -1803,13 +1849,20 @@ public class ImaUtilTest {
@Test
@Test
public
void
public
void
getAdGroupAndIndexInLiveMultiPeriodTimeline_partialAdGroupAtTimelineStart_correctAdGroupIndexAndAdIndexInAdGroup
()
{
getAdGroupAndIndexInLiveMultiPeriodTimeline_partialAdGroupAtTimelineStart_correctAdGroupIndexAndAdIndexInAdGroup
()
{
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
// Content timeline with content and ad periods: c, a, a, [a, c, a, a, a, c]
// Content timeline with content and ad periods: c, a, a, [a, c, a, a, a, c]
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
100_000_000
,
/* liveWindowDurationUs= */
100_000_000
,
/* nowUs= */
151_000_123
,
/* nowUs= */
151_000_123
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1818,25 +1871,25 @@ public class ImaUtilTest {
...
@@ -1818,25 +1871,25 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
30_000_000
,
/* currentContentPeriodPositionUs= */
30_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
40_000_000
,
/* currentContentPeriodPositionUs= */
40_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
2
,
/* adPositionInAdPod= */
2
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
50_000_000
,
/* currentContentPeriodPositionUs= */
50_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
3
,
/* adPositionInAdPod= */
3
,
/* totalAdDurationUs= */
3
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
3
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
3
,
/* totalAdsInAdPod= */
3
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
...
@@ -1856,14 +1909,24 @@ public class ImaUtilTest {
...
@@ -1856,14 +1909,24 @@ public class ImaUtilTest {
@Test
@Test
public
void
public
void
getAdGroupAndIndexInLiveMultiPeriodTimeline_onlyPartialAdGroupInWindow_correctAdGroupIndexAndAdIndexInAdGroup
()
{
getAdGroupAndIndexInLiveMultiPeriodTimeline_onlyPartialAdGroupInWindow_correctAdGroupIndexAndAdIndexInAdGroup
()
{
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
// Content timeline with content and ad periods: c, a, [a, a, a, a], a, c
// Content timeline with content and ad periods: c, a, [a, a, a, a], a, c
// First three ad periods of the ad group already outside of the live window.
// First three ad periods of the ad group already outside of the live window.
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
30_000_000
,
/* liveWindowDurationUs= */
30_000_000
,
/* nowUs= */
71_000_123
,
/* nowUs= */
71_000_123
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
,
true
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
,
true
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1873,9 +1936,9 @@ public class ImaUtilTest {
...
@@ -1873,9 +1936,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
30_000_000
,
/* currentContentPeriodPositionUs= */
30_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
6
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
6
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
6
,
/* totalAdsInAdPod= */
6
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
...
@@ -1883,9 +1946,9 @@ public class ImaUtilTest {
...
@@ -1883,9 +1946,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
40_000_000
,
/* currentContentPeriodPositionUs= */
40_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
2
,
/* adPositionInAdPod= */
2
,
/* totalAdDurationUs= */
6
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
6
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
6
,
/* totalAdsInAdPod= */
6
,
adPlaybackState
);
adPlaybackState
);
...
@@ -1903,9 +1966,9 @@ public class ImaUtilTest {
...
@@ -1903,9 +1966,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
50_000_000
,
/* currentContentPeriodPositionUs= */
50_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
3
,
/* adPositionInAdPod= */
3
,
/* totalAdDurationUs= */
6
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
6
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
6
,
/* totalAdsInAdPod= */
6
,
adPlaybackState
);
adPlaybackState
);
...
@@ -1941,13 +2004,23 @@ public class ImaUtilTest {
...
@@ -1941,13 +2004,23 @@ public class ImaUtilTest {
@Test
@Test
public
void
handleAdPeriodRemovedFromTimeline_removalCorrectlyHandled
()
{
public
void
handleAdPeriodRemovedFromTimeline_removalCorrectlyHandled
()
{
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
// Content timeline with content and ad periods: a,[c, a, a, a, a, a, a, c], a
// Content timeline with content and ad periods: a,[c, a, a, a, a, a, a, c], a
FakeMultiPeriodLiveTimeline
contentTimeline
=
FakeMultiPeriodLiveTimeline
contentTimeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
70_000_123
,
/* liveWindowDurationUs= */
70_000_123
,
/* nowUs= */
189_453_123
,
/* nowUs= */
189_453_123
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
,
true
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
,
true
,
true
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
true
,
/* populateAds= */
true
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -1957,9 +2030,9 @@ public class ImaUtilTest {
...
@@ -1957,9 +2030,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
120_000_000
,
/* currentContentPeriodPositionUs= */
120_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
1
,
/* adPositionInAdPod= */
1
,
/* totalAdDurationUs= */
6
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
6
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
6
,
/* totalAdsInAdPod= */
6
,
adPlaybackState
);
adPlaybackState
);
adPlaybackState
=
adPlaybackState
=
...
@@ -1967,9 +2040,9 @@ public class ImaUtilTest {
...
@@ -1967,9 +2040,9 @@ public class ImaUtilTest {
adPlaybackState
=
adPlaybackState
=
addLiveAdBreak
(
addLiveAdBreak
(
/* currentContentPeriodPositionUs= */
130_000_000
,
/* currentContentPeriodPositionUs= */
130_000_000
,
/* adDurationUs= */
AD_PERIOD_DURATION_US
,
/* adDurationUs= */
adPeriodDurationUs
,
/* adPositionInAdPod= */
2
,
/* adPositionInAdPod= */
2
,
/* totalAdDurationUs= */
6
*
AD_PERIOD_DURATION_US
,
/* totalAdDurationUs= */
6
*
adPeriodDurationUs
,
/* totalAdsInAdPod= */
6
,
/* totalAdsInAdPod= */
6
,
adPlaybackState
);
adPlaybackState
);
...
@@ -2099,13 +2172,17 @@ public class ImaUtilTest {
...
@@ -2099,13 +2172,17 @@ public class ImaUtilTest {
@Test
@Test
public
void
getAdGroupDurationUsForLiveAdPeriodIndex_allAdsInTimeline_correctAdGroupDuration
()
{
public
void
getAdGroupDurationUsForLiveAdPeriodIndex_allAdsInTimeline_correctAdGroupDuration
()
{
int
adPodTotalAdCount
=
2
;
int
adPodTotalAdCount
=
2
;
long
adPeriodDurationUs
=
msToUs
(
AD_PERIOD_DURATION_MS
);
// Content and ad periods in timeline: [c, a, a, c, a, a].
// Content and ad periods in timeline: [c, a, a, c, a, a].
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
75_007_123
,
/* liveWindowDurationUs= */
75_007_123
,
/* nowUs= */
99_321_457
,
/* nowUs= */
99_321_457
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
true
,
/* populateAds= */
true
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -2121,11 +2198,11 @@ public class ImaUtilTest {
...
@@ -2121,11 +2198,11 @@ public class ImaUtilTest {
assertThat
(
assertThat
(
ImaUtil
.
getAdGroupDurationUsForLiveAdPeriodIndex
(
ImaUtil
.
getAdGroupDurationUsForLiveAdPeriodIndex
(
timeline
,
firstAdPodInfo
,
/* adPeriodIndex= */
1
,
new
Window
(),
new
Period
()))
timeline
,
firstAdPodInfo
,
/* adPeriodIndex= */
1
,
new
Window
(),
new
Period
()))
.
isEqualTo
(
2
*
AD_PERIOD_DURATION_US
);
.
isEqualTo
(
2
*
adPeriodDurationUs
);
assertThat
(
assertThat
(
ImaUtil
.
getAdGroupDurationUsForLiveAdPeriodIndex
(
ImaUtil
.
getAdGroupDurationUsForLiveAdPeriodIndex
(
timeline
,
secondAdPodInfo
,
/* adPeriodIndex= */
2
,
new
Window
(),
new
Period
()))
timeline
,
secondAdPodInfo
,
/* adPeriodIndex= */
2
,
new
Window
(),
new
Period
()))
.
isEqualTo
(
2
*
AD_PERIOD_DURATION_US
);
.
isEqualTo
(
2
*
adPeriodDurationUs
);
// The second ad group has the last ad with an unknown duration.
// The second ad group has the last ad with an unknown duration.
assertThat
(
assertThat
(
ImaUtil
.
getAdGroupDurationUsForLiveAdPeriodIndex
(
ImaUtil
.
getAdGroupDurationUsForLiveAdPeriodIndex
(
...
@@ -2144,10 +2221,13 @@ public class ImaUtilTest {
...
@@ -2144,10 +2221,13 @@ public class ImaUtilTest {
// Content and ad periods in timeline: [a, a, c]. First two ads not in window.
// Content and ad periods in timeline: [a, a, c]. First two ads not in window.
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0
,
/* availabilityStartTime
M
s= */
0
,
/* liveWindowDurationUs= */
49_321_753
,
/* liveWindowDurationUs= */
49_321_753
,
/* nowUs= */
85_007_123
,
/* nowUs= */
85_007_123
,
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* adSequencePattern= */
new
boolean
[]
{
false
,
true
,
true
},
/* periodDurationMsPattern= */
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
true
,
/* populateAds= */
true
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
...
libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMultiPeriodLiveTimeline.java
View file @
e4194fc8
...
@@ -17,6 +17,7 @@ package androidx.media3.test.utils;
...
@@ -17,6 +17,7 @@ package androidx.media3.test.utils;
import
static
androidx
.
media3
.
common
.
util
.
Assertions
.
checkArgument
;
import
static
androidx
.
media3
.
common
.
util
.
Assertions
.
checkArgument
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
msToUs
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
msToUs
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
sum
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
usToMs
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
usToMs
;
import
androidx.media3.common.AdPlaybackState
;
import
androidx.media3.common.AdPlaybackState
;
...
@@ -42,14 +43,14 @@ import java.util.Arrays;
...
@@ -42,14 +43,14 @@ import java.util.Arrays;
*
*
* <p>Periods are either of type content or ad as defined by the ad sequence pattern. A period is an
* <p>Periods are either of type content or ad as defined by the ad sequence pattern. A period is an
* ad if {@code adSequencePattern[id % adSequencePattern.length]} evaluates to true. Ad periods have
* ad if {@code adSequencePattern[id % adSequencePattern.length]} evaluates to true. Ad periods have
* a duration of {@link #AD_PERIOD_DURATION_
U
S} and content periods have a duration of {@link
* a duration of {@link #AD_PERIOD_DURATION_
M
S} and content periods have a duration of {@link
* #PERIOD_DURATION_
U
S}.
* #PERIOD_DURATION_
M
S}.
*/
*/
@UnstableApi
@UnstableApi
public
class
FakeMultiPeriodLiveTimeline
extends
Timeline
{
public
class
FakeMultiPeriodLiveTimeline
extends
Timeline
{
public
static
final
long
AD_PERIOD_DURATION_
US
=
10_00
0_000L
;
public
static
final
long
AD_PERIOD_DURATION_
MS
=
1
0_000L
;
public
static
final
long
PERIOD_DURATION_
US
=
30_00
0_000L
;
public
static
final
long
PERIOD_DURATION_
MS
=
3
0_000L
;
private
final
boolean
[]
adSequencePattern
;
private
final
boolean
[]
adSequencePattern
;
private
final
MediaItem
mediaItem
;
private
final
MediaItem
mediaItem
;
...
@@ -58,6 +59,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -58,6 +59,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
private
final
boolean
isContentTimeline
;
private
final
boolean
isContentTimeline
;
private
final
boolean
populateAds
;
private
final
boolean
populateAds
;
private
final
boolean
playedAds
;
private
final
boolean
playedAds
;
private
final
long
[]
periodDurationUsPattern
;
private
long
nowUs
;
private
long
nowUs
;
private
ImmutableList
<
PeriodData
>
periods
;
private
ImmutableList
<
PeriodData
>
periods
;
...
@@ -65,53 +67,55 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -65,53 +67,55 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
/**
/**
* Creates an instance.
* Creates an instance.
*
*
* @param availabilityStartTimeUs The start time of the available time range, in UNIX epoch.
* @param availabilityStartTimeMs The start time of the available time range, UNIX epoch in
* milliseconds.
* @param liveWindowDurationUs The duration of the live window.
* @param liveWindowDurationUs The duration of the live window.
* @param nowUs The current time that determines the end of the live window.
* @param nowUs The current time that determines the end of the live window.
* @param adSequencePattern The repeating pattern of periods starting at {@code
* @param adSequencePattern The repeating pattern of periods starting at {@code
* availabilityStartTimeUs}. True is an ad period, and false a content period.
* availabilityStartTimeMs}. True is an ad period, and false a content period.
* @param periodDurationMsPattern The repeating pattern of periods durations starting at {@code
* availabilityStartTimeMs}, in milliseconds. Must have the same length as {@code
* adSequencePattern}.
* @param isContentTimeline Whether the timeline is a content timeline without {@link
* @param isContentTimeline Whether the timeline is a content timeline without {@link
* AdPlaybackState}s.
* AdPlaybackState}s.
* @param populateAds Whether to populate ads in the same way if an ad event has been received.
* @param populateAds Whether to populate ads in the same way if an ad event has been received.
* @param playedAds Whether ads should be marked as played if populated.
* @param playedAds Whether ads should be marked as played if populated.
*/
*/
public
FakeMultiPeriodLiveTimeline
(
public
FakeMultiPeriodLiveTimeline
(
long
availabilityStartTime
U
s
,
long
availabilityStartTime
M
s
,
long
liveWindowDurationUs
,
long
liveWindowDurationUs
,
long
nowUs
,
long
nowUs
,
boolean
[]
adSequencePattern
,
boolean
[]
adSequencePattern
,
long
[]
periodDurationMsPattern
,
boolean
isContentTimeline
,
boolean
isContentTimeline
,
boolean
populateAds
,
boolean
populateAds
,
boolean
playedAds
)
{
boolean
playedAds
)
{
checkArgument
(
nowUs
-
liveWindowDurationUs
>=
availabilityStartTimeUs
);
checkArgument
(
nowUs
-
liveWindowDurationUs
>=
msToUs
(
availabilityStartTimeMs
));
this
.
availabilityStartTimeUs
=
availabilityStartTimeUs
;
checkArgument
(
adSequencePattern
.
length
==
periodDurationMsPattern
.
length
);
this
.
availabilityStartTimeUs
=
msToUs
(
availabilityStartTimeMs
);
this
.
liveWindowDurationUs
=
liveWindowDurationUs
;
this
.
liveWindowDurationUs
=
liveWindowDurationUs
;
this
.
nowUs
=
nowUs
;
this
.
nowUs
=
nowUs
;
this
.
adSequencePattern
=
Arrays
.
copyOf
(
adSequencePattern
,
adSequencePattern
.
length
);
this
.
adSequencePattern
=
Arrays
.
copyOf
(
adSequencePattern
,
adSequencePattern
.
length
);
periodDurationUsPattern
=
new
long
[
periodDurationMsPattern
.
length
];
for
(
int
i
=
0
;
i
<
periodDurationMsPattern
.
length
;
i
++)
{
periodDurationUsPattern
[
i
]
=
msToUs
(
periodDurationMsPattern
[
i
]);
}
this
.
isContentTimeline
=
isContentTimeline
;
this
.
isContentTimeline
=
isContentTimeline
;
this
.
populateAds
=
populateAds
;
this
.
populateAds
=
populateAds
;
this
.
playedAds
=
playedAds
;
this
.
playedAds
=
playedAds
;
mediaItem
=
new
MediaItem
.
Builder
().
build
();
mediaItem
=
new
MediaItem
.
Builder
().
build
();
periods
=
periods
=
invalidate
(
invalidate
(
availabilityStartTimeUs
,
msToUs
(
availabilityStartTimeMs
)
,
liveWindowDurationUs
,
liveWindowDurationUs
,
nowUs
,
nowUs
,
adSequencePattern
,
adSequencePattern
,
periodDurationUsPattern
,
isContentTimeline
,
isContentTimeline
,
populateAds
,
populateAds
,
playedAds
);
playedAds
);
}
}
/** Calculates the total duration of the given ad period sequence. */
public
static
long
calculateAdSequencePatternDurationUs
(
boolean
[]
adSequencePattern
)
{
long
durationUs
=
0
;
for
(
boolean
isAd
:
adSequencePattern
)
{
durationUs
+=
(
isAd
?
AD_PERIOD_DURATION_US
:
PERIOD_DURATION_US
);
}
return
durationUs
;
}
/** Advances the live window by the given duration, in microseconds. */
/** Advances the live window by the given duration, in microseconds. */
public
void
advanceNowUs
(
long
durationUs
)
{
public
void
advanceNowUs
(
long
durationUs
)
{
nowUs
+=
durationUs
;
nowUs
+=
durationUs
;
...
@@ -121,11 +125,35 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -121,11 +125,35 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
liveWindowDurationUs
,
liveWindowDurationUs
,
nowUs
,
nowUs
,
adSequencePattern
,
adSequencePattern
,
periodDurationUsPattern
,
isContentTimeline
,
isContentTimeline
,
populateAds
,
populateAds
,
playedAds
);
playedAds
);
}
}
/**
* The window's start time in microseconds since the Unix epoch, or {@link C#TIME_UNSET} if
* unknown or not applicable.
*/
public
long
getWindowStartTimeUs
()
{
Window
window
=
getWindow
(
/* windowIndex= */
0
,
new
Window
());
// Revert us/ms truncation introduced in `getWindow()`. This is identical to the truncation
// applied in the Media3 `DashMediaSource.DashTimeline` and can be reverted in the same way.
return
window
.
windowStartTimeMs
!=
C
.
TIME_UNSET
?
msToUs
(
window
.
windowStartTimeMs
)
+
(
window
.
positionInFirstPeriodUs
%
1000
)
:
C
.
TIME_UNSET
;
}
/**
* Returns the period start time since Unix epoch, in microseconds.
*
* <p>Note: The returned value has millisecond precision only, so the trailing 3 digits are always
* zeros.
*/
public
long
getPeriodStartTimeUs
(
int
periodIndex
)
{
return
msToUs
(
periods
.
get
(
periodIndex
).
periodStartTimeMs
);
}
@Override
@Override
public
int
getWindowCount
()
{
public
int
getWindowCount
()
{
return
1
;
return
1
;
...
@@ -136,12 +164,13 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -136,12 +164,13 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
checkArgument
(
windowIndex
==
0
);
checkArgument
(
windowIndex
==
0
);
MediaItem
.
LiveConfiguration
liveConfiguration
=
MediaItem
.
LiveConfiguration
liveConfiguration
=
new
MediaItem
.
LiveConfiguration
.
Builder
().
build
();
new
MediaItem
.
LiveConfiguration
.
Builder
().
build
();
long
positionInFirstPeriodUs
=
-
periods
.
get
(
0
).
positionInWindowUs
;
window
.
set
(
window
.
set
(
/* uid= */
"live-window"
,
/* uid= */
"live-window"
,
mediaItem
,
mediaItem
,
/* manifest= */
null
,
/* manifest= */
null
,
/* presentationStartTimeMs= */
C
.
TIME_UNSET
,
/* presentationStartTimeMs= */
C
.
TIME_UNSET
,
/* windowStartTimeMs= */
usToMs
(
nowUs
-
liveWindowDuration
Us
),
/* windowStartTimeMs= */
periods
.
get
(
0
).
periodStartTimeMs
+
usToMs
(
positionInFirstPeriod
Us
),
/* elapsedRealtimeEpochOffsetMs= */
0
,
/* elapsedRealtimeEpochOffsetMs= */
0
,
/* isSeekable= */
true
,
/* isSeekable= */
true
,
/* isDynamic= */
true
,
/* isDynamic= */
true
,
...
@@ -150,7 +179,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -150,7 +179,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
/* durationUs= */
liveWindowDurationUs
,
/* durationUs= */
liveWindowDurationUs
,
/* firstPeriodIndex= */
0
,
/* firstPeriodIndex= */
0
,
/* lastPeriodIndex= */
getPeriodCount
()
-
1
,
/* lastPeriodIndex= */
getPeriodCount
()
-
1
,
/* positionInFirstPeriodUs= */
-
periods
.
get
(
0
).
positionInWindow
Us
);
positionInFirstPeriod
Us
);
return
window
;
return
window
;
}
}
...
@@ -193,24 +222,23 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -193,24 +222,23 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
long
liveWindowDurationUs
,
long
liveWindowDurationUs
,
long
now
,
long
now
,
boolean
[]
adSequencePattern
,
boolean
[]
adSequencePattern
,
long
[]
periodDurationUsPattern
,
boolean
isContentTimeline
,
boolean
isContentTimeline
,
boolean
populateAds
,
boolean
populateAds
,
boolean
playedAds
)
{
boolean
playedAds
)
{
long
windowStartTimeUs
=
now
-
liveWindowDurationUs
;
long
windowStartTimeUs
=
now
-
liveWindowDurationUs
;
int
sequencePeriodCount
=
adSequencePattern
.
length
;
int
sequencePeriodCount
=
adSequencePattern
.
length
;
long
sequenceDurationUs
=
calculateAdSequencePatternDurationUs
(
adSequence
Pattern
);
long
sequenceDurationUs
=
sum
(
periodDurationUs
Pattern
);
long
skippedSequenceCount
=
(
windowStartTimeUs
-
availabilityStartTimeUs
)
/
sequenceDurationUs
;
long
skippedSequenceCount
=
(
windowStartTimeUs
-
availabilityStartTimeUs
)
/
sequenceDurationUs
;
// Search the first period of the live window.
// Search the first period of the live window.
int
firstPeriodIndex
=
(
int
)
(
skippedSequenceCount
*
sequencePeriodCount
);
int
firstPeriodIndex
=
(
int
)
(
skippedSequenceCount
*
sequencePeriodCount
);
boolean
isAd
=
adSequencePattern
[
firstPeriodIndex
%
sequencePeriodCount
];
long
firstPeriodDurationUs
=
periodDurationUsPattern
[
firstPeriodIndex
%
sequencePeriodCount
];
long
firstPeriodDurationUs
=
isAd
?
AD_PERIOD_DURATION_US
:
PERIOD_DURATION_US
;
long
firstPeriodEndTimeUs
=
long
firstPeriodEndTimeUs
=
availabilityStartTimeUs
availabilityStartTimeUs
+
(
sequenceDurationUs
*
skippedSequenceCount
)
+
(
sequenceDurationUs
*
skippedSequenceCount
)
+
firstPeriodDurationUs
;
+
firstPeriodDurationUs
;
while
(
firstPeriodEndTimeUs
<=
windowStartTimeUs
)
{
while
(
firstPeriodEndTimeUs
<=
windowStartTimeUs
)
{
isAd
=
adSequencePattern
[++
firstPeriodIndex
%
sequencePeriodCount
];
firstPeriodDurationUs
=
periodDurationUsPattern
[++
firstPeriodIndex
%
sequencePeriodCount
];
firstPeriodDurationUs
=
isAd
?
AD_PERIOD_DURATION_US
:
PERIOD_DURATION_US
;
firstPeriodEndTimeUs
+=
firstPeriodDurationUs
;
firstPeriodEndTimeUs
+=
firstPeriodDurationUs
;
}
}
ImmutableList
.
Builder
<
PeriodData
>
liveWindow
=
new
ImmutableList
.
Builder
<>();
ImmutableList
.
Builder
<
PeriodData
>
liveWindow
=
new
ImmutableList
.
Builder
<>();
...
@@ -218,8 +246,8 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -218,8 +246,8 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
int
lastPeriodIndex
=
firstPeriodIndex
;
int
lastPeriodIndex
=
firstPeriodIndex
;
// Add periods to the window from the first period until we find a period start after `now`.
// Add periods to the window from the first period until we find a period start after `now`.
while
(
lastPeriodStartTimeUs
<
now
)
{
while
(
lastPeriodStartTimeUs
<
now
)
{
isAd
=
adSequence
Pattern
[
lastPeriodIndex
%
sequencePeriodCount
];
long
periodDurationUs
=
periodDurationUs
Pattern
[
lastPeriodIndex
%
sequencePeriodCount
];
long
periodDurationUs
=
isAd
?
AD_PERIOD_DURATION_US
:
PERIOD_DURATION_US
;
boolean
isAd
=
adSequencePattern
[
lastPeriodIndex
%
sequencePeriodCount
]
;
AdPlaybackState
adPlaybackState
=
AdPlaybackState
.
NONE
;
AdPlaybackState
adPlaybackState
=
AdPlaybackState
.
NONE
;
if
(!
isContentTimeline
)
{
if
(!
isContentTimeline
)
{
adPlaybackState
=
new
AdPlaybackState
(
"adsId"
).
withLivePostrollPlaceholderAppended
();
adPlaybackState
=
new
AdPlaybackState
(
"adsId"
).
withLivePostrollPlaceholderAppended
();
...
@@ -244,6 +272,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -244,6 +272,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
/* id= */
lastPeriodIndex
++,
/* id= */
lastPeriodIndex
++,
periodDurationUs
,
periodDurationUs
,
/* positionInWindowUs= */
lastPeriodStartTimeUs
-
windowStartTimeUs
,
/* positionInWindowUs= */
lastPeriodStartTimeUs
-
windowStartTimeUs
,
/* periodStartTimeMs= */
usToMs
(
lastPeriodStartTimeUs
),
isAd
,
isAd
,
adPlaybackState
));
adPlaybackState
));
lastPeriodStartTimeUs
+=
periodDurationUs
;
lastPeriodStartTimeUs
+=
periodDurationUs
;
...
@@ -257,6 +286,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -257,6 +286,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
private
final
Object
uid
;
private
final
Object
uid
;
private
final
long
durationUs
;
private
final
long
durationUs
;
private
final
long
positionInWindowUs
;
private
final
long
positionInWindowUs
;
private
final
long
periodStartTimeMs
;
private
final
AdPlaybackState
adPlaybackState
;
private
final
AdPlaybackState
adPlaybackState
;
/** Creates an instance. */
/** Creates an instance. */
...
@@ -264,9 +294,11 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
...
@@ -264,9 +294,11 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
int
id
,
int
id
,
long
durationUs
,
long
durationUs
,
long
positionInWindowUs
,
long
positionInWindowUs
,
long
periodStartTimeMs
,
boolean
isAd
,
boolean
isAd
,
AdPlaybackState
adPlaybackState
)
{
AdPlaybackState
adPlaybackState
)
{
this
.
id
=
id
;
this
.
id
=
id
;
this
.
periodStartTimeMs
=
periodStartTimeMs
;
this
.
uid
=
"uid-"
+
id
+
"["
+
(
isAd
?
"a"
:
"c"
)
+
"]"
;
this
.
uid
=
"uid-"
+
id
+
"["
+
(
isAd
?
"a"
:
"c"
)
+
"]"
;
this
.
durationUs
=
durationUs
;
this
.
durationUs
=
durationUs
;
this
.
positionInWindowUs
=
positionInWindowUs
;
this
.
positionInWindowUs
=
positionInWindowUs
;
...
...
libraries/test_utils/src/test/java/androidx/media3/test/utils/FakeMultiPeriodLiveTimelineTest.java
View file @
e4194fc8
...
@@ -15,14 +15,15 @@
...
@@ -15,14 +15,15 @@
*/
*/
package
androidx
.
media3
.
test
.
utils
;
package
androidx
.
media3
.
test
.
utils
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_US
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
msToUs
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_US
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
sum
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
calculateAdSequencePatternDurationUs
;
import
static
androidx
.
media3
.
common
.
util
.
Util
.
usToMs
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
AD_PERIOD_DURATION_MS
;
import
static
androidx
.
media3
.
test
.
utils
.
FakeMultiPeriodLiveTimeline
.
PERIOD_DURATION_MS
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
androidx.media3.common.C
;
import
androidx.media3.common.C
;
import
androidx.media3.common.Timeline
;
import
androidx.media3.common.Timeline
;
import
androidx.media3.common.util.Util
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runner.RunWith
;
...
@@ -36,12 +37,16 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -36,12 +37,16 @@ public class FakeMultiPeriodLiveTimelineTest {
@Test
@Test
public
void
newInstance_availabilitySinceStartOfUnixEpoch_correctLiveWindow
()
{
public
void
newInstance_availabilitySinceStartOfUnixEpoch_correctLiveWindow
()
{
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
long
[]
periodDurationMsPattern
=
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
};
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* nowUs= */
60_000_000L
,
/* nowUs= */
60_000_000L
,
adSequencePattern
,
adSequencePattern
,
periodDurationMsPattern
,
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -63,22 +68,28 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -63,22 +68,28 @@ public class FakeMultiPeriodLiveTimelineTest {
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* nowUs= */
60_000_000L
,
/* nowUs= */
60_000_000L
,
adSequencePattern
),
adSequencePattern
,
adSequencePattern
);
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
}
}
@Test
@Test
public
void
newInstance_timelineWithAdsPopulated_correctPlaybackStates
()
{
public
void
newInstance_timelineWithAdsPopulated_correctPlaybackStates
()
{
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
long
[]
periodDurationMsPattern
=
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
};
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* nowUs= */
100_000_000L
,
/* nowUs= */
100_000_000L
,
adSequencePattern
,
adSequencePattern
,
periodDurationMsPattern
,
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
true
,
/* populateAds= */
true
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -123,22 +134,28 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -123,22 +134,28 @@ public class FakeMultiPeriodLiveTimelineTest {
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* nowUs= */
100_000_000L
,
/* nowUs= */
100_000_000L
,
adSequencePattern
),
adSequencePattern
,
adSequencePattern
);
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
}
}
@Test
@Test
public
void
newInstance_timelineWithAdsNotPopulated_correctPlaybackStates
()
{
public
void
newInstance_timelineWithAdsNotPopulated_correctPlaybackStates
()
{
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
long
[]
periodDurationMsPattern
=
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
};
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* nowUs= */
100_000_000L
,
/* nowUs= */
100_000_000L
,
adSequencePattern
,
adSequencePattern
,
periodDurationMsPattern
,
/* isContentTimeline= */
false
,
/* isContentTimeline= */
false
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -175,22 +192,28 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -175,22 +192,28 @@ public class FakeMultiPeriodLiveTimelineTest {
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* liveWindowDurationUs= */
50_000_000L
,
/* nowUs= */
100_000_000L
,
/* nowUs= */
100_000_000L
,
adSequencePattern
),
adSequencePattern
,
adSequencePattern
);
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
}
}
@Test
@Test
public
void
advanceTimeUs_availabilitySinceStartOfUnixEpoch_correctPeriodsInLiveWindow
()
{
public
void
advanceTimeUs_availabilitySinceStartOfUnixEpoch_correctPeriodsInLiveWindow
()
{
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
long
[]
periodDurationMsPattern
=
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
};
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* nowUs= */
60_000_123L
,
/* nowUs= */
60_000_123L
,
adSequencePattern
,
adSequencePattern
,
periodDurationMsPattern
,
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -209,11 +232,13 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -209,11 +232,13 @@ public class FakeMultiPeriodLiveTimelineTest {
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* nowUs= */
60_000_123L
,
/* nowUs= */
60_000_123L
,
adSequencePattern
),
adSequencePattern
,
adSequencePattern
);
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
// Advance nowUs so that the window ends just 1us before the next period moves into the window.
// Advance nowUs so that the window ends just 1us before the next period moves into the window.
timeline
.
advanceNowUs
(
19999877L
);
timeline
.
advanceNowUs
(
19999877L
);
...
@@ -231,11 +256,13 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -231,11 +256,13 @@ public class FakeMultiPeriodLiveTimelineTest {
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* nowUs= */
60_000_123L
+
19999877L
,
/* nowUs= */
60_000_123L
+
19999877L
,
adSequencePattern
),
adSequencePattern
,
adSequencePattern
);
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
// Advance the window by 1us to add the next period at the end of the window.
// Advance the window by 1us to add the next period at the end of the window.
timeline
.
advanceNowUs
(
1L
);
timeline
.
advanceNowUs
(
1L
);
...
@@ -254,110 +281,159 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -254,110 +281,159 @@ public class FakeMultiPeriodLiveTimelineTest {
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* liveWindowDurationUs= */
60_000_000L
,
/* nowUs= */
60_000_123L
+
19999878L
,
/* nowUs= */
60_000_123L
+
19999878L
,
adSequencePattern
),
adSequencePattern
,
adSequencePattern
);
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
}
}
@Test
@Test
public
void
newInstance_advancedAvailabilityStartTime_correctlyInterpolatedPeriodIds
()
{
public
void
newInstance_advancedAvailabilityStartTime_correctlyInterpolatedPeriodIds
()
{
Timeline
.
Period
period
=
new
Timeline
.
Period
();
Timeline
.
Period
period
=
new
Timeline
.
Period
();
long
availabilityStartTime
U
s
=
0
;
long
availabilityStartTime
M
s
=
0
;
long
nowUs
=
120_000_123
;
long
nowUs
=
120_000_123
;
long
liveWindowDurationUs
=
60_000_987L
;
long
liveWindowDurationUs
=
60_000_987L
;
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
long
sequenceDurationUs
=
calculateAdSequencePatternDurationUs
(
adSequencePattern
);
long
[]
periodDurationMsPattern
=
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
};
long
sequenceDurationUs
=
50_000_000L
;
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
availabilityStartTime
U
s
,
availabilityStartTime
M
s
,
liveWindowDurationUs
,
liveWindowDurationUs
,
nowUs
,
nowUs
,
adSequencePattern
,
adSequencePattern
,
periodDurationMsPattern
,
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
true
);
/* playedAds= */
true
);
assertThat
(
timeline
.
getWindow
(
0
,
new
Timeline
.
Window
()).
windowStartTimeMs
)
.
isEqualTo
(
Util
.
usToMs
(
nowUs
-
liveWindowDurationUs
));
assertThat
(
timeline
.
getPeriodCount
()).
isEqualTo
(
4
);
assertThat
(
timeline
.
getPeriodCount
()).
isEqualTo
(
4
);
long
windowStartTimeUs
=
timeline
.
getWindowStartTimeUs
();
assertThat
(
windowStartTimeUs
+
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
0
));
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
id
).
isEqualTo
(
3
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
id
).
isEqualTo
(
3
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
uid
).
isEqualTo
(
"uid-3[c]"
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
uid
).
isEqualTo
(
"uid-3[c]"
);
assertThat
(
windowStartTimeUs
+
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
1
));
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
id
).
isEqualTo
(
4
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
id
).
isEqualTo
(
4
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
uid
).
isEqualTo
(
"uid-4[a]"
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
uid
).
isEqualTo
(
"uid-4[a]"
);
assertThat
(
windowStartTimeUs
+
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
2
));
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
id
).
isEqualTo
(
5
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
id
).
isEqualTo
(
5
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
uid
).
isEqualTo
(
"uid-5[a]"
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
uid
).
isEqualTo
(
"uid-5[a]"
);
assertThat
(
windowStartTimeUs
+
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
3
));
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
id
).
isEqualTo
(
6
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
id
).
isEqualTo
(
6
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
uid
).
isEqualTo
(
"uid-6[c]"
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
uid
).
isEqualTo
(
"uid-6[c]"
);
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
availabilityStartTimeUs
,
liveWindowDurationUs
,
nowUs
,
adSequencePattern
),
availabilityStartTimeMs
,
adSequencePattern
);
liveWindowDurationUs
,
nowUs
,
adSequencePattern
,
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
timeline
.
advanceNowUs
(
sequenceDurationUs
*
13
);
timeline
.
advanceNowUs
(
sequenceDurationUs
*
13
);
windowStartTimeUs
=
timeline
.
getWindowStartTimeUs
();
assertThat
(
timeline
.
getWindow
(
0
,
new
Timeline
.
Window
()).
windowStartTimeMs
)
assertThat
(
.
isEqualTo
(
Util
.
usToMs
((
nowUs
+
sequenceDurationUs
*
13
)
-
liveWindowDurationUs
));
windowStartTimeUs
+
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
0
));
assertThat
(
timeline
.
getPeriodCount
()).
isEqualTo
(
4
);
assertThat
(
timeline
.
getPeriodCount
()).
isEqualTo
(
4
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
id
).
isEqualTo
((
13
*
3
)
+
3
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
id
).
isEqualTo
((
13
*
3
)
+
3
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
uid
)
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
0
,
period
).
uid
)
.
isEqualTo
(
"uid-"
+
((
13
*
3
)
+
3
)
+
"[c]"
);
.
isEqualTo
(
"uid-"
+
((
13
*
3
)
+
3
)
+
"[c]"
);
assertThat
(
windowStartTimeUs
+
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
1
));
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
id
).
isEqualTo
((
13
*
3
)
+
4
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
id
).
isEqualTo
((
13
*
3
)
+
4
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
uid
)
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
1
,
period
).
uid
)
.
isEqualTo
(
"uid-"
+
((
13
*
3
)
+
4
)
+
"[a]"
);
.
isEqualTo
(
"uid-"
+
((
13
*
3
)
+
4
)
+
"[a]"
);
assertThat
(
windowStartTimeUs
+
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
2
));
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
id
).
isEqualTo
((
13
*
3
)
+
5
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
id
).
isEqualTo
((
13
*
3
)
+
5
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
uid
)
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
2
,
period
).
uid
)
.
isEqualTo
(
"uid-"
+
((
13
*
3
)
+
5
)
+
"[a]"
);
.
isEqualTo
(
"uid-"
+
((
13
*
3
)
+
5
)
+
"[a]"
);
assertThat
(
windowStartTimeUs
+
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
3
));
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
id
).
isEqualTo
((
13
*
3
)
+
6
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
id
).
isEqualTo
((
13
*
3
)
+
6
);
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
uid
)
assertThat
(
timeline
.
getPeriod
(
/* periodIndex= */
3
,
period
).
uid
)
.
isEqualTo
(
"uid-"
+
((
13
*
3
)
+
6
)
+
"[c]"
);
.
isEqualTo
(
"uid-"
+
((
13
*
3
)
+
6
)
+
"[c]"
);
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
availabilityStartTime
U
s
,
availabilityStartTime
M
s
,
liveWindowDurationUs
,
liveWindowDurationUs
,
(
nowUs
+
sequenceDurationUs
*
13
),
(
nowUs
+
sequenceDurationUs
*
13
),
adSequencePattern
),
adSequencePattern
,
adSequencePattern
);
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
}
}
@Test
@Test
public
void
newInstance_availabilitySinceAWeekAfterStartOfUnixEpoch_correctLiveWindow
()
{
public
void
newInstance_availabilitySinceAWeekAfterStartOfUnixEpoch_correctLiveWindow
()
{
long
availabilityStartTime
Us
=
7
*
A_DAY_US
;
long
availabilityStartTime
Ms
=
usToMs
(
7
*
A_DAY_US
)
;
long
nowUs
=
18
*
A_DAY_US
+
135_000_000
;
long
nowUs
=
18
*
A_DAY_US
+
135_000_000
;
long
liveWindowDurationUs
=
60_000_000L
;
long
liveWindowDurationUs
=
60_000_000L
;
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
};
long
[]
periodDurationMsPattern
=
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
};
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
availabilityStartTime
U
s
,
availabilityStartTime
M
s
,
liveWindowDurationUs
,
liveWindowDurationUs
,
nowUs
,
nowUs
,
adSequencePattern
,
adSequencePattern
,
periodDurationMsPattern
,
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
assertThat
(
timeline
.
getWindow
(
0
,
new
Timeline
.
Window
()).
windowStartTimeMs
)
assertThat
(
timeline
.
getWindow
(
0
,
new
Timeline
.
Window
()).
windowStartTimeMs
)
.
isEqualTo
(
Util
.
usToMs
(
nowUs
-
liveWindowDurationUs
));
.
isEqualTo
(
usToMs
(
nowUs
-
liveWindowDurationUs
));
assertExpectedWindow
(
assertExpectedWindow
(
timeline
,
timeline
,
calculateExpectedWindow
(
calculateExpectedWindow
(
availabilityStartTimeUs
,
liveWindowDurationUs
,
nowUs
,
adSequencePattern
),
availabilityStartTimeMs
,
adSequencePattern
);
liveWindowDurationUs
,
nowUs
,
adSequencePattern
,
periodDurationMsPattern
),
adSequencePattern
,
periodDurationMsPattern
);
}
}
@Test
@Test
public
void
newInstance_adSequencePattern_correctPeriodTypesFromStartOfAvailability
()
{
public
void
newInstance_adSequencePattern_correctPeriodTypesFromStartOfAvailability
()
{
FakeMultiPeriodLiveTimeline
timeline
=
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
120_000_000L
,
/* liveWindowDurationUs= */
120_000_000L
,
/* nowUs= */
120_000_000L
,
/* nowUs= */
120_000_000L
,
new
boolean
[]
{
false
,
true
,
true
,
true
},
new
boolean
[]
{
false
,
true
,
true
,
true
},
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -392,10 +468,17 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -392,10 +468,17 @@ public class FakeMultiPeriodLiveTimelineTest {
timeline
=
timeline
=
new
FakeMultiPeriodLiveTimeline
(
new
FakeMultiPeriodLiveTimeline
(
/* availabilityStartTime
U
s= */
0L
,
/* availabilityStartTime
M
s= */
0L
,
/* liveWindowDurationUs= */
220_000_000L
,
/* liveWindowDurationUs= */
220_000_000L
,
/* nowUs= */
250_000_000L
,
/* nowUs= */
250_000_000L
,
new
boolean
[]
{
false
,
true
,
false
,
true
,
false
},
new
boolean
[]
{
false
,
true
,
false
,
true
,
false
},
new
long
[]
{
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
PERIOD_DURATION_MS
,
AD_PERIOD_DURATION_MS
,
PERIOD_DURATION_MS
},
/* isContentTimeline= */
true
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* populateAds= */
false
,
/* playedAds= */
false
);
/* playedAds= */
false
);
...
@@ -415,22 +498,62 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -415,22 +498,62 @@ public class FakeMultiPeriodLiveTimelineTest {
assertThat
(
timeline
.
getPeriod
(
9
,
period
).
uid
).
isEqualTo
(
"uid-10[c]"
);
assertThat
(
timeline
.
getPeriod
(
9
,
period
).
uid
).
isEqualTo
(
"uid-10[c]"
);
}
}
@Test
public
void
advanceNowUs_calculatePeriodStartTimeUsFromWindowStartMs_correctPeriodStartTimeUs
()
{
long
[]
periodDurationMsPattern
=
{
1
,
7
,
5
,
3
};
boolean
[]
adSequencePattern
=
{
false
,
true
,
true
,
true
};
long
liveWindowDurationUs
=
15_243L
;
long
nowUs
=
29_000_123L
;
long
availabilityStartTimeMs
=
1L
;
FakeMultiPeriodLiveTimeline
timeline
=
new
FakeMultiPeriodLiveTimeline
(
availabilityStartTimeMs
,
liveWindowDurationUs
,
nowUs
,
adSequencePattern
,
periodDurationMsPattern
,
/* isContentTimeline= */
true
,
/* populateAds= */
false
,
/* playedAds= */
false
);
Timeline
.
Window
window
=
new
Timeline
.
Window
();
Timeline
.
Period
period
=
new
Timeline
.
Period
();
for
(
long
i
=
0
;
i
<
50_000L
;
i
++)
{
timeline
.
getWindow
(
/* windowIndex= */
0
,
window
);
// Assert the DashMediaSource specific truncation can be reverted to calculate the period
// start time (See `FakeMultiPeriodLiveTimeline.getWindowStartImeUs()` also).
long
windowStartTimeUs
=
msToUs
(
window
.
windowStartTimeMs
)
+
(
window
.
positionInFirstPeriodUs
%
1000
);
for
(
int
j
=
window
.
firstPeriodIndex
;
j
<=
window
.
lastPeriodIndex
;
j
++)
{
timeline
.
getPeriod
(
/* periodIndex= */
j
,
period
);
assertThat
(
windowStartTimeUs
+
period
.
positionInWindowUs
)
.
isEqualTo
(
timeline
.
getPeriodStartTimeUs
(
/* periodIndex= */
j
));
}
timeline
.
advanceNowUs
(
1
);
}
}
private
ExpectedWindow
calculateExpectedWindow
(
private
ExpectedWindow
calculateExpectedWindow
(
long
availabilityStartTime
U
s
,
long
availabilityStartTime
M
s
,
long
liveWindowDurationUs
,
long
liveWindowDurationUs
,
long
nowUs
,
long
nowUs
,
boolean
[]
adSequencePattern
)
{
boolean
[]
adSequencePattern
,
long
[]
periodDurationMsPattern
)
{
long
[]
periodDurationUsPattern
=
new
long
[
periodDurationMsPattern
.
length
];
for
(
int
i
=
0
;
i
<
periodDurationMsPattern
.
length
;
i
++)
{
periodDurationUsPattern
[
i
]
=
msToUs
(
periodDurationMsPattern
[
i
]);
}
long
windowStartTimeUs
=
nowUs
-
liveWindowDurationUs
;
long
windowStartTimeUs
=
nowUs
-
liveWindowDurationUs
;
long
sequenceDurationUs
=
calculateAdSequencePatternDurationUs
(
adSequence
Pattern
);
long
sequenceDurationUs
=
sum
(
periodDurationUs
Pattern
);
long
durationBeforeWindowStartUs
=
windowStartTimeUs
-
availabilityStartTimeUs
;
long
durationBeforeWindowStartUs
=
windowStartTimeUs
-
msToUs
(
availabilityStartTimeMs
)
;
long
skippedSequenceCount
=
durationBeforeWindowStartUs
/
sequenceDurationUs
;
long
skippedSequenceCount
=
durationBeforeWindowStartUs
/
sequenceDurationUs
;
long
remainingDurationBeforeWindowUs
=
durationBeforeWindowStartUs
%
sequenceDurationUs
;
long
remainingDurationBeforeWindowUs
=
durationBeforeWindowStartUs
%
sequenceDurationUs
;
int
idOfFirstPeriodInWindow
=
(
int
)
(
skippedSequenceCount
*
adSequencePattern
.
length
);
int
idOfFirstPeriodInWindow
=
(
int
)
(
skippedSequenceCount
*
adSequencePattern
.
length
);
long
lastSkippedPeriodDurationUs
=
0L
;
long
lastSkippedPeriodDurationUs
=
0L
;
// Skip period by period until we reach the window start.
// Skip period by period until we reach the window start.
while
(
remainingDurationBeforeWindowUs
>
0
)
{
while
(
remainingDurationBeforeWindowUs
>
0
)
{
boolean
isAd
=
adSequencePattern
[
idOfFirstPeriodInWindow
++
%
adSequencePattern
.
length
];
lastSkippedPeriodDurationUs
=
lastSkippedPeriodDurationUs
=
isAd
?
AD_PERIOD_DURATION_US
:
PERIOD_DURATION_US
;
periodDurationUsPattern
[
idOfFirstPeriodInWindow
++
%
adSequencePattern
.
length
]
;
remainingDurationBeforeWindowUs
-=
lastSkippedPeriodDurationUs
;
remainingDurationBeforeWindowUs
-=
lastSkippedPeriodDurationUs
;
}
}
long
positionOfFirstPeriodInWindowUs
=
0
;
long
positionOfFirstPeriodInWindowUs
=
0
;
...
@@ -442,24 +565,29 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -442,24 +565,29 @@ public class FakeMultiPeriodLiveTimelineTest {
-(
lastSkippedPeriodDurationUs
+
remainingDurationBeforeWindowUs
);
-(
lastSkippedPeriodDurationUs
+
remainingDurationBeforeWindowUs
);
}
}
long
durationOfFirstPeriodInWindowUs
=
long
durationOfFirstPeriodInWindowUs
=
adSequencePattern
[
idOfFirstPeriodInWindow
%
adSequencePattern
.
length
]
periodDurationUsPattern
[
idOfFirstPeriodInWindow
%
adSequencePattern
.
length
];
?
AD_PERIOD_DURATION_US
:
PERIOD_DURATION_US
;
long
durationInWindowUs
=
long
durationInWindowUs
=
remainingDurationBeforeWindowUs
==
0
remainingDurationBeforeWindowUs
==
0
?
durationOfFirstPeriodInWindowUs
?
durationOfFirstPeriodInWindowUs
:
-
remainingDurationBeforeWindowUs
;
:
-
remainingDurationBeforeWindowUs
;
int
idOfLastPeriodInWindow
=
idOfFirstPeriodInWindow
;
int
idOfLastPeriodInWindow
=
idOfFirstPeriodInWindow
;
while
(
durationInWindowUs
<
liveWindowDurationUs
)
{
while
(
durationInWindowUs
<
liveWindowDurationUs
)
{
boolean
isAd
=
adSequencePattern
[++
idOfLastPeriodInWindow
%
adSequencePattern
.
length
];
durationInWindowUs
+=
durationInWindowUs
+=
isAd
?
AD_PERIOD_DURATION_US
:
PERIOD_DURATION_US
;
periodDurationUsPattern
[++
idOfLastPeriodInWindow
%
adSequencePattern
.
length
]
;
}
}
return
new
ExpectedWindow
(
return
new
ExpectedWindow
(
idOfFirstPeriodInWindow
,
idOfLastPeriodInWindow
,
positionOfFirstPeriodInWindowUs
);
idOfFirstPeriodInWindow
,
idOfLastPeriodInWindow
,
positionOfFirstPeriodInWindowUs
);
}
}
private
void
assertExpectedWindow
(
private
void
assertExpectedWindow
(
Timeline
timeline
,
ExpectedWindow
expectedWindow
,
boolean
[]
adSequencePattern
)
{
Timeline
timeline
,
ExpectedWindow
expectedWindow
,
boolean
[]
adSequencePattern
,
long
[]
periodDurationMsPattern
)
{
long
[]
periodDurationUsPattern
=
new
long
[
periodDurationMsPattern
.
length
];
for
(
int
i
=
0
;
i
<
periodDurationMsPattern
.
length
;
i
++)
{
periodDurationUsPattern
[
i
]
=
msToUs
(
periodDurationMsPattern
[
i
]);
}
Timeline
.
Period
period
=
new
Timeline
.
Period
();
Timeline
.
Period
period
=
new
Timeline
.
Period
();
assertThat
(
timeline
.
getPeriodCount
())
assertThat
(
timeline
.
getPeriodCount
())
.
isEqualTo
(
expectedWindow
.
idOfLastPeriod
-
expectedWindow
.
idOfFirstPeriod
+
1
);
.
isEqualTo
(
expectedWindow
.
idOfLastPeriod
-
expectedWindow
.
idOfFirstPeriod
+
1
);
...
@@ -467,11 +595,12 @@ public class FakeMultiPeriodLiveTimelineTest {
...
@@ -467,11 +595,12 @@ public class FakeMultiPeriodLiveTimelineTest {
for
(
int
i
=
0
;
i
<
timeline
.
getPeriodCount
();
i
++)
{
for
(
int
i
=
0
;
i
<
timeline
.
getPeriodCount
();
i
++)
{
int
id
=
expectedWindow
.
idOfFirstPeriod
+
i
;
int
id
=
expectedWindow
.
idOfFirstPeriod
+
i
;
boolean
isAd
=
adSequencePattern
[
id
%
adSequencePattern
.
length
];
boolean
isAd
=
adSequencePattern
[
id
%
adSequencePattern
.
length
];
long
durationUs
=
periodDurationUsPattern
[
id
%
periodDurationUsPattern
.
length
];
assertThat
(
timeline
.
getPeriod
(
i
,
period
).
id
).
isEqualTo
(
id
);
assertThat
(
timeline
.
getPeriod
(
i
,
period
).
id
).
isEqualTo
(
id
);
assertThat
(
timeline
.
getPeriod
(
i
,
period
).
uid
)
assertThat
(
timeline
.
getPeriod
(
i
,
period
).
uid
)
.
isEqualTo
(
"uid-"
+
id
+
"["
+
(
isAd
?
"a"
:
"c"
)
+
"]"
);
.
isEqualTo
(
"uid-"
+
id
+
"["
+
(
isAd
?
"a"
:
"c"
)
+
"]"
);
assertThat
(
timeline
.
getPeriod
(
i
,
period
).
positionInWindowUs
).
isEqualTo
(
positionInWindowUs
);
assertThat
(
timeline
.
getPeriod
(
i
,
period
).
positionInWindowUs
).
isEqualTo
(
positionInWindowUs
);
positionInWindowUs
+=
isAd
?
AD_PERIOD_DURATION_US
:
PERIOD_DURATION_US
;
positionInWindowUs
+=
durationUs
;
}
}
}
}
...
...
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