Search in sources :

Example 11 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class DefaultTrackSelector method selectTextTrack.

// Text track selection implementation.
protected TrackSelection selectTextTrack(TrackGroupArray groups, int[][] formatSupport, String preferredTextLanguage, String preferredAudioLanguage, boolean exceedRendererCapabilitiesIfNecessary) {
    TrackGroup selectedGroup = null;
    int selectedTrackIndex = 0;
    int selectedTrackScore = 0;
    for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
        TrackGroup trackGroup = groups.get(groupIndex);
        int[] trackFormatSupport = formatSupport[groupIndex];
        for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
            if (isSupported(trackFormatSupport[trackIndex], exceedRendererCapabilitiesIfNecessary)) {
                Format format = trackGroup.getFormat(trackIndex);
                boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
                boolean isForced = (format.selectionFlags & C.SELECTION_FLAG_FORCED) != 0;
                int trackScore;
                if (formatHasLanguage(format, preferredTextLanguage)) {
                    if (isDefault) {
                        trackScore = 6;
                    } else if (!isForced) {
                        // Prefer non-forced to forced if a preferred text language has been specified. Where
                        // both are provided the non-forced track will usually contain the forced subtitles as
                        // a subset.
                        trackScore = 5;
                    } else {
                        trackScore = 4;
                    }
                } else if (isDefault) {
                    trackScore = 3;
                } else if (isForced) {
                    if (formatHasLanguage(format, preferredAudioLanguage)) {
                        trackScore = 2;
                    } else {
                        trackScore = 1;
                    }
                } else {
                    // Track should not be selected.
                    continue;
                }
                if (isSupported(trackFormatSupport[trackIndex], false)) {
                    trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
                }
                if (trackScore > selectedTrackScore) {
                    selectedGroup = trackGroup;
                    selectedTrackIndex = trackIndex;
                    selectedTrackScore = trackScore;
                }
            }
        }
    }
    return selectedGroup == null ? null : new FixedTrackSelection(selectedGroup, selectedTrackIndex);
}
Also used : Format(com.google.android.exoplayer2.Format) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) Point(android.graphics.Point)

Example 12 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class DefaultTrackSelector method selectAdaptiveVideoTrack.

private static TrackSelection selectAdaptiveVideoTrack(RendererCapabilities rendererCapabilities, TrackGroupArray groups, int[][] formatSupport, int maxVideoWidth, int maxVideoHeight, int maxVideoBitrate, boolean allowNonSeamlessAdaptiveness, boolean allowMixedMimeAdaptiveness, int viewportWidth, int viewportHeight, boolean orientationMayChange, TrackSelection.Factory adaptiveVideoTrackSelectionFactory) throws ExoPlaybackException {
    int requiredAdaptiveSupport = allowNonSeamlessAdaptiveness ? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS | RendererCapabilities.ADAPTIVE_SEAMLESS) : RendererCapabilities.ADAPTIVE_SEAMLESS;
    boolean allowMixedMimeTypes = allowMixedMimeAdaptiveness && (rendererCapabilities.supportsMixedMimeTypeAdaptation() & requiredAdaptiveSupport) != 0;
    for (int i = 0; i < groups.length; i++) {
        TrackGroup group = groups.get(i);
        int[] adaptiveTracks = getAdaptiveTracksForGroup(group, formatSupport[i], allowMixedMimeTypes, requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight, maxVideoBitrate, viewportWidth, viewportHeight, orientationMayChange);
        if (adaptiveTracks.length > 0) {
            return adaptiveVideoTrackSelectionFactory.createTrackSelection(group, adaptiveTracks);
        }
    }
    return null;
}
Also used : TrackGroup(com.google.android.exoplayer2.source.TrackGroup) Point(android.graphics.Point)

Example 13 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class DefaultTrackSelector method selectFixedVideoTrack.

