Search in sources :

Example 41 with TrackSelectorResult

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

the class MappingTrackSelector method selectTracks.

@Override
public final TrackSelectorResult selectTracks(RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups, MediaPeriodId periodId, Timeline timeline) throws ExoPlaybackException {
    // Structures into which data will be written during the selection. The extra item at the end
    // of each array is to store data associated with track groups that cannot be associated with
    // any renderer.
    int[] rendererTrackGroupCounts = new int[rendererCapabilities.length + 1];
    TrackGroup[][] rendererTrackGroups = new TrackGroup[rendererCapabilities.length + 1][];
    @Capabilities int[][][] rendererFormatSupports = new int[rendererCapabilities.length + 1][][];
    for (int i = 0; i < rendererTrackGroups.length; i++) {
        rendererTrackGroups[i] = new TrackGroup[trackGroups.length];
        rendererFormatSupports[i] = new int[trackGroups.length][];
    }
    // Determine the extent to which each renderer supports mixed mimeType adaptation.
    @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports = getMixedMimeTypeAdaptationSupports(rendererCapabilities);
    // renderer provides for each track in the group.
    for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
        TrackGroup group = trackGroups.get(groupIndex);
        // Associate the group to a preferred renderer.
        boolean preferUnassociatedRenderer = MimeTypes.getTrackType(group.getFormat(0).sampleMimeType) == C.TRACK_TYPE_METADATA;
        int rendererIndex = findRenderer(rendererCapabilities, group, rendererTrackGroupCounts, preferUnassociatedRenderer);
        // Evaluate the support that the renderer provides for each track in the group.
        @Capabilities int[] rendererFormatSupport = rendererIndex == rendererCapabilities.length ? new int[group.length] : getFormatSupport(rendererCapabilities[rendererIndex], group);
        // Stash the results.
        int rendererTrackGroupCount = rendererTrackGroupCounts[rendererIndex];
        rendererTrackGroups[rendererIndex][rendererTrackGroupCount] = group;
        rendererFormatSupports[rendererIndex][rendererTrackGroupCount] = rendererFormatSupport;
        rendererTrackGroupCounts[rendererIndex]++;
    }
    // Create a track group array for each renderer, and trim each rendererFormatSupports entry.
    TrackGroupArray[] rendererTrackGroupArrays = new TrackGroupArray[rendererCapabilities.length];
    int[] rendererTrackTypes = new int[rendererCapabilities.length];
    for (int i = 0; i < rendererCapabilities.length; i++) {
        int rendererTrackGroupCount = rendererTrackGroupCounts[i];
        rendererTrackGroupArrays[i] = new TrackGroupArray(Util.nullSafeArrayCopy(rendererTrackGroups[i], rendererTrackGroupCount));
        rendererFormatSupports[i] = Util.nullSafeArrayCopy(rendererFormatSupports[i], rendererTrackGroupCount);
        rendererTrackTypes[i] = rendererCapabilities[i].getTrackType();
    }
    // Create a track group array for track groups not mapped to a renderer.
    int unmappedTrackGroupCount = rendererTrackGroupCounts[rendererCapabilities.length];
    TrackGroupArray unmappedTrackGroupArray = new TrackGroupArray(Util.nullSafeArrayCopy(rendererTrackGroups[rendererCapabilities.length], unmappedTrackGroupCount));
    // Package up the track information and selections.
    MappedTrackInfo mappedTrackInfo = new MappedTrackInfo(rendererTrackTypes, rendererTrackGroupArrays, rendererMixedMimeTypeAdaptationSupports, rendererFormatSupports, unmappedTrackGroupArray);
    Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> result = selectTracks(mappedTrackInfo, rendererFormatSupports, rendererMixedMimeTypeAdaptationSupports);
    return new TrackSelectorResult(result.first, result.second, mappedTrackInfo);
}
Also used : TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) NullableType(org.checkerframework.checker.nullness.compatqual.NullableType) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) Capabilities(com.google.android.exoplayer2.RendererCapabilities.Capabilities) RendererCapabilities(com.google.android.exoplayer2.RendererCapabilities) AdaptiveSupport(com.google.android.exoplayer2.RendererCapabilities.AdaptiveSupport)

Example 42 with TrackSelectorResult

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

the class MediaPeriodHolder method handlePrepared.

/**
 * Handles period preparation.
 *
 * @param playbackSpeed The current factor by which playback is sped up.
 * @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 requestedStartPositionUs = info.startPositionUs;
    if (info.durationUs != C.TIME_UNSET && requestedStartPositionUs >= info.durationUs) {
        // Make sure start position doesn't exceed period duration.
        requestedStartPositionUs = max(0, info.durationUs - 1);
    }
    long newStartPositionUs = applyTrackSelection(selectorResult, requestedStartPositionUs, /* forceRecreateStreams= */
    false);
    rendererPositionOffsetUs += info.startPositionUs - newStartPositionUs;
    info = info.copyWithStartPositionUs(newStartPositionUs);
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult)

