Search in sources :

Example 41 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class ExtractorAsserts method assertOutput.

/**
 * Asserts that an extractor consumes valid input data successfully under the specified
 * conditions.
 *
 * @param extractor The {@link Extractor} to be tested.
 * @param dumpFilesPrefix The dump files prefix prepended to the dump files path.
 * @param data Content of the input file.
 * @param context To be used to load the sample file.
 * @param sniffFirst Whether to sniff the data by calling {@link Extractor#sniff(ExtractorInput)}
 *     prior to consuming it.
 * @param simulateIOErrors Whether to simulate IO errors.
 * @param simulateUnknownLength Whether to simulate unknown input length.
 * @param simulatePartialReads Whether to simulate partial reads.
 * @throws IOException If reading from the input fails.
 */
private static void assertOutput(Extractor extractor, String dumpFilesPrefix, byte[] data, Context context, boolean deduplicateConsecutiveFormats, boolean sniffFirst, boolean simulateIOErrors, boolean simulateUnknownLength, boolean simulatePartialReads) throws IOException {
    FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).setSimulateIOErrors(simulateIOErrors).setSimulateUnknownLength(simulateUnknownLength).setSimulatePartialReads(simulatePartialReads).build();
    if (sniffFirst) {
        assertSniff(extractor, input, /* expectedResult= */
        true);
        input.resetPeekPosition();
    }
    FakeExtractorOutput extractorOutput = consumeTestData(extractor, input, 0, true, deduplicateConsecutiveFormats);
    if (simulateUnknownLength) {
        DumpFileAsserts.assertOutput(context, extractorOutput, dumpFilesPrefix + UNKNOWN_LENGTH_EXTENSION);
    } else {
        DumpFileAsserts.assertOutput(context, extractorOutput, dumpFilesPrefix + ".0" + DUMP_EXTENSION);
    }
    // Seeking to (timeUs=0, position=0) should always work, and cause the same data to be output.
    extractorOutput.clearTrackOutputs();
    input.reset();
    consumeTestData(extractor, input, /* timeUs= */
    0, extractorOutput, false);
    if (simulateUnknownLength) {
        DumpFileAsserts.assertOutput(context, extractorOutput, dumpFilesPrefix + UNKNOWN_LENGTH_EXTENSION);
    } else {
        DumpFileAsserts.assertOutput(context, extractorOutput, dumpFilesPrefix + ".0" + DUMP_EXTENSION);
    }
    SeekMap seekMap = Assertions.checkNotNull(extractorOutput.seekMap);
    long durationUs = seekMap.getDurationUs();
    // Only seek to the timeUs=0 if the SeekMap is unseekable or the duration is unknown.
    int numberSeekTests = seekMap.isSeekable() && durationUs != C.TIME_UNSET ? 4 : 1;
    for (int j = 0; j < numberSeekTests; j++) {
        long timeUs = durationUs * j / 3;
        long position = seekMap.getSeekPoints(timeUs).first.position;
        if (timeUs == 0 && position == 0) {
            // Already tested.
            continue;
        }
        input.reset();
        input.setPosition((int) position);
        extractorOutput.clearTrackOutputs();
        consumeTestData(extractor, input, timeUs, extractorOutput, false);
        if (simulateUnknownLength && timeUs == 0) {
            DumpFileAsserts.assertOutput(context, extractorOutput, dumpFilesPrefix + UNKNOWN_LENGTH_EXTENSION);
        } else {
            DumpFileAsserts.assertOutput(context, extractorOutput, dumpFilesPrefix + '.' + j + DUMP_EXTENSION);
        }
    }
}
Also used : SeekMap(com.google.android.exoplayer2.extractor.SeekMap)

Example 42 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class FakeRenderer method render.

@Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
    if (isEnded) {
        return;
    }
    playbackPositionUs = positionUs;
    while (true) {
        if (!hasPendingBuffer) {
            FormatHolder formatHolder = getFormatHolder();
            buffer.clear();
            @ReadDataResult int result = readSource(formatHolder, buffer, /* readFlags= */
            0);
            if (result == C.RESULT_FORMAT_READ) {
                DrmSession.replaceSession(currentDrmSession, formatHolder.drmSession);
                currentDrmSession = formatHolder.drmSession;
                Format format = Assertions.checkNotNull(formatHolder.format);
                if (MimeTypes.getTrackType(format.sampleMimeType) != getTrackType()) {
                    throw ExoPlaybackException.createForRenderer(new IllegalStateException(Util.formatInvariant("Format track type (%s) doesn't match renderer track type (%s).", MimeTypes.getTrackType(format.sampleMimeType), getTrackType())), getName(), getIndex(), format, C.FORMAT_UNSUPPORTED_TYPE, /* isRecoverable= */
                    false, PlaybackException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED);
                }
                formatsRead.add(format);
                onFormatChanged(format);
            } else if (result == C.RESULT_BUFFER_READ) {
                if (buffer.isEndOfStream()) {
                    isEnded = true;
                    return;
                }
                hasPendingBuffer = true;
            } else {
                Assertions.checkState(result == C.RESULT_NOTHING_READ);
                return;
            }
        }
        if (hasPendingBuffer) {
            if (!shouldProcessBuffer(buffer.timeUs, positionUs)) {
                return;
            }
            lastSamplePositionUs = buffer.timeUs;
            sampleBufferReadCount++;
            hasPendingBuffer = false;
        }
    }
}
Also used : Format(com.google.android.exoplayer2.Format) ReadDataResult(com.google.android.exoplayer2.source.SampleStream.ReadDataResult) FormatHolder(com.google.android.exoplayer2.FormatHolder)

Example 43 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class FakeVideoRenderer method shouldProcessBuffer.

@Override
protected boolean shouldProcessBuffer(long bufferTimeUs, long playbackPositionUs) {
    boolean shouldProcess = super.shouldProcessBuffer(bufferTimeUs, playbackPositionUs);
    boolean shouldRenderFirstFrame = output != null && (!renderedFirstFrameAfterEnable ? (getState() == Renderer.STATE_STARTED || mayRenderFirstFrameAfterEnableIfNotStarted) : !renderedFirstFrameAfterReset);
    shouldProcess |= shouldRenderFirstFrame && playbackPositionUs >= streamOffsetUs;
    @Nullable Object output = this.output;
    if (shouldProcess && !renderedFirstFrameAfterReset && output != null) {
        @MonotonicNonNull Format format = Assertions.checkNotNull(this.format);
        eventDispatcher.videoSizeChanged(new VideoSize(format.width, format.height, format.rotationDegrees, format.pixelWidthHeightRatio));
        eventDispatcher.renderedFirstFrame(output);
        renderedFirstFrameAfterReset = true;
        renderedFirstFrameAfterEnable = true;
    }
    return shouldProcess;
}
Also used : Format(com.google.android.exoplayer2.Format) MonotonicNonNull(org.checkerframework.checker.nullness.qual.MonotonicNonNull) VideoSize(com.google.android.exoplayer2.video.VideoSize) Nullable(androidx.annotation.Nullable)

Example 44 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class DefaultPlaybackSessionManager method updateSessions.

