Search in sources :

Example 36 with Assertions.checkNotNull

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

the class HlsSampleStreamWrapper method readData.

public int readData(int sampleQueueIndex, FormatHolder formatHolder, DecoderInputBuffer buffer, @ReadFlags int readFlags) {
    if (isPendingReset()) {
        return C.RESULT_NOTHING_READ;
    }
    // TODO: Split into discard (in discardBuffer) and format change (here and in skipData) steps.
    if (!mediaChunks.isEmpty()) {
        int discardToMediaChunkIndex = 0;
        while (discardToMediaChunkIndex < mediaChunks.size() - 1 && finishedReadingChunk(mediaChunks.get(discardToMediaChunkIndex))) {
            discardToMediaChunkIndex++;
        }
        Util.removeRange(mediaChunks, 0, discardToMediaChunkIndex);
        HlsMediaChunk currentChunk = mediaChunks.get(0);
        Format trackFormat = currentChunk.trackFormat;
        if (!trackFormat.equals(downstreamTrackFormat)) {
            mediaSourceEventDispatcher.downstreamFormatChanged(trackType, trackFormat, currentChunk.trackSelectionReason, currentChunk.trackSelectionData, currentChunk.startTimeUs);
        }
        downstreamTrackFormat = trackFormat;
    }
    if (!mediaChunks.isEmpty() && !mediaChunks.get(0).isPublished()) {
        // Don't read into preload chunks until we can be sure they are permanently published.
        return C.RESULT_NOTHING_READ;
    }
    int result = sampleQueues[sampleQueueIndex].read(formatHolder, buffer, readFlags, loadingFinished);
    if (result == C.RESULT_FORMAT_READ) {
        Format format = Assertions.checkNotNull(formatHolder.format);
        if (sampleQueueIndex == primarySampleQueueIndex) {
            // Fill in primary sample format with information from the track format.
            int chunkUid = sampleQueues[sampleQueueIndex].peekSourceId();
            int chunkIndex = 0;
            while (chunkIndex < mediaChunks.size() && mediaChunks.get(chunkIndex).uid != chunkUid) {
                chunkIndex++;
            }
            Format trackFormat = chunkIndex < mediaChunks.size() ? mediaChunks.get(chunkIndex).trackFormat : Assertions.checkNotNull(upstreamTrackFormat);
            format = format.withManifestFormatInfo(trackFormat);
        }
        formatHolder.format = format;
    }
    return result;
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 37 with Assertions.checkNotNull

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

the class HlsMediaPeriod method buildAndPrepareSampleStreamWrappers.

// Internal methods.
private void buildAndPrepareSampleStreamWrappers(long positionUs) {
    HlsMultivariantPlaylist multivariantPlaylist = Assertions.checkNotNull(playlistTracker.getMultivariantPlaylist());
    Map<String, DrmInitData> overridingDrmInitData = useSessionKeys ? deriveOverridingDrmInitData(multivariantPlaylist.sessionKeyDrmInitData) : Collections.emptyMap();
    boolean hasVariants = !multivariantPlaylist.variants.isEmpty();
    List<Rendition> audioRenditions = multivariantPlaylist.audios;
    List<Rendition> subtitleRenditions = multivariantPlaylist.subtitles;
    pendingPrepareCount = 0;
    ArrayList<HlsSampleStreamWrapper> sampleStreamWrappers = new ArrayList<>();
    ArrayList<int[]> manifestUrlIndicesPerWrapper = new ArrayList<>();
    if (hasVariants) {
        buildAndPrepareMainSampleStreamWrapper(multivariantPlaylist, positionUs, sampleStreamWrappers, manifestUrlIndicesPerWrapper, overridingDrmInitData);
    }
    // TODO: Build video stream wrappers here.
    buildAndPrepareAudioSampleStreamWrappers(positionUs, audioRenditions, sampleStreamWrappers, manifestUrlIndicesPerWrapper, overridingDrmInitData);
    audioVideoSampleStreamWrapperCount = sampleStreamWrappers.size();
    // these.
    for (int i = 0; i < subtitleRenditions.size(); i++) {
        Rendition subtitleRendition = subtitleRenditions.get(i);
        String sampleStreamWrapperUid = "subtitle:" + i + ":" + subtitleRendition.name;
        HlsSampleStreamWrapper sampleStreamWrapper = buildSampleStreamWrapper(sampleStreamWrapperUid, C.TRACK_TYPE_TEXT, new Uri[] { subtitleRendition.url }, new Format[] { subtitleRendition.format }, null, Collections.emptyList(), overridingDrmInitData, positionUs);
        manifestUrlIndicesPerWrapper.add(new int[] { i });
        sampleStreamWrappers.add(sampleStreamWrapper);
        sampleStreamWrapper.prepareWithMultivariantPlaylistInfo(new TrackGroup[] { new TrackGroup(sampleStreamWrapperUid, subtitleRendition.format) }, /* primaryTrackGroupIndex= */
        0);
    }
    this.sampleStreamWrappers = sampleStreamWrappers.toArray(new HlsSampleStreamWrapper[0]);
    this.manifestUrlIndicesPerWrapper = manifestUrlIndicesPerWrapper.toArray(new int[0][]);
    pendingPrepareCount = this.sampleStreamWrappers.length;
    // Set timestamp master and trigger preparation (if not already prepared)
    this.sampleStreamWrappers[0].setIsTimestampMaster(true);
    for (HlsSampleStreamWrapper sampleStreamWrapper : this.sampleStreamWrappers) {
        sampleStreamWrapper.continuePreparing();
    }
    // All wrappers are enabled during preparation.
    enabledSampleStreamWrappers = this.sampleStreamWrappers;
}
Also used : Rendition(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition) ArrayList(java.util.ArrayList) DrmInitData(com.google.android.exoplayer2.drm.DrmInitData) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) HlsMultivariantPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist)

