Search in sources :

Example 1 with Clock

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;
}
Also used : Format(androidx.media3.common.Format)

Example 2 with Clock

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));
}
Also used : Player(androidx.media3.common.Player) AnalyticsListener(androidx.media3.exoplayer.analytics.AnalyticsListener) TransferListener(androidx.media3.datasource.TransferListener) MediaSourceEventListener(androidx.media3.exoplayer.source.MediaSourceEventListener) Listener(androidx.media3.common.Player.Listener) DrmSessionEventListener(androidx.media3.exoplayer.drm.DrmSessionEventListener) FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) DiscontinuityReason(androidx.media3.common.Player.DiscontinuityReason) ActionSchedule(androidx.media3.test.utils.ActionSchedule) PlayerRunnable(androidx.media3.test.utils.ActionSchedule.PlayerRunnable) FakeClock(androidx.media3.test.utils.FakeClock) TestExoPlayerBuilder(androidx.media3.test.utils.TestExoPlayerBuilder) AtomicReference(java.util.concurrent.atomic.AtomicReference) FakeClock(androidx.media3.test.utils.FakeClock) Clock(androidx.media3.common.util.Clock) Listener(androidx.media3.common.Player.Listener) AtomicLong(java.util.concurrent.atomic.AtomicLong) CompositeMediaSource(androidx.media3.exoplayer.source.CompositeMediaSource) ClippingMediaSource(androidx.media3.exoplayer.source.ClippingMediaSource) FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) MaskingMediaSource(androidx.media3.exoplayer.source.MaskingMediaSource) ServerSideAdInsertionMediaSource(androidx.media3.exoplayer.source.ads.ServerSideAdInsertionMediaSource) FakeAdaptiveMediaSource(androidx.media3.test.utils.FakeAdaptiveMediaSource) ConcatenatingMediaSource(androidx.media3.exoplayer.source.ConcatenatingMediaSource) MediaSource(androidx.media3.exoplayer.source.MediaSource) ClippingMediaSource(androidx.media3.exoplayer.source.ClippingMediaSource) Test(org.junit.Test)

Example 3 with Clock

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);
}
Also used : SmtaMetadataEntry(androidx.media3.extractor.metadata.mp4.SmtaMetadataEntry) MediaItem(androidx.media3.common.MediaItem) SlowMotionData(androidx.media3.extractor.metadata.mp4.SlowMotionData) ArrayList(java.util.ArrayList) TrackGroupArray(androidx.media3.common.TrackGroupArray) MdtaMetadataEntry(androidx.media3.extractor.metadata.mp4.MdtaMetadataEntry) Test(org.junit.Test)

Example 4 with Clock

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();
}
Also used : MediaItem(androidx.media3.common.MediaItem) TrackGroupArray(androidx.media3.common.TrackGroupArray) Test(org.junit.Test)

Example 5 with Clock

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);
}
Also used : FakeClock(androidx.media3.test.utils.FakeClock) Before(org.junit.Before)

Aggregations

Test (org.junit.Test)17 MediaItem (androidx.media3.common.MediaItem)6 TrackGroupArray (androidx.media3.common.TrackGroupArray)6 ExoPlayer (androidx.media3.exoplayer.ExoPlayer)5 Clock (androidx.media3.common.util.Clock)4 FakeClock (androidx.media3.test.utils.FakeClock)4 FakeMediaClockRenderer (androidx.media3.test.utils.FakeMediaClockRenderer)4 Listener (androidx.media3.common.Player.Listener)3 Before (org.junit.Before)3 PlaybackParameters (androidx.media3.common.PlaybackParameters)2 Player (androidx.media3.common.Player)2 MediaSource (androidx.media3.exoplayer.source.MediaSource)2 FakeMediaSource (androidx.media3.test.utils.FakeMediaSource)2 TestExoPlayerBuilder (androidx.media3.test.utils.TestExoPlayerBuilder)2 ArrayList (java.util.ArrayList)2 HandlerThread (android.os.HandlerThread)1 VisibleForTesting (androidx.annotation.VisibleForTesting)1 AdPlaybackState (androidx.media3.common.AdPlaybackState)1 Format (androidx.media3.common.Format)1 PlaybackException (androidx.media3.common.PlaybackException)1