Search in sources :

Example 76 with TrackSelectorResult

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

the class MappingTrackSelector method selectTracks.

// TrackSelector implementation.
@Override
public final TrackSelectorResult selectTracks(RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups) 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][];
    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.
    int[] mixedMimeTypeAdaptationSupport = getMixedMimeTypeAdaptationSupport(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.
        int rendererIndex = findRenderer(rendererCapabilities, group);
        // Evaluate the support that the renderer provides for each track in the group.
        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(Arrays.copyOf(rendererTrackGroups[i], rendererTrackGroupCount));
        rendererFormatSupports[i] = Arrays.copyOf(rendererFormatSupports[i], rendererTrackGroupCount);
        rendererTrackTypes[i] = rendererCapabilities[i].getTrackType();
    }
    // Create a track group array for track groups not associated with a renderer.
    int unassociatedTrackGroupCount = rendererTrackGroupCounts[rendererCapabilities.length];
    TrackGroupArray unassociatedTrackGroupArray = new TrackGroupArray(Arrays.copyOf(rendererTrackGroups[rendererCapabilities.length], unassociatedTrackGroupCount));
    TrackSelection[] trackSelections = selectTracks(rendererCapabilities, rendererTrackGroupArrays, rendererFormatSupports);
    // Apply track disabling and overriding.
    for (int i = 0; i < rendererCapabilities.length; i++) {
        if (rendererDisabledFlags.get(i)) {
            trackSelections[i] = null;
        } else {
            TrackGroupArray rendererTrackGroup = rendererTrackGroupArrays[i];
            Map<TrackGroupArray, SelectionOverride> overrides = selectionOverrides.get(i);
            SelectionOverride override = overrides == null ? null : overrides.get(rendererTrackGroup);
            if (override != null) {
                trackSelections[i] = override.createTrackSelection(rendererTrackGroup);
            }
        }
    }
    // Package up the track information and selections.
    MappedTrackInfo mappedTrackInfo = new MappedTrackInfo(rendererTrackTypes, rendererTrackGroupArrays, mixedMimeTypeAdaptationSupport, rendererFormatSupports, unassociatedTrackGroupArray);
    // Initialize the renderer configurations to the default configuration for all renderers with
    // selections, and null otherwise.
    RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCapabilities.length];
    for (int i = 0; i < rendererCapabilities.length; i++) {
        rendererConfigurations[i] = trackSelections[i] != null ? RendererConfiguration.DEFAULT : null;
    }
    // Configure audio and video renderers to use tunneling if appropriate.
    maybeConfigureRenderersForTunneling(rendererCapabilities, rendererTrackGroupArrays, rendererFormatSupports, rendererConfigurations, trackSelections, tunnelingAudioSessionId);
    return new TrackSelectorResult(trackGroups, new TrackSelectionArray(trackSelections), mappedTrackInfo, rendererConfigurations);
}
Also used : TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) RendererConfiguration(com.google.android.exoplayer2.RendererConfiguration)

Example 77 with TrackSelectorResult

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

the class DownloadHelper method onMediaPrepared.