Example 38 with Assertions.checkNotNull

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

the class WavHeaderReader method skipToData.

/**
   * Skips to the data in the given WAV input stream and returns its data size. After calling, the
   * input stream's position will point to the start of sample data in the WAV.
   * <p>
   * If an exception is thrown, the input position will be left pointing to a chunk header.
   *
   * @param input Input stream to skip to the data chunk in. Its peek position must be pointing to
   *     a valid chunk header.
   * @param wavHeader WAV header to populate with data bounds.
   * @throws ParserException If an error occurs parsing chunks.
   * @throws IOException If reading from the input fails.
   * @throws InterruptedException If interrupted while reading from input.
   */
public static void skipToData(ExtractorInput input, WavHeader wavHeader) throws IOException, InterruptedException {
    Assertions.checkNotNull(input);
    Assertions.checkNotNull(wavHeader);
    // Make sure the peek position is set to the read position before we peek the first header.
    input.resetPeekPosition();
    ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES);
    // Skip all chunks until we hit the data header.
    ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
    while (chunkHeader.id != Util.getIntegerCodeForString("data")) {
        Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id);
        long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size;
        // Override size of RIFF chunk, since it describes its size as the entire file.
        if (chunkHeader.id == Util.getIntegerCodeForString("RIFF")) {
            bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4;
        }
        if (bytesToSkip > Integer.MAX_VALUE) {
            throw new ParserException("Chunk is too large (~2GB+) to skip; id: " + chunkHeader.id);
        }
        input.skipFully((int) bytesToSkip);
        chunkHeader = ChunkHeader.peek(input, scratch);
    }
    // Skip past the "data" header.
    input.skipFully(ChunkHeader.SIZE_IN_BYTES);
    wavHeader.setDataBounds(input.getPosition(), chunkHeader.size);
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) ParserException(com.google.android.exoplayer2.ParserException)

Example 39 with Assertions.checkNotNull

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

the class PlayerWrapper method replacePlaylistItem.

public boolean replacePlaylistItem(int index, androidx.media2.common.MediaItem media2MediaItem) {
    Assertions.checkArgument(!media2Playlist.contains(media2MediaItem));
    index = Util.constrainValue(index, 0, media2Playlist.size());
    MediaItem exoPlayerMediaItemToAdd = Assertions.checkNotNull(mediaItemConverter.convertToExoPlayerMediaItem(media2MediaItem));
    ignoreTimelineUpdates = true;
    player.removeMediaItem(index);
    ignoreTimelineUpdates = false;
    player.addMediaItem(index, exoPlayerMediaItemToAdd);
    return true;
}
Also used : CallbackMediaItem(androidx.media2.common.CallbackMediaItem) MediaItem(com.google.android.exoplayer2.MediaItem)

Example 40 with Assertions.checkNotNull

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

the class FfmpegAudioDecoder method decode.

@Override
@Nullable
protected FfmpegDecoderException decode(DecoderInputBuffer inputBuffer, SimpleDecoderOutputBuffer outputBuffer, boolean reset) {
    if (reset) {
        nativeContext = ffmpegReset(nativeContext, extraData);
        if (nativeContext == 0) {
            return new FfmpegDecoderException("Error resetting (see logcat).");
        }
    }
    ByteBuffer inputData = Util.castNonNull(inputBuffer.data);
    int inputSize = inputData.limit();
    ByteBuffer outputData = outputBuffer.init(inputBuffer.timeUs, outputBufferSize);
    int result = ffmpegDecode(nativeContext, inputData, inputSize, outputData, outputBufferSize);
    if (result == AUDIO_DECODER_ERROR_OTHER) {
        return new FfmpegDecoderException("Error decoding (see logcat).");
    } else if (result == AUDIO_DECODER_ERROR_INVALID_DATA) {
        // Treat invalid data errors as non-fatal to match the behavior of MediaCodec. No output will
        // be produced for this buffer, so mark it as decode-only to ensure that the audio sink's
        // position is reset when more audio is produced.
        outputBuffer.setFlags(C.BUFFER_FLAG_DECODE_ONLY);
        return null;
    } else if (result == 0) {
        // There's no need to output empty buffers.
        outputBuffer.setFlags(C.BUFFER_FLAG_DECODE_ONLY);
        return null;
    }
    if (!hasOutputFormat) {
        channelCount = ffmpegGetChannelCount(nativeContext);
        sampleRate = ffmpegGetSampleRate(nativeContext);
        if (sampleRate == 0 && "alac".equals(codecName)) {
            Assertions.checkNotNull(extraData);
            // ALAC decoder did not set the sample rate in earlier versions of FFmpeg. See
            // https://trac.ffmpeg.org/ticket/6096.
            ParsableByteArray parsableExtraData = new ParsableByteArray(extraData);
            parsableExtraData.setPosition(extraData.length - 4);
            sampleRate = parsableExtraData.readUnsignedIntToInt();
        }
        hasOutputFormat = true;
    }
    outputData.position(0);
    outputData.limit(result);
    return null;
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) ByteBuffer(java.nio.ByteBuffer) Nullable(androidx.annotation.Nullable)

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