@Override
public synchronized void updateSessions(EventTime eventTime) {
    Assertions.checkNotNull(listener);
    if (eventTime.timeline.isEmpty()) {
        // Don't try to create new sessions for empty timelines.
        return;
    }
    @Nullable SessionDescriptor currentSession = sessions.get(currentSessionId);
    if (eventTime.mediaPeriodId != null && currentSession != null) {
        // If we receive an event associated with a media period, then it needs to be either part of
        // the current window if it's the first created media period, or a window that will be played
        // in the future. Otherwise, we know that it belongs to a session that was already finished
        // and we can ignore the event.
        boolean isAlreadyFinished = currentSession.windowSequenceNumber == C.INDEX_UNSET ? currentSession.windowIndex != eventTime.windowIndex : eventTime.mediaPeriodId.windowSequenceNumber < currentSession.windowSequenceNumber;
        if (isAlreadyFinished) {
            return;
        }
    }
    SessionDescriptor eventSession = getOrAddSession(eventTime.windowIndex, eventTime.mediaPeriodId);
    if (currentSessionId == null) {
        currentSessionId = eventSession.sessionId;
    }
    if (eventTime.mediaPeriodId != null && eventTime.mediaPeriodId.isAd()) {
        // Ensure that the content session for an ad session is created first.
        MediaPeriodId contentMediaPeriodId = new MediaPeriodId(eventTime.mediaPeriodId.periodUid, eventTime.mediaPeriodId.windowSequenceNumber, eventTime.mediaPeriodId.adGroupIndex);
        SessionDescriptor contentSession = getOrAddSession(eventTime.windowIndex, contentMediaPeriodId);
        if (!contentSession.isCreated) {
            contentSession.isCreated = true;
            eventTime.timeline.getPeriodByUid(eventTime.mediaPeriodId.periodUid, period);
            long adGroupPositionMs = Util.usToMs(period.getAdGroupTimeUs(eventTime.mediaPeriodId.adGroupIndex)) + period.getPositionInWindowMs();
            // getAdGroupTimeUs may return 0 for prerolls despite period offset.
            adGroupPositionMs = max(0, adGroupPositionMs);
            EventTime eventTimeForContent = new EventTime(eventTime.realtimeMs, eventTime.timeline, eventTime.windowIndex, contentMediaPeriodId, /* eventPlaybackPositionMs= */
            adGroupPositionMs, eventTime.currentTimeline, eventTime.currentWindowIndex, eventTime.currentMediaPeriodId, eventTime.currentPlaybackPositionMs, eventTime.totalBufferedDurationMs);
            listener.onSessionCreated(eventTimeForContent, contentSession.sessionId);
        }
    }
    if (!eventSession.isCreated) {
        eventSession.isCreated = true;
        listener.onSessionCreated(eventTime, eventSession.sessionId);
    }
    if (eventSession.sessionId.equals(currentSessionId) && !eventSession.isActive) {
        eventSession.isActive = true;
        listener.onSessionActive(eventTime, eventSession.sessionId);
    }
}
Also used : EventTime(com.google.android.exoplayer2.analytics.AnalyticsListener.EventTime) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) Nullable(androidx.annotation.Nullable)

Example 45 with Assertions.checkNotNull

use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.

the class HlsMediaPeriod method selectTracks.