// Initialization of array of Lists.
@SuppressWarnings("unchecked")
private void onMediaPrepared() {
    Assertions.checkNotNull(mediaPreparer);
    Assertions.checkNotNull(mediaPreparer.mediaPeriods);
    Assertions.checkNotNull(mediaPreparer.timeline);
    int periodCount = mediaPreparer.mediaPeriods.length;
    int rendererCount = rendererCapabilities.length;
    trackSelectionsByPeriodAndRenderer = (List<TrackSelection>[][]) new List<?>[periodCount][rendererCount];
    immutableTrackSelectionsByPeriodAndRenderer = (List<TrackSelection>[][]) new List<?>[periodCount][rendererCount];
    for (int i = 0; i < periodCount; i++) {
        for (int j = 0; j < rendererCount; j++) {
            trackSelectionsByPeriodAndRenderer[i][j] = new ArrayList<>();
            immutableTrackSelectionsByPeriodAndRenderer[i][j] = Collections.unmodifiableList(trackSelectionsByPeriodAndRenderer[i][j]);
        }
    }
    trackGroupArrays = new TrackGroupArray[periodCount];
    mappedTrackInfos = new MappedTrackInfo[periodCount];
    for (int i = 0; i < periodCount; i++) {
        trackGroupArrays[i] = mediaPreparer.mediaPeriods[i].getTrackGroups();
        TrackSelectorResult trackSelectorResult = runTrackSelection(/* periodIndex= */
        i);
        trackSelector.onSelectionActivated(trackSelectorResult.info);
        mappedTrackInfos[i] = Assertions.checkNotNull(trackSelector.getCurrentMappedTrackInfo());
    }
    setPreparedWithMedia();
    Assertions.checkNotNull(callbackHandler).post(() -> Assertions.checkNotNull(callback).onPrepared(this));
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult) ArrayList(java.util.ArrayList) List(java.util.List) TrackSelection(com.google.android.exoplayer2.trackselection.TrackSelection) BaseTrackSelection(com.google.android.exoplayer2.trackselection.BaseTrackSelection)

Example 78 with TrackSelectorResult

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

the class DownloadHelper method runTrackSelection.

/**
 * Runs the track selection for a given period index with the current parameters. The selected
 * tracks will be added to {@link #trackSelectionsByPeriodAndRenderer}.
 */
// Intentional reference comparison of track group instances.
@SuppressWarnings("ReferenceEquality")
@RequiresNonNull({ "trackGroupArrays", "trackSelectionsByPeriodAndRenderer", "mediaPreparer", "mediaPreparer.timeline" })
private TrackSelectorResult runTrackSelection(int periodIndex) {
    try {
        TrackSelectorResult trackSelectorResult = trackSelector.selectTracks(rendererCapabilities, trackGroupArrays[periodIndex], new MediaPeriodId(mediaPreparer.timeline.getUidOfPeriod(periodIndex)), mediaPreparer.timeline);
        for (int i = 0; i < trackSelectorResult.length; i++) {
            @Nullable TrackSelection newSelection = trackSelectorResult.selections.get(i);
            if (newSelection == null) {
                continue;
            }
            List<TrackSelection> existingSelectionList = trackSelectionsByPeriodAndRenderer[periodIndex][i];
            boolean mergedWithExistingSelection = false;
            for (int j = 0; j < existingSelectionList.size(); j++) {
                TrackSelection existingSelection = existingSelectionList.get(j);
                if (existingSelection.getTrackGroup() == newSelection.getTrackGroup()) {
                    // Merge with existing selection.
                    scratchSet.clear();
                    for (int k = 0; k < existingSelection.length(); k++) {
                        scratchSet.put(existingSelection.getIndexInTrackGroup(k), 0);
                    }
                    for (int k = 0; k < newSelection.length(); k++) {
                        scratchSet.put(newSelection.getIndexInTrackGroup(k), 0);
                    }
                    int[] mergedTracks = new int[scratchSet.size()];
                    for (int k = 0; k < scratchSet.size(); k++) {
                        mergedTracks[k] = scratchSet.keyAt(k);
                    }
                    existingSelectionList.set(j, new DownloadTrackSelection(existingSelection.getTrackGroup(), mergedTracks));
                    mergedWithExistingSelection = true;
                    break;
                }
            }
            if (!mergedWithExistingSelection) {
                existingSelectionList.add(newSelection);
            }
        }
        return trackSelectorResult;
    } catch (ExoPlaybackException e) {
        // DefaultTrackSelector does not throw exceptions during track selection.
        throw new UnsupportedOperationException(e);
    }
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) ExoPlaybackException(com.google.android.exoplayer2.ExoPlaybackException) TrackSelection(com.google.android.exoplayer2.trackselection.TrackSelection) BaseTrackSelection(com.google.android.exoplayer2.trackselection.BaseTrackSelection) Nullable(androidx.annotation.Nullable) RequiresNonNull(org.checkerframework.checker.nullness.qual.RequiresNonNull)

Example 79 with TrackSelectorResult

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