Example 43 with TrackSelectorResult

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

the class MappingTrackSelector method selectTracks.

@Override
public final TrackSelectorResult selectTracks(RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups, MediaPeriodId periodId, Timeline timeline) throws ExoPlaybackException {
    // Structures into which data will be written during the selection. The extra item at the end
    // of each array is to store data associated with track groups that cannot be associated with
    // any renderer.
    int[] rendererTrackGroupCounts = new int[rendererCapabilities.length + 1];
    TrackGroup[][] rendererTrackGroups = new TrackGroup[rendererCapabilities.length + 1][];
    @Capabilities int[][][] rendererFormatSupports = new int[rendererCapabilities.length + 1][][];
    for (int i = 0; i < rendererTrackGroups.length; i++) {
        rendererTrackGroups[i] = new TrackGroup[trackGroups.length];
        rendererFormatSupports[i] = new int[trackGroups.length][];
    }
    // Determine the extent to which each renderer supports mixed mimeType adaptation.
    @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports = getMixedMimeTypeAdaptationSupports(rendererCapabilities);
    // renderer provides for each track in the group.
    for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
        TrackGroup group = trackGroups.get(groupIndex);
        // Associate the group to a preferred renderer.
        boolean preferUnassociatedRenderer = MimeTypes.getTrackType(group.getFormat(0).sampleMimeType) == C.TRACK_TYPE_METADATA;
        int rendererIndex = findRenderer(rendererCapabilities, group, rendererTrackGroupCounts, preferUnassociatedRenderer);
        // Evaluate the support that the renderer provides for each track in the group.
        @Capabilities int[] rendererFormatSupport = rendererIndex == rendererCapabilities.length ? new int[group.length] : getFormatSupport(rendererCapabilities[rendererIndex], group);
        // Stash the results.
        int rendererTrackGroupCount = rendererTrackGroupCounts[rendererIndex];
        rendererTrackGroups[rendererIndex][rendererTrackGroupCount] = group;
        rendererFormatSupports[rendererIndex][rendererTrackGroupCount] = rendererFormatSupport;
        rendererTrackGroupCounts[rendererIndex]++;
    }
    // Create a track group array for each renderer, and trim each rendererFormatSupports entry.
    TrackGroupArray[] rendererTrackGroupArrays = new TrackGroupArray[rendererCapabilities.length];
    String[] rendererNames = new String[rendererCapabilities.length];
    int[] rendererTrackTypes = new int[rendererCapabilities.length];
    for (int i = 0; i < rendererCapabilities.length; i++) {
        int rendererTrackGroupCount = rendererTrackGroupCounts[i];
        rendererTrackGroupArrays[i] = new TrackGroupArray(Util.nullSafeArrayCopy(rendererTrackGroups[i], rendererTrackGroupCount));
        rendererFormatSupports[i] = Util.nullSafeArrayCopy(rendererFormatSupports[i], rendererTrackGroupCount);
        rendererNames[i] = rendererCapabilities[i].getName();
        rendererTrackTypes[i] = rendererCapabilities[i].getTrackType();
    }
    // Create a track group array for track groups not mapped to a renderer.
    int unmappedTrackGroupCount = rendererTrackGroupCounts[rendererCapabilities.length];
    TrackGroupArray unmappedTrackGroupArray = new TrackGroupArray(Util.nullSafeArrayCopy(rendererTrackGroups[rendererCapabilities.length], unmappedTrackGroupCount));
    // Package up the track information and selections.
    MappedTrackInfo mappedTrackInfo = new MappedTrackInfo(rendererNames, rendererTrackTypes, rendererTrackGroupArrays, rendererMixedMimeTypeAdaptationSupports, rendererFormatSupports, unmappedTrackGroupArray);
    Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]> result = selectTracks(mappedTrackInfo, rendererFormatSupports, rendererMixedMimeTypeAdaptationSupports, periodId, timeline);
    TracksInfo tracksInfo = buildTracksInfo(result.second, mappedTrackInfo);
    return new TrackSelectorResult(result.first, result.second, tracksInfo, mappedTrackInfo);
}
Also used : TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) NullableType(org.checkerframework.checker.nullness.compatqual.NullableType) TracksInfo(com.google.android.exoplayer2.TracksInfo) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) RendererCapabilities(com.google.android.exoplayer2.RendererCapabilities) Capabilities(com.google.android.exoplayer2.RendererCapabilities.Capabilities) AdaptiveSupport(com.google.android.exoplayer2.RendererCapabilities.AdaptiveSupport)

Example 44 with TrackSelectorResult

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

the class ExoPlayerImplInternal method maybeUpdateReadingPeriod.