@Override
public long selectTracks(@NullableType ExoTrackSelection[] selections, boolean[] mayRetainStreamFlags, @NullableType SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
    // Map each selection and stream onto a child period index.
    int[] streamChildIndices = new int[selections.length];
    int[] selectionChildIndices = new int[selections.length];
    for (int i = 0; i < selections.length; i++) {
        streamChildIndices[i] = streams[i] == null ? C.INDEX_UNSET : streamWrapperIndices.get(streams[i]);
        selectionChildIndices[i] = C.INDEX_UNSET;
        if (selections[i] != null) {
            TrackGroup trackGroup = selections[i].getTrackGroup();
            for (int j = 0; j < sampleStreamWrappers.length; j++) {
                if (sampleStreamWrappers[j].getTrackGroups().indexOf(trackGroup) != C.INDEX_UNSET) {
                    selectionChildIndices[i] = j;
                    break;
                }
            }
        }
    }
    boolean forceReset = false;
    streamWrapperIndices.clear();
    // Select tracks for each child, copying the resulting streams back into a new streams array.
    SampleStream[] newStreams = new SampleStream[selections.length];
    @NullableType SampleStream[] childStreams = new SampleStream[selections.length];
    @NullableType ExoTrackSelection[] childSelections = new ExoTrackSelection[selections.length];
    int newEnabledSampleStreamWrapperCount = 0;
    HlsSampleStreamWrapper[] newEnabledSampleStreamWrappers = new HlsSampleStreamWrapper[sampleStreamWrappers.length];
    for (int i = 0; i < sampleStreamWrappers.length; i++) {
        for (int j = 0; j < selections.length; j++) {
            childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
            childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
        }
        HlsSampleStreamWrapper sampleStreamWrapper = sampleStreamWrappers[i];
        boolean wasReset = sampleStreamWrapper.selectTracks(childSelections, mayRetainStreamFlags, childStreams, streamResetFlags, positionUs, forceReset);
        boolean wrapperEnabled = false;
        for (int j = 0; j < selections.length; j++) {
            SampleStream childStream = childStreams[j];
            if (selectionChildIndices[j] == i) {
                // Assert that the child provided a stream for the selection.
                Assertions.checkNotNull(childStream);
                newStreams[j] = childStream;
                wrapperEnabled = true;
                streamWrapperIndices.put(childStream, i);
            } else if (streamChildIndices[j] == i) {
                // Assert that the child cleared any previous stream.
                Assertions.checkState(childStream == null);
            }
        }
        if (wrapperEnabled) {
            newEnabledSampleStreamWrappers[newEnabledSampleStreamWrapperCount] = sampleStreamWrapper;
            if (newEnabledSampleStreamWrapperCount++ == 0) {
                // The first enabled wrapper is always allowed to initialize timestamp adjusters. Note
                // that the first wrapper will correspond to a variant, or else an audio rendition, or
                // else a text rendition, in that order.
                sampleStreamWrapper.setIsTimestampMaster(true);
                if (wasReset || enabledSampleStreamWrappers.length == 0 || sampleStreamWrapper != enabledSampleStreamWrappers[0]) {
                    // The wrapper responsible for initializing the timestamp adjusters was reset or
                    // changed. We need to reset the timestamp adjuster provider and all other wrappers.
                    timestampAdjusterProvider.reset();
                    forceReset = true;
                }
            } else {
                // Additional wrappers are also allowed to initialize timestamp adjusters if they contain
                // audio or video, since they are expected to contain dense samples. Text wrappers are not
                // permitted except in the case above in which no variant or audio rendition wrappers are
                // enabled.
                sampleStreamWrapper.setIsTimestampMaster(i < audioVideoSampleStreamWrapperCount);
            }
        }
    }
    // Copy the new streams back into the streams array.
    System.arraycopy(newStreams, 0, streams, 0, newStreams.length);
    // Update the local state.
    enabledSampleStreamWrappers = Util.nullSafeArrayCopy(newEnabledSampleStreamWrappers, newEnabledSampleStreamWrapperCount);
    compositeSequenceableLoader = compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(enabledSampleStreamWrappers);
    return positionUs;
}
Also used : ExoTrackSelection(com.google.android.exoplayer2.trackselection.ExoTrackSelection) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) NullableType(org.checkerframework.checker.nullness.compatqual.NullableType) SampleStream(com.google.android.exoplayer2.source.SampleStream)

Aggregations

Nullable (androidx.annotation.Nullable)28 Format (com.google.android.exoplayer2.Format)10 ArrayList (java.util.ArrayList)9 MediaItem (com.google.android.exoplayer2.MediaItem)8 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)5 Matcher (java.util.regex.Matcher)5 SuppressLint (android.annotation.SuppressLint)4 Context (android.content.Context)4 Uri (android.net.Uri)4 MediaSource (com.google.android.exoplayer2.source.MediaSource)4 DataSource (com.google.android.exoplayer2.upstream.DataSource)4 StatsDataSource (com.google.android.exoplayer2.upstream.StatsDataSource)4 Activity (android.app.Activity)3 Intent (android.content.Intent)3 SQLException (android.database.SQLException)3 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)3 Bundle (android.os.Bundle)3 CallbackMediaItem (androidx.media2.common.CallbackMediaItem)3 C (com.google.android.exoplayer2.C)3 ExoPlayer (com.google.android.exoplayer2.ExoPlayer)3