Search in sources :

Example 16 with TrackGroupArray

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

the class MetadataRetriever method retrieveMetadata.

@VisibleForTesting
static /* package */
ListenableFuture<TrackGroupArray> retrieveMetadata(Context context, MediaItem mediaItem, Clock clock) {
    ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory().setMp4ExtractorFlags(Mp4Extractor.FLAG_READ_MOTION_PHOTO_METADATA | Mp4Extractor.FLAG_READ_SEF_DATA);
    MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(context, extractorsFactory);
    return retrieveMetadata(mediaSourceFactory, mediaItem, clock);
}
Also used : DefaultExtractorsFactory(com.google.android.exoplayer2.extractor.DefaultExtractorsFactory) MediaSource(com.google.android.exoplayer2.source.MediaSource) ExtractorsFactory(com.google.android.exoplayer2.extractor.ExtractorsFactory) DefaultExtractorsFactory(com.google.android.exoplayer2.extractor.DefaultExtractorsFactory) DefaultMediaSourceFactory(com.google.android.exoplayer2.source.DefaultMediaSourceFactory) VisibleForTesting(androidx.annotation.VisibleForTesting)

Example 17 with TrackGroupArray

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

the class ProgressiveMediaPeriod method maybeFinishPrepare.

private void maybeFinishPrepare() {
    if (released || prepared || !sampleQueuesBuilt || seekMap == null) {
        return;
    }
    for (SampleQueue sampleQueue : sampleQueues) {
        if (sampleQueue.getUpstreamFormat() == null) {
            return;
        }
    }
    loadCondition.close();
    int trackCount = sampleQueues.length;
    TrackGroup[] trackArray = new TrackGroup[trackCount];
    boolean[] trackIsAudioVideoFlags = new boolean[trackCount];
    for (int i = 0; i < trackCount; i++) {
        Format trackFormat = Assertions.checkNotNull(sampleQueues[i].getUpstreamFormat());
        @Nullable String mimeType = trackFormat.sampleMimeType;
        boolean isAudio = MimeTypes.isAudio(mimeType);
        boolean isAudioVideo = isAudio || MimeTypes.isVideo(mimeType);
        trackIsAudioVideoFlags[i] = isAudioVideo;
        haveAudioVideoTracks |= isAudioVideo;
        @Nullable IcyHeaders icyHeaders = this.icyHeaders;
        if (icyHeaders != null) {
            if (isAudio || sampleQueueTrackIds[i].isIcyTrack) {
                @Nullable Metadata metadata = trackFormat.metadata;
                if (metadata == null) {
                    metadata = new Metadata(icyHeaders);
                } else {
                    metadata = metadata.copyWithAppendedEntries(icyHeaders);
                }
                trackFormat = trackFormat.buildUpon().setMetadata(metadata).build();
            }
            // an average or peak bitrate of its own.
            if (isAudio && trackFormat.averageBitrate == Format.NO_VALUE && trackFormat.peakBitrate == Format.NO_VALUE && icyHeaders.bitrate != Format.NO_VALUE) {
                trackFormat = trackFormat.buildUpon().setAverageBitrate(icyHeaders.bitrate).build();
            }
        }
        trackFormat = trackFormat.copyWithCryptoType(drmSessionManager.getCryptoType(trackFormat));
        trackArray[i] = new TrackGroup(/* id= */
        Integer.toString(i), trackFormat);
    }
    trackState = new TrackState(new TrackGroupArray(trackArray), trackIsAudioVideoFlags);
    prepared = true;
    Assertions.checkNotNull(callback).onPrepared(this);
}
Also used : Metadata(com.google.android.exoplayer2.metadata.Metadata) IcyHeaders(com.google.android.exoplayer2.metadata.icy.IcyHeaders) Format(com.google.android.exoplayer2.Format) Nullable(androidx.annotation.Nullable)

Example 18 with TrackGroupArray

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

the class ProgressiveMediaPeriod method selectTracks.

