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;
}
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;
}
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);
}
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;
}
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;
}
Aggregations