the class ExoPlayerImplInternal method enableRenderer.

private void enableRenderer(int rendererIndex, boolean wasRendererEnabled, int enabledRendererIndex) throws ExoPlaybackException {
    MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
    Renderer renderer = renderers[rendererIndex];
    enabledRenderers[enabledRendererIndex] = renderer;
    if (renderer.getState() == Renderer.STATE_DISABLED) {
        TrackSelectorResult trackSelectorResult = playingPeriodHolder.getTrackSelectorResult();
        RendererConfiguration rendererConfiguration = trackSelectorResult.rendererConfigurations[rendererIndex];
        TrackSelection newSelection = trackSelectorResult.selections.get(rendererIndex);
        Format[] formats = getFormats(newSelection);
        // The renderer needs enabling with its new track selection.
        boolean playing = playWhenReady && playbackInfo.playbackState == Player.STATE_READY;
        // Consider as joining only if the renderer was previously disabled.
        boolean joining = !wasRendererEnabled && playing;
        // Enable the renderer.
        renderer.enable(rendererConfiguration, formats, playingPeriodHolder.sampleStreams[rendererIndex], rendererPositionUs, joining, playingPeriodHolder.getRendererOffset());
        mediaClock.onRendererEnabled(renderer);
        // Start the renderer if playing.
        if (playing) {
            renderer.start();
        }
    }
}
Also used : TrackSelectorResult(com.google.android.exoplayer2.trackselection.TrackSelectorResult) TrackSelection(com.google.android.exoplayer2.trackselection.TrackSelection)

Example 80 with TrackSelectorResult

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

the class MediaPeriodHolder method applyTrackSelection.

/**
 * Applies a {@link TrackSelectorResult} to the period.
 *
 * @param newTrackSelectorResult The {@link TrackSelectorResult} to apply.
 * @param positionUs The position relative to the start of the period at which to apply the new
 *     track selections, in microseconds.
 * @param forceRecreateStreams Whether all streams are forced to be recreated.
 * @param streamResetFlags Will be populated to indicate which streams have been reset or were
 *     newly created.
 * @return The actual position relative to the start of the period at which the new track
 *     selections are applied.
 */
public long applyTrackSelection(TrackSelectorResult newTrackSelectorResult, long positionUs, boolean forceRecreateStreams, boolean[] streamResetFlags) {
    for (int i = 0; i < newTrackSelectorResult.length; i++) {
        mayRetainStreamFlags[i] = !forceRecreateStreams && newTrackSelectorResult.isEquivalent(trackSelectorResult, i);
    }
    // Undo the effect of previous call to associate no-sample renderers with empty tracks
    // so the mediaPeriod receives back whatever it sent us before.
    disassociateNoSampleRenderersWithEmptySampleStream(sampleStreams);
    disableTrackSelectionsInResult();
    trackSelectorResult = newTrackSelectorResult;
    enableTrackSelectionsInResult();
    // Disable streams on the period and get new streams for updated/newly-enabled tracks.
    TrackSelectionArray trackSelections = newTrackSelectorResult.selections;
    positionUs = mediaPeriod.selectTracks(trackSelections.getAll(), mayRetainStreamFlags, sampleStreams, streamResetFlags, positionUs);
    associateNoSampleRenderersWithEmptySampleStream(sampleStreams);
    // Update whether we have enabled tracks and sanity check the expected streams are non-null.
    hasEnabledTracks = false;
    for (int i = 0; i < sampleStreams.length; i++) {
        if (sampleStreams[i] != null) {
            Assertions.checkState(newTrackSelectorResult.isRendererEnabled(i));
            // hasEnabledTracks should be true only when non-empty streams exists.
            if (rendererCapabilities[i].getTrackType() != C.TRACK_TYPE_NONE) {
                hasEnabledTracks = true;
            }
        } else {
            Assertions.checkState(trackSelections.get(i) == null);
        }
    }
    return positionUs;
}
Also used : TrackSelectionArray(com.google.android.exoplayer2.trackselection.TrackSelectionArray)

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