Search in sources :

Example 36 with TrackSelectorResult

use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project ExoPlayer by google.

the class MediaPeriodQueueTest method setupTimeline.

private void setupTimeline(Timeline timeline) {
    fakeMediaSource = new FakeMediaSource(timeline);
    MediaSourceList.MediaSourceHolder mediaSourceHolder = new MediaSourceList.MediaSourceHolder(fakeMediaSource, /* useLazyPreparation= */
    false);
    mediaSourceList.setMediaSources(ImmutableList.of(mediaSourceHolder), new FakeShuffleOrder(/* length= */
    1));
    mediaSourceHolder.mediaSource.prepareSource(mock(MediaSourceCaller.class), /* mediaTransferListener */
    null, PlayerId.UNSET);
    Timeline playlistTimeline = mediaSourceList.createTimeline();
    firstPeriodUid = playlistTimeline.getUidOfPeriod(/* periodIndex= */
    0);
    playbackInfo = new PlaybackInfo(playlistTimeline, mediaPeriodQueue.resolveMediaPeriodIdForAds(playlistTimeline, firstPeriodUid, /* positionUs= */
    0), /* requestedContentPositionUs= */
    C.TIME_UNSET, /* discontinuityStartPositionUs= */
    0, Player.STATE_READY, /* playbackError= */
    null, /* isLoading= */
    false, /* trackGroups= */
    null, /* trackSelectorResult= */
    null, /* staticMetadata= */
    ImmutableList.of(), /* loadingMediaPeriodId= */
    null, /* playWhenReady= */
    false, Player.PLAYBACK_SUPPRESSION_REASON_NONE, /* playbackParameters= */
    PlaybackParameters.DEFAULT, /* bufferedPositionUs= */
    0, /* totalBufferedDurationUs= */
    0, /* positionUs= */
    0, /* offloadSchedulingEnabled= */
    false, /* sleepingForOffload= */
    false);
}
Also used : MediaSourceCaller(com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller) SinglePeriodTimeline(com.google.android.exoplayer2.source.SinglePeriodTimeline) SinglePeriodAdTimeline(com.google.android.exoplayer2.source.ads.SinglePeriodAdTimeline) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) FakeShuffleOrder(com.google.android.exoplayer2.testutil.FakeShuffleOrder)

Example 37 with TrackSelectorResult

use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project Telegram-FOSS by Telegram-FOSS-Team.

the class ExoPlayerImplInternal method maybeUpdateReadingPeriod.

private void maybeUpdateReadingPeriod() throws ExoPlaybackException {
    MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
    if (readingPeriodHolder == null) {
        return;
    }
    if (readingPeriodHolder.getNext() == null) {
        // We don't have a successor to advance the reading period to.
        if (readingPeriodHolder.info.isFinal) {
            for (int i = 0; i < renderers.length; i++) {
                Renderer renderer = renderers[i];
                SampleStream sampleStream = readingPeriodHolder.sampleStreams[i];
                // stream in case of playlist changes that cause the stream to be no longer final.
                if (sampleStream != null && renderer.getStream() == sampleStream && renderer.hasReadStreamToEnd()) {
                    renderer.setCurrentStreamFinal();
                }
            }
        }
        return;
    }
    if (!hasReadingPeriodFinishedReading()) {
        return;
    }
    if (!readingPeriodHolder.getNext().prepared) {
        // The successor is not prepared yet.
        return;
    }
    TrackSelectorResult oldTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();
    readingPeriodHolder = queue.advanceReadingPeriod();
    TrackSelectorResult newTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();
    if (readingPeriodHolder.mediaPeriod.readDiscontinuity() != C.TIME_UNSET) {
        // The new period starts with a discontinuity, so the renderers will play out all data, then
        // be disabled and re-enabled when they start playing the next period.
        setAllRendererStreamsFinal();
        return;
    }
    for (int i = 0; i < renderers.length; i++) {
        Renderer renderer = renderers[i];
        boolean rendererWasEnabled = oldTrackSelectorResult.isRendererEnabled(i);
        if (rendererWasEnabled && !renderer.isCurrentStreamFinal()) {
            // The renderer is enabled and its stream is not final, so we still have a chance to replace
            // the sample streams.
            TrackSelection newSelection = newTrackSelectorResult.selections.get(i);
            boolean newRendererEnabled = newTrackSelectorResult.isRendererEnabled(i);
            boolean isNoSampleRenderer = rendererCapabilities[i].getTrackType() == C.TRACK_TYPE_NONE;
            RendererConfiguration oldConfig = oldTrackSelectorResult.rendererConfigurations[i];
            RendererConfiguration newConfig = newTrackSelectorResult.rendererConfigurations[i];
            if (newRendererEnabled && newConfig.equals(oldConfig) && !isNoSampleRenderer) {
                // Replace the renderer's SampleStream so the transition to playing the next period can
                // be seamless.
                // This should be avoided for no-sample renderer, because skipping ahead for such
                // renderer doesn't have any benefit (the renderer does not consume the sample stream),
                // and it will change the provided rendererOffsetUs while the renderer is still
                // rendering from the playing media period.
                Format[] formats = getFormats(newSelection);
                renderer.replaceStream(formats, readingPeriodHolder.sampleStreams[i], readingPeriodHolder.getRendererOffset());
            } else {
                // The renderer will be disabled when transitioning to playing the next period, because
                // there's no new selection, or because a configuration change is required, or because
                // it's a no-sample renderer for which rendererOffsetUs should be updated only when
                // starting to play the next period. Mark the SampleStream as final to play out any
                // remaining data.
                renderer.setCurrentStreamFinal();
            }
        }
    }
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult) TrackSelection(com.google.android.exoplayer2.trackselection.TrackSelection) SampleStream(com.google.android.exoplayer2.source.SampleStream)