private void maybeUpdateReadingPeriod() {
    @Nullable MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
    if (readingPeriodHolder == null) {
        return;
    }
    if (readingPeriodHolder.getNext() == null || pendingPauseAtEndOfPeriod) {
        // intentionally to pause at the end of the period.
        if (readingPeriodHolder.info.isFinal || pendingPauseAtEndOfPeriod) {
            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()) {
                    long streamEndPositionUs = readingPeriodHolder.info.durationUs != C.TIME_UNSET && readingPeriodHolder.info.durationUs != C.TIME_END_OF_SOURCE ? readingPeriodHolder.getRendererOffset() + readingPeriodHolder.info.durationUs : C.TIME_UNSET;
                    setCurrentStreamFinal(renderer, streamEndPositionUs);
                }
            }
        }
        return;
    }
    if (!hasReadingPeriodFinishedReading()) {
        return;
    }
    if (!readingPeriodHolder.getNext().prepared && rendererPositionUs < readingPeriodHolder.getNext().getStartPositionRendererTime()) {
        // The successor is not prepared yet and playback hasn't reached the transition point.
        return;
    }
    MediaPeriodHolder oldReadingPeriodHolder = readingPeriodHolder;
    TrackSelectorResult oldTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();
    readingPeriodHolder = queue.advanceReadingPeriod();
    TrackSelectorResult newTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();
    updatePlaybackSpeedSettingsForNewPeriod(/* newTimeline= */
    playbackInfo.timeline, /* newPeriodId= */
    readingPeriodHolder.info.id, /* oldTimeline= */
    playbackInfo.timeline, /* oldPeriodId= */
    oldReadingPeriodHolder.info.id, /* positionForTargetOffsetOverrideUs= */
    C.TIME_UNSET);
    if (readingPeriodHolder.prepared && 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(/* streamEndPositionUs= */
        readingPeriodHolder.getStartPositionRendererTime());
        return;
    }
    for (int i = 0; i < renderers.length; i++) {
        boolean oldRendererEnabled = oldTrackSelectorResult.isRendererEnabled(i);
        boolean newRendererEnabled = newTrackSelectorResult.isRendererEnabled(i);
        if (oldRendererEnabled && !renderers[i].isCurrentStreamFinal()) {
            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) {
                // 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.
                setCurrentStreamFinal(renderers[i], /* streamEndPositionUs= */
                readingPeriodHolder.getStartPositionRendererTime());
            }
        }
    }
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult) TextRenderer(com.google.android.exoplayer2.text.TextRenderer) Nullable(androidx.annotation.Nullable) SampleStream(com.google.android.exoplayer2.source.SampleStream)

Example 45 with TrackSelectorResult

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

the class ExoPlayerImplInternal method handlePositionDiscontinuity.

@CheckResult
private PlaybackInfo handlePositionDiscontinuity(MediaPeriodId mediaPeriodId, long positionUs, long requestedContentPositionUs, long discontinuityStartPositionUs, boolean reportDiscontinuity, @DiscontinuityReason int discontinuityReason) {
    deliverPendingMessageAtStartPositionRequired = deliverPendingMessageAtStartPositionRequired || positionUs != playbackInfo.positionUs || !mediaPeriodId.equals(playbackInfo.periodId);
    resetPendingPauseAtEndOfPeriod();
    TrackGroupArray trackGroupArray = playbackInfo.trackGroups;
    TrackSelectorResult trackSelectorResult = playbackInfo.trackSelectorResult;
    List<Metadata> staticMetadata = playbackInfo.staticMetadata;
    if (mediaSourceList.isPrepared()) {
        @Nullable MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
        trackGroupArray = playingPeriodHolder == null ? TrackGroupArray.EMPTY : playingPeriodHolder.getTrackGroups();
        trackSelectorResult = playingPeriodHolder == null ? emptyTrackSelectorResult : playingPeriodHolder.getTrackSelectorResult();
        staticMetadata = extractMetadataFromTrackSelectionArray(trackSelectorResult.selections);
        // Ensure the media period queue requested content position matches the new playback info.
        if (playingPeriodHolder != null && playingPeriodHolder.info.requestedContentPositionUs != requestedContentPositionUs) {
            playingPeriodHolder.info = playingPeriodHolder.info.copyWithRequestedContentPositionUs(requestedContentPositionUs);
        }
    } else if (!mediaPeriodId.equals(playbackInfo.periodId)) {
        // Reset previously kept track info if unprepared and the period changes.
        trackGroupArray = TrackGroupArray.EMPTY;
        trackSelectorResult = emptyTrackSelectorResult;
        staticMetadata = ImmutableList.of();
    }
    if (reportDiscontinuity) {
        playbackInfoUpdate.setPositionDiscontinuity(discontinuityReason);
    }
    return playbackInfo.copyWithNewPosition(mediaPeriodId, positionUs, requestedContentPositionUs, discontinuityStartPositionUs, getTotalBufferedDurationUs(), trackGroupArray, trackSelectorResult, staticMetadata);
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) Metadata(com.google.android.exoplayer2.metadata.Metadata) Nullable(androidx.annotation.Nullable) CheckResult(androidx.annotation.CheckResult)

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