use of androidx.media3.common.util.Clock in project media by androidx.
the class AdaptiveTrackSelection method determineIdealSelectedIndex.
/**
* Computes the ideal selected index ignoring buffer health.
*
* @param nowMs The current time in the timebase of {@link Clock#elapsedRealtime()}, or {@link
* Long#MIN_VALUE} to ignore track exclusion.
* @param chunkDurationUs The duration of a media chunk in microseconds, or {@link C#TIME_UNSET}
* if unknown.
*/
private int determineIdealSelectedIndex(long nowMs, long chunkDurationUs) {
long effectiveBitrate = getAllocatedBandwidth(chunkDurationUs);
int lowestBitrateAllowedIndex = 0;
for (int i = 0; i < length; i++) {
if (nowMs == Long.MIN_VALUE || !isBlacklisted(i, nowMs)) {
Format format = getFormat(i);
if (canSelectFormat(format, format.bitrate, effectiveBitrate)) {
return i;
} else {
lowestBitrateAllowedIndex = i;
}
}
}
return lowestBitrateAllowedIndex;
}
use of androidx.media3.common.util.Clock in project media by androidx.
the class ExoPlayerTest method clippedLoopedPeriodsArePlayedFully.
@Test
public void clippedLoopedPeriodsArePlayedFully() throws Exception {
long startPositionUs = 300_000;
long expectedDurationUs = 700_000;
MediaSource mediaSource = new ClippingMediaSource(new FakeMediaSource(), startPositionUs, startPositionUs + expectedDurationUs);
Clock clock = new FakeClock(/* isAutoAdvancing= */
true);
AtomicReference<Player> playerReference = new AtomicReference<>();
AtomicLong positionAtDiscontinuityMs = new AtomicLong(C.TIME_UNSET);
AtomicLong clockAtStartMs = new AtomicLong(C.TIME_UNSET);
AtomicLong clockAtDiscontinuityMs = new AtomicLong(C.TIME_UNSET);
Player.Listener playerListener = new Player.Listener() {
@Override
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (playbackState == Player.STATE_READY && clockAtStartMs.get() == C.TIME_UNSET) {
clockAtStartMs.set(clock.elapsedRealtime());
}
}
@Override
public void onPositionDiscontinuity(@DiscontinuityReason int reason) {
if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {
positionAtDiscontinuityMs.set(playerReference.get().getCurrentPosition());
clockAtDiscontinuityMs.set(clock.elapsedRealtime());
}
}
};
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
playerReference.set(player);
player.addListener(playerListener);
}
}).pause().setRepeatMode(Player.REPEAT_MODE_ALL).waitForPlaybackState(Player.STATE_READY).playUntilPosition(/* mediaItemIndex= */
0, /* positionMs= */
1).playUntilStartOfMediaItem(/* mediaItemIndex= */
0).setRepeatMode(Player.REPEAT_MODE_OFF).play().build();
new ExoPlayerTestRunner.Builder(context).setClock(clock).setMediaSources(mediaSource).setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
assertThat(positionAtDiscontinuityMs.get()).isAtLeast(0L);
assertThat(clockAtDiscontinuityMs.get() - clockAtStartMs.get()).isAtLeast(Util.usToMs(expectedDurationUs));
}
use of androidx.media3.common.util.Clock in project media by androidx.
the class MetadataRetrieverTest method retrieveMetadata_sefSlowMotion_outputsExpectedMetadata.
@Test
public void retrieveMetadata_sefSlowMotion_outputsExpectedMetadata() throws Exception {
MediaItem mediaItem = MediaItem.fromUri(Uri.parse("asset://android_asset/media/mp4/sample_sef_slow_motion.mp4"));
SmtaMetadataEntry expectedSmtaEntry = new SmtaMetadataEntry(/* captureFrameRate= */
240, /* svcTemporalLayerCount= */
4);
List<SlowMotionData.Segment> segments = new ArrayList<>();
segments.add(new SlowMotionData.Segment(/* startTimeMs= */
88, /* endTimeMs= */
879, /* speedDivisor= */
2));
segments.add(new SlowMotionData.Segment(/* startTimeMs= */
1255, /* endTimeMs= */
1970, /* speedDivisor= */
8));
SlowMotionData expectedSlowMotionData = new SlowMotionData(segments);
MdtaMetadataEntry expectedMdtaEntry = new MdtaMetadataEntry(KEY_ANDROID_CAPTURE_FPS, /* value= */
new byte[] { 67, 112, 0, 0 }, /* localeIndicator= */
0, /* typeIndicator= */
23);
ListenableFuture<TrackGroupArray> trackGroupsFuture = retrieveMetadata(context, mediaItem, clock);
ShadowLooper.idleMainLooper();
TrackGroupArray trackGroups = trackGroupsFuture.get(TEST_TIMEOUT_SEC, TimeUnit.SECONDS);
// Video and audio
assertThat(trackGroups.length).isEqualTo(2);
// Audio
assertThat(trackGroups.get(0).getFormat(0).metadata.length()).isEqualTo(2);
assertThat(trackGroups.get(0).getFormat(0).metadata.get(0)).isEqualTo(expectedSmtaEntry);
assertThat(trackGroups.get(0).getFormat(0).metadata.get(1)).isEqualTo(expectedSlowMotionData);
// Video
assertThat(trackGroups.get(1).getFormat(0).metadata.length()).isEqualTo(3);
assertThat(trackGroups.get(1).getFormat(0).metadata.get(0)).isEqualTo(expectedMdtaEntry);
assertThat(trackGroups.get(1).getFormat(0).metadata.get(1)).isEqualTo(expectedSmtaEntry);
assertThat(trackGroups.get(1).getFormat(0).metadata.get(2)).isEqualTo(expectedSlowMotionData);
}
use of androidx.media3.common.util.Clock in project media by androidx.
the class MetadataRetrieverTest method retrieveMetadata_heicStillPhoto_outputsEmptyMetadata.
@Test
public void retrieveMetadata_heicStillPhoto_outputsEmptyMetadata() throws Exception {
MediaItem mediaItem = MediaItem.fromUri(Uri.parse("asset://android_asset/media/mp4/sample_still_photo.heic"));
ListenableFuture<TrackGroupArray> trackGroupsFuture = retrieveMetadata(context, mediaItem, clock);
ShadowLooper.idleMainLooper();
TrackGroupArray trackGroups = trackGroupsFuture.get(TEST_TIMEOUT_SEC, TimeUnit.SECONDS);
assertThat(trackGroups.length).isEqualTo(1);
assertThat(trackGroups.get(0).length).isEqualTo(1);
assertThat(trackGroups.get(0).getFormat(0).metadata).isNull();
}
use of androidx.media3.common.util.Clock in project media by androidx.
the class MetadataRetrieverTest method setUp.
@Before
public void setUp() throws Exception {
context = ApplicationProvider.getApplicationContext();
clock = new FakeClock(/* isAutoAdvancing= */
true);
}
Aggregations