Example 38 with TrackSelectorResult

use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project Telegram-FOSS by Telegram-FOSS-Team.

the class ExoPlayerImplInternal method enableRenderers.

private void enableRenderers(boolean[] rendererWasEnabledFlags, int totalEnabledRendererCount) throws ExoPlaybackException {
    enabledRenderers = new Renderer[totalEnabledRendererCount];
    int enabledRendererCount = 0;
    TrackSelectorResult trackSelectorResult = queue.getPlayingPeriod().getTrackSelectorResult();
    // by the disabled renderers will be available to renderers that are being enabled.
    for (int i = 0; i < renderers.length; i++) {
        if (!trackSelectorResult.isRendererEnabled(i)) {
            renderers[i].reset();
        }
    }
    // Enable the renderers.
    for (int i = 0; i < renderers.length; i++) {
        if (trackSelectorResult.isRendererEnabled(i)) {
            enableRenderer(i, rendererWasEnabledFlags[i], enabledRendererCount++);
        }
    }
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult)

Example 39 with TrackSelectorResult

use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project Telegram-FOSS by Telegram-FOSS-Team.

the class ExoPlayerImplInternal method reselectTracksInternal.

private void reselectTracksInternal() throws ExoPlaybackException {
    float playbackSpeed = mediaClock.getPlaybackParameters().speed;
    // Reselect tracks on each period in turn, until the selection changes.
    MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
    MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
    boolean selectionsChangedForReadPeriod = true;
    TrackSelectorResult newTrackSelectorResult;
    while (true) {
        if (periodHolder == null || !periodHolder.prepared) {
            // The reselection did not change any prepared periods.
            return;
        }
        newTrackSelectorResult = periodHolder.selectTracks(playbackSpeed, playbackInfo.timeline);
        if (!newTrackSelectorResult.isEquivalent(periodHolder.getTrackSelectorResult())) {
            // Selected tracks have changed for this period.
            break;
        }
        if (periodHolder == readingPeriodHolder) {
            // The track reselection didn't affect any period that has been read.
            selectionsChangedForReadPeriod = false;
        }
        periodHolder = periodHolder.getNext();
    }
    if (selectionsChangedForReadPeriod) {
        // Update streams and rebuffer for the new selection, recreating all streams if reading ahead.
        MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
        boolean recreateStreams = queue.removeAfter(playingPeriodHolder);
        boolean[] streamResetFlags = new boolean[renderers.length];
        long periodPositionUs = playingPeriodHolder.applyTrackSelection(newTrackSelectorResult, playbackInfo.positionUs, recreateStreams, streamResetFlags);
        if (playbackInfo.playbackState != Player.STATE_ENDED && periodPositionUs != playbackInfo.positionUs) {
            playbackInfo = copyWithNewPosition(playbackInfo.periodId, periodPositionUs, playbackInfo.contentPositionUs);
            playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL);
            resetRendererPosition(periodPositionUs);
        }
        int enabledRendererCount = 0;
        boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
        for (int i = 0; i < renderers.length; i++) {
            Renderer renderer = renderers[i];
            rendererWasEnabledFlags[i] = renderer.getState() != Renderer.STATE_DISABLED;
            SampleStream sampleStream = playingPeriodHolder.sampleStreams[i];
            if (sampleStream != null) {
                enabledRendererCount++;
            }
            if (rendererWasEnabledFlags[i]) {
                if (sampleStream != renderer.getStream()) {
                    // We need to disable the renderer.
                    disableRenderer(renderer);
                } else if (streamResetFlags[i]) {
                    // The renderer will continue to consume from its current stream, but needs to be reset.
                    renderer.resetPosition(rendererPositionUs);
                }
            }
        }
        playbackInfo = playbackInfo.copyWithTrackInfo(playingPeriodHolder.getTrackGroups(), playingPeriodHolder.getTrackSelectorResult());
        enableRenderers(rendererWasEnabledFlags, enabledRendererCount);
    } else {
        // Release and re-prepare/buffer periods after the one whose selection changed.
        queue.removeAfter(periodHolder);
        if (periodHolder.prepared) {
            long loadingPeriodPositionUs = Math.max(periodHolder.info.startPositionUs, periodHolder.toPeriodTime(rendererPositionUs));
            periodHolder.applyTrackSelection(newTrackSelectorResult, loadingPeriodPositionUs, false);
        }
    }
    handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */
    true);
    if (playbackInfo.playbackState != Player.STATE_ENDED) {
        maybeContinueLoading();
        updatePlaybackPositions();
        handler.sendEmptyMessage(MSG_DO_SOME_WORK);
    }
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult) SampleStream(com.google.android.exoplayer2.source.SampleStream)