private static TrackSelection selectFixedVideoTrack(TrackGroupArray groups, int[][] formatSupport, int maxVideoWidth, int maxVideoHeight, int maxVideoBitrate, int viewportWidth, int viewportHeight, boolean orientationMayChange, boolean exceedConstraintsIfNecessary, boolean exceedRendererCapabilitiesIfNecessary) {
    TrackGroup selectedGroup = null;
    int selectedTrackIndex = 0;
    int selectedTrackScore = 0;
    int selectedBitrate = Format.NO_VALUE;
    int selectedPixelCount = Format.NO_VALUE;
    for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
        TrackGroup trackGroup = groups.get(groupIndex);
        List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(trackGroup, viewportWidth, viewportHeight, orientationMayChange);
        int[] trackFormatSupport = formatSupport[groupIndex];
        for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
            if (isSupported(trackFormatSupport[trackIndex], exceedRendererCapabilitiesIfNecessary)) {
                Format format = trackGroup.getFormat(trackIndex);
                boolean isWithinConstraints = selectedTrackIndices.contains(trackIndex) && (format.width == Format.NO_VALUE || format.width <= maxVideoWidth) && (format.height == Format.NO_VALUE || format.height <= maxVideoHeight) && (format.bitrate == Format.NO_VALUE || format.bitrate <= maxVideoBitrate);
                if (!isWithinConstraints && !exceedConstraintsIfNecessary) {
                    // Track should not be selected.
                    continue;
                }
                int trackScore = isWithinConstraints ? 2 : 1;
                if (isSupported(trackFormatSupport[trackIndex], false)) {
                    trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
                }
                boolean selectTrack = trackScore > selectedTrackScore;
                if (trackScore == selectedTrackScore) {
                    // Use the pixel count as a tie breaker (or bitrate if pixel counts are tied). If we're
                    // within constraints prefer a higher pixel count (or bitrate), else prefer a lower
                    // count (or bitrate). If still tied then prefer the first track (i.e. the one that's
                    // already selected).
                    int comparisonResult;
                    int formatPixelCount = format.getPixelCount();
                    if (formatPixelCount != selectedPixelCount) {
                        comparisonResult = compareFormatValues(format.getPixelCount(), selectedPixelCount);
                    } else {
                        comparisonResult = compareFormatValues(format.bitrate, selectedBitrate);
                    }
                    selectTrack = isWithinConstraints ? comparisonResult > 0 : comparisonResult < 0;
                }
                if (selectTrack) {
                    selectedGroup = trackGroup;
                    selectedTrackIndex = trackIndex;
                    selectedTrackScore = trackScore;
                    selectedBitrate = format.bitrate;
                    selectedPixelCount = format.getPixelCount();
                }
            }
        }
    }
    return selectedGroup == null ? null : new FixedTrackSelection(selectedGroup, selectedTrackIndex);
}
Also used : Format(com.google.android.exoplayer2.Format) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) Point(android.graphics.Point)

Example 14 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class DefaultTrackSelector method getViewportFilteredTrackIndices.

// Viewport size util methods.
private static List<Integer> getViewportFilteredTrackIndices(TrackGroup group, int viewportWidth, int viewportHeight, boolean orientationMayChange) {
    // Initially include all indices.
    ArrayList<Integer> selectedTrackIndices = new ArrayList<>(group.length);
    for (int i = 0; i < group.length; i++) {
        selectedTrackIndices.add(i);
    }
    if (viewportWidth == Integer.MAX_VALUE || viewportHeight == Integer.MAX_VALUE) {
        // Viewport dimensions not set. Return the full set of indices.
        return selectedTrackIndices;
    }
    int maxVideoPixelsToRetain = Integer.MAX_VALUE;
    for (int i = 0; i < group.length; i++) {
        Format format = group.getFormat(i);
        // We'll discard formats of higher resolution.
        if (format.width > 0 && format.height > 0) {
            Point maxVideoSizeInViewport = getMaxVideoSizeInViewport(orientationMayChange, viewportWidth, viewportHeight, format.width, format.height);
            int videoPixels = format.width * format.height;
            if (format.width >= (int) (maxVideoSizeInViewport.x * FRACTION_TO_CONSIDER_FULLSCREEN) && format.height >= (int) (maxVideoSizeInViewport.y * FRACTION_TO_CONSIDER_FULLSCREEN) && videoPixels < maxVideoPixelsToRetain) {
                maxVideoPixelsToRetain = videoPixels;
            }
        }
    }
    // filter out formats with unknown dimensions, since we have some whose dimensions are known.
    if (maxVideoPixelsToRetain != Integer.MAX_VALUE) {
        for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) {
            Format format = group.getFormat(selectedTrackIndices.get(i));
            int pixelCount = format.getPixelCount();
            if (pixelCount == Format.NO_VALUE || pixelCount > maxVideoPixelsToRetain) {
                selectedTrackIndices.remove(i);
            }
        }
    }
    return selectedTrackIndices;
}
Also used : Format(com.google.android.exoplayer2.Format) ArrayList(java.util.ArrayList) Point(android.graphics.Point) Point(android.graphics.Point)

Example 15 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup 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)

Aggregations

TrackGroup (com.google.android.exoplayer2.source.TrackGroup)13 Format (com.google.android.exoplayer2.Format)8 Point (android.graphics.Point)6 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)6 TrackSelection (com.google.android.exoplayer2.trackselection.TrackSelection)2 ArrayList (java.util.ArrayList)2 SuppressLint (android.annotation.SuppressLint)1 TypedArray (android.content.res.TypedArray)1 LayoutInflater (android.view.LayoutInflater)1 View (android.view.View)1 ViewGroup (android.view.ViewGroup)1 CheckedTextView (android.widget.CheckedTextView)1 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)1 RendererConfiguration (com.google.android.exoplayer2.RendererConfiguration)1 Metadata (com.google.android.exoplayer2.metadata.Metadata)1 CompositeSequenceableLoader (com.google.android.exoplayer2.source.CompositeSequenceableLoader)1 MediaSource (com.google.android.exoplayer2.source.MediaSource)1 SampleStream (com.google.android.exoplayer2.source.SampleStream)1 AdaptationSet (com.google.android.exoplayer2.source.dash.manifest.AdaptationSet)1 Representation (com.google.android.exoplayer2.source.dash.manifest.Representation)1