@Override
public long selectTracks(@NullableType ExoTrackSelection[] selections, boolean[] mayRetainStreamFlags, @NullableType SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
    assertPrepared();
    TrackGroupArray tracks = trackState.tracks;
    boolean[] trackEnabledStates = trackState.trackEnabledStates;
    int oldEnabledTrackCount = enabledTrackCount;
    // Deselect old tracks.
    for (int i = 0; i < selections.length; i++) {
        if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
            int track = ((SampleStreamImpl) streams[i]).track;
            Assertions.checkState(trackEnabledStates[track]);
            enabledTrackCount--;
            trackEnabledStates[track] = false;
            streams[i] = null;
        }
    }
    // We'll always need to seek if this is a first selection to a non-zero position, or if we're
    // making a selection having previously disabled all tracks.
    boolean seekRequired = seenFirstTrackSelection ? oldEnabledTrackCount == 0 : positionUs != 0;
    // Select new tracks.
    for (int i = 0; i < selections.length; i++) {
        if (streams[i] == null && selections[i] != null) {
            ExoTrackSelection selection = selections[i];
            Assertions.checkState(selection.length() == 1);
            Assertions.checkState(selection.getIndexInTrackGroup(0) == 0);
            int track = tracks.indexOf(selection.getTrackGroup());
            Assertions.checkState(!trackEnabledStates[track]);
            enabledTrackCount++;
            trackEnabledStates[track] = true;
            streams[i] = new SampleStreamImpl(track);
            streamResetFlags[i] = true;
            // If there's still a chance of avoiding a seek, try and seek within the sample queue.
            if (!seekRequired) {
                SampleQueue sampleQueue = sampleQueues[track];
                // A seek can be avoided if we're able to seek to the current playback position in the
                // sample queue, or if we haven't read anything from the queue since the previous seek
                // (this case is common for sparse tracks such as metadata tracks). In all other cases a
                // seek is required.
                seekRequired = !sampleQueue.seekTo(positionUs, /* allowTimeBeyondBuffer= */
                true) && sampleQueue.getReadIndex() != 0;
            }
        }
    }
    if (enabledTrackCount == 0) {
        pendingDeferredRetry = false;
        notifyDiscontinuity = false;
        if (loader.isLoading()) {
            // Discard as much as we can synchronously.
            for (SampleQueue sampleQueue : sampleQueues) {
                sampleQueue.discardToEnd();
            }
            loader.cancelLoading();
        } else {
            for (SampleQueue sampleQueue : sampleQueues) {
                sampleQueue.reset();
            }
        }
    } else if (seekRequired) {
        positionUs = seekToUs(positionUs);
        // We'll need to reset renderers consuming from all streams due to the seek.
        for (int i = 0; i < streams.length; i++) {
            if (streams[i] != null) {
                streamResetFlags[i] = true;
            }
        }
    }
    seenFirstTrackSelection = true;
    return positionUs;
}
Also used : ExoTrackSelection(com.google.android.exoplayer2.trackselection.ExoTrackSelection)

Example 19 with TrackGroupArray

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

the class DefaultTrackSelector method selectTracksForType.