Example 40 with TrackSelectorResult

use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project Telegram-FOSS by Telegram-FOSS-Team.

the class MediaPeriodHolder method handlePrepared.

/**
 * Handles period preparation.
 *
 * @param playbackSpeed The current playback speed.
 * @param timeline The current {@link Timeline}.
 * @throws ExoPlaybackException If an error occurs during track selection.
 */
public void handlePrepared(float playbackSpeed, Timeline timeline) throws ExoPlaybackException {
    prepared = true;
    trackGroups = mediaPeriod.getTrackGroups();
    TrackSelectorResult selectorResult = selectTracks(playbackSpeed, timeline);
    long newStartPositionUs = applyTrackSelection(selectorResult, info.startPositionUs, /* forceRecreateStreams= */
    false);
    rendererPositionOffsetUs += info.startPositionUs - newStartPositionUs;
    info = info.copyWithStartPositionUs(newStartPositionUs);
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult)

Aggregations

TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)62 Test (org.junit.Test)58 Format (com.google.android.exoplayer2.Format)47 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)30 TrackSelectorResult (com.google.android.exoplayer2.trackselection.TrackSelectorResult)17 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)12 HashMap (java.util.HashMap)8 ParametersBuilder (com.google.android.exoplayer2.trackselection.DefaultTrackSelector.ParametersBuilder)7 TrackSelectionOverride (com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride)6 SampleStream (com.google.android.exoplayer2.source.SampleStream)5 TrackSelection (com.google.android.exoplayer2.trackselection.TrackSelection)5 Nullable (androidx.annotation.Nullable)4 Capabilities (com.google.android.exoplayer2.RendererCapabilities.Capabilities)4 TextRenderer (com.google.android.exoplayer2.text.TextRenderer)4 ExoTrackSelection (com.google.android.exoplayer2.trackselection.ExoTrackSelection)3 ExoPlaybackException (com.google.android.exoplayer2.ExoPlaybackException)2 AdaptiveSupport (com.google.android.exoplayer2.RendererCapabilities.AdaptiveSupport)2 MediaPeriodId (com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)2 BaseTrackSelection (com.google.android.exoplayer2.trackselection.BaseTrackSelection)2 SelectionOverride (com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride)2