@Nullable
private <T extends TrackInfo<T>> Pair<ExoTrackSelection.Definition, Integer> selectTracksForType(@C.TrackType int trackType, MappedTrackInfo mappedTrackInfo, @Capabilities int[][][] formatSupport, TrackInfo.Factory<T> trackInfoFactory, Comparator<List<T>> selectionComparator) {
    ArrayList<List<T>> possibleSelections = new ArrayList<>();
    int rendererCount = mappedTrackInfo.getRendererCount();
    for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) {
        if (trackType == mappedTrackInfo.getRendererType(rendererIndex)) {
            TrackGroupArray groups = mappedTrackInfo.getTrackGroups(rendererIndex);
            for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
                TrackGroup trackGroup = groups.get(groupIndex);
                @Capabilities int[] groupSupport = formatSupport[rendererIndex][groupIndex];
                List<T> trackInfos = trackInfoFactory.create(rendererIndex, trackGroup, groupSupport);
                boolean[] usedTrackInSelection = new boolean[trackGroup.length];
                for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
                    T trackInfo = trackInfos.get(trackIndex);
                    @SelectionEligibility int eligibility = trackInfo.getSelectionEligibility();
                    if (usedTrackInSelection[trackIndex] || eligibility == SELECTION_ELIGIBILITY_NO) {
                        continue;
                    }
                    List<T> selection;
                    if (eligibility == SELECTION_ELIGIBILITY_FIXED) {
                        selection = ImmutableList.of(trackInfo);
                    } else {
                        selection = new ArrayList<>();
                        selection.add(trackInfo);
                        for (int i = trackIndex + 1; i < trackGroup.length; i++) {
                            T otherTrackInfo = trackInfos.get(i);
                            if (otherTrackInfo.getSelectionEligibility() == SELECTION_ELIGIBILITY_ADAPTIVE) {
                                if (trackInfo.isCompatibleForAdaptationWith(otherTrackInfo)) {
                                    selection.add(otherTrackInfo);
                                    usedTrackInSelection[i] = true;
                                }
                            }
                        }
                    }
                    possibleSelections.add(selection);
                }
            }
        }
    }
    if (possibleSelections.isEmpty()) {
        return null;
    }
    List<T> bestSelection = max(possibleSelections, selectionComparator);
    int[] trackIndices = new int[bestSelection.size()];
    for (int i = 0; i < bestSelection.size(); i++) {
        trackIndices[i] = bestSelection.get(i).trackIndex;
    }
    T firstTrackInfo = bestSelection.get(0);
    return Pair.create(new ExoTrackSelection.Definition(firstTrackInfo.trackGroup, trackIndices), firstTrackInfo.rendererIndex);
}
Also used : ArrayList(java.util.ArrayList) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) SuppressLint(android.annotation.SuppressLint) Point(android.graphics.Point) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) Capabilities(com.google.android.exoplayer2.RendererCapabilities.Capabilities) RendererCapabilities(com.google.android.exoplayer2.RendererCapabilities) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Nullable(androidx.annotation.Nullable)

Example 20 with TrackGroupArray

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

the class DefaultTrackSelector method getLegacyRendererOverride.

// Calling deprecated getSelectionOverride.
@SuppressWarnings("deprecation")
private ExoTrackSelection.@NullableType Definition getLegacyRendererOverride(MappedTrackInfo mappedTrackInfo, Parameters params, int rendererIndex) {
    TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
    @Nullable SelectionOverride override = params.getSelectionOverride(rendererIndex, rendererTrackGroups);
    if (override == null) {
        return null;
    }
    return new ExoTrackSelection.Definition(rendererTrackGroups.get(override.groupIndex), override.tracks, override.type);
}
Also used : TrackSelectionOverride(com.google.android.exoplayer2.trackselection.TrackSelectionOverrides.TrackSelectionOverride) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) Nullable(androidx.annotation.Nullable)

Aggregations

TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)126 Test (org.junit.Test)92 Format (com.google.android.exoplayer2.Format)67 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)50 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)36 Nullable (androidx.annotation.Nullable)18 FakeMediaSource (com.google.android.exoplayer2.testutil.FakeMediaSource)17 FakeTimeline (com.google.android.exoplayer2.testutil.FakeTimeline)17 TransferListener (com.google.android.exoplayer2.upstream.TransferListener)14 DrmSessionManager (com.google.android.exoplayer2.drm.DrmSessionManager)13 MediaSource (com.google.android.exoplayer2.source.MediaSource)13 MediaPeriodId (com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)13 FakeMediaPeriod (com.google.android.exoplayer2.testutil.FakeMediaPeriod)13 TestExoPlayerBuilder (com.google.android.exoplayer2.testutil.TestExoPlayerBuilder)13 Allocator (com.google.android.exoplayer2.upstream.Allocator)12 ArrayList (java.util.ArrayList)11 ClippingMediaSource (com.google.android.exoplayer2.source.ClippingMediaSource)9 CompositeMediaSource (com.google.android.exoplayer2.source.CompositeMediaSource)9 ConcatenatingMediaSource (com.google.android.exoplayer2.source.ConcatenatingMediaSource)9 MaskingMediaSource (com.google.android.exoplayer2.source.MaskingMediaSource)9