use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.
the class DashUtil method loadInitializationData.
/**
* Loads initialization data for the {@code representation} and optionally index data then returns
* a {@link BundledChunkExtractor} which contains the output.
*
* @param chunkExtractor The {@link ChunkExtractor} to use.
* @param dataSource The source from which the data should be loaded.
* @param representation The representation which initialization chunk belongs to.
* @param baseUrlIndex The index of the base URL with which to resolve the request URI.
* @param loadIndex Whether to load index data too.
* @throws IOException Thrown when there is an error while loading.
*/
private static void loadInitializationData(ChunkExtractor chunkExtractor, DataSource dataSource, Representation representation, int baseUrlIndex, boolean loadIndex) throws IOException {
RangedUri initializationUri = Assertions.checkNotNull(representation.getInitializationUri());
@Nullable RangedUri requestUri;
if (loadIndex) {
@Nullable RangedUri indexUri = representation.getIndexUri();
if (indexUri == null) {
return;
}
// It's common for initialization and index data to be stored adjacently. Attempt to merge
// the two requests together to request both at once.
requestUri = initializationUri.attemptMerge(indexUri, representation.baseUrls.get(baseUrlIndex).url);
if (requestUri == null) {
loadInitializationData(dataSource, representation, baseUrlIndex, chunkExtractor, initializationUri);
requestUri = indexUri;
}
} else {
requestUri = initializationUri;
}
loadInitializationData(dataSource, representation, baseUrlIndex, chunkExtractor, requestUri);
}
use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.
the class TestExoPlayerBuilder method build.
/**
* Builds an {@link ExoPlayer} using the provided values or their defaults.
*/
public ExoPlayer build() {
Assertions.checkNotNull(looper, "TestExoPlayer builder run on a thread without Looper and no Looper specified.");
// Do not update renderersFactory and renderers here, otherwise their getters may
// return different values before and after build() is called, making them confusing.
RenderersFactory playerRenderersFactory = renderersFactory;
if (playerRenderersFactory == null) {
playerRenderersFactory = (eventHandler, videoRendererEventListener, audioRendererEventListener, textRendererOutput, metadataRendererOutput) -> renderers != null ? renderers : new Renderer[] { new FakeVideoRenderer(eventHandler, videoRendererEventListener), new FakeAudioRenderer(eventHandler, audioRendererEventListener) };
}
ExoPlayer.Builder builder = new ExoPlayer.Builder(context, playerRenderersFactory).setTrackSelector(trackSelector).setLoadControl(loadControl).setBandwidthMeter(bandwidthMeter).setAnalyticsCollector(new DefaultAnalyticsCollector(clock)).setClock(clock).setUseLazyPreparation(useLazyPreparation).setLooper(looper).setSeekBackIncrementMs(seekBackIncrementMs).setSeekForwardIncrementMs(seekForwardIncrementMs);
if (mediaSourceFactory != null) {
builder.setMediaSourceFactory(mediaSourceFactory);
}
return builder.build();
}
use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.
the class TimelineAsserts method assertPeriodCounts.
/**
* Asserts that period counts for each window are set correctly. Also asserts that {@link
* Window#firstPeriodIndex} and {@link Window#lastPeriodIndex} are set correctly, and it asserts
* the correct behavior of {@link Timeline#getNextWindowIndex(int, int, boolean)}.
*/
public static void assertPeriodCounts(Timeline timeline, int... expectedPeriodCounts) {
int windowCount = timeline.getWindowCount();
assertThat(windowCount).isEqualTo(expectedPeriodCounts.length);
int[] accumulatedPeriodCounts = new int[windowCount + 1];
accumulatedPeriodCounts[0] = 0;
for (int i = 0; i < windowCount; i++) {
accumulatedPeriodCounts[i + 1] = accumulatedPeriodCounts[i] + expectedPeriodCounts[i];
}
assertThat(timeline.getPeriodCount()).isEqualTo(accumulatedPeriodCounts[accumulatedPeriodCounts.length - 1]);
Window window = new Window();
Period period = new Period();
for (int i = 0; i < windowCount; i++) {
timeline.getWindow(i, window);
assertThat(window.firstPeriodIndex).isEqualTo(accumulatedPeriodCounts[i]);
assertThat(window.lastPeriodIndex).isEqualTo(accumulatedPeriodCounts[i + 1] - 1);
}
int expectedWindowIndex = 0;
for (int i = 0; i < timeline.getPeriodCount(); i++) {
timeline.getPeriod(i, period, true);
while (i >= accumulatedPeriodCounts[expectedWindowIndex + 1]) {
expectedWindowIndex++;
}
assertThat(period.windowIndex).isEqualTo(expectedWindowIndex);
Object periodUid = Assertions.checkNotNull(period.uid);
assertThat(timeline.getIndexOfPeriod(periodUid)).isEqualTo(i);
assertThat(timeline.getUidOfPeriod(i)).isEqualTo(periodUid);
for (int repeatMode : REPEAT_MODES) {
if (i < accumulatedPeriodCounts[expectedWindowIndex + 1] - 1) {
assertThat(timeline.getNextPeriodIndex(i, period, window, repeatMode, false)).isEqualTo(i + 1);
} else {
int nextWindow = timeline.getNextWindowIndex(expectedWindowIndex, repeatMode, false);
int nextPeriod = nextWindow == C.INDEX_UNSET ? C.INDEX_UNSET : accumulatedPeriodCounts[nextWindow];
assertThat(timeline.getNextPeriodIndex(i, period, window, repeatMode, false)).isEqualTo(nextPeriod);
}
}
}
}
use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.
the class MediaCodecRenderer method maybeInitCodecOrBypass.
protected final void maybeInitCodecOrBypass() throws ExoPlaybackException {
if (codec != null || bypassEnabled || inputFormat == null) {
// We have a codec, are bypassing it, or don't have a format to decide how to render.
return;
}
if (sourceDrmSession == null && shouldUseBypass(inputFormat)) {
initBypass(inputFormat);
return;
}
setCodecDrmSession(sourceDrmSession);
String mimeType = inputFormat.sampleMimeType;
if (codecDrmSession != null) {
if (mediaCrypto == null) {
@Nullable FrameworkCryptoConfig sessionCryptoConfig = getFrameworkCryptoConfig(codecDrmSession);
if (sessionCryptoConfig == null) {
@Nullable DrmSessionException drmError = codecDrmSession.getError();
if (drmError != null) {
// Continue for now. We may be able to avoid failure if a new input format causes the
// session to be replaced without it having been used.
} else {
// The drm session isn't open yet.
return;
}
} else {
try {
mediaCrypto = new MediaCrypto(sessionCryptoConfig.uuid, sessionCryptoConfig.sessionId);
} catch (MediaCryptoException e) {
throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR);
}
mediaCryptoRequiresSecureDecoder = !sessionCryptoConfig.forceAllowInsecureDecoderComponents && mediaCrypto.requiresSecureDecoderComponent(mimeType);
}
}
if (FrameworkCryptoConfig.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC) {
@DrmSession.State int drmSessionState = codecDrmSession.getState();
if (drmSessionState == DrmSession.STATE_ERROR) {
DrmSessionException drmSessionException = Assertions.checkNotNull(codecDrmSession.getError());
throw createRendererException(drmSessionException, inputFormat, drmSessionException.errorCode);
} else if (drmSessionState != DrmSession.STATE_OPENED_WITH_KEYS) {
// Wait for keys.
return;
}
}
}
try {
maybeInitCodecWithFallback(mediaCrypto, mediaCryptoRequiresSecureDecoder);
} catch (DecoderInitializationException e) {
throw createRendererException(e, inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
}
}
use of com.google.android.exoplayer2.util.Assertions.checkNotNull in project ExoPlayer by google.
the class SegmentDownloader method download.
@Override
public final void download(@Nullable ProgressListener progressListener) throws IOException, InterruptedException {
ArrayDeque<Segment> pendingSegments = new ArrayDeque<>();
ArrayDeque<SegmentDownloadRunnable> recycledRunnables = new ArrayDeque<>();
if (priorityTaskManager != null) {
priorityTaskManager.add(C.PRIORITY_DOWNLOAD);
}
try {
CacheDataSource dataSource = cacheDataSourceFactory.createDataSourceForDownloading();
// Get the manifest and all of the segments.
M manifest = getManifest(dataSource, manifestDataSpec, /* removing= */
false);
if (!streamKeys.isEmpty()) {
manifest = manifest.copy(streamKeys);
}
List<Segment> segments = getSegments(dataSource, manifest, /* removing= */
false);
// Sort the segments so that we download media in the right order from the start of the
// content, and merge segments where possible to minimize the number of server round trips.
Collections.sort(segments);
mergeSegments(segments, cacheKeyFactory);
// Scan the segments, removing any that are fully downloaded.
int totalSegments = segments.size();
int segmentsDownloaded = 0;
long contentLength = 0;
long bytesDownloaded = 0;
for (int i = segments.size() - 1; i >= 0; i--) {
DataSpec dataSpec = segments.get(i).dataSpec;
String cacheKey = cacheKeyFactory.buildCacheKey(dataSpec);
long segmentLength = dataSpec.length;
if (segmentLength == C.LENGTH_UNSET) {
long resourceLength = ContentMetadata.getContentLength(cache.getContentMetadata(cacheKey));
if (resourceLength != C.LENGTH_UNSET) {
segmentLength = resourceLength - dataSpec.position;
}
}
long segmentBytesDownloaded = cache.getCachedBytes(cacheKey, dataSpec.position, segmentLength);
bytesDownloaded += segmentBytesDownloaded;
if (segmentLength != C.LENGTH_UNSET) {
if (segmentLength == segmentBytesDownloaded) {
// The segment is fully downloaded.
segmentsDownloaded++;
segments.remove(i);
}
if (contentLength != C.LENGTH_UNSET) {
contentLength += segmentLength;
}
} else {
contentLength = C.LENGTH_UNSET;
}
}
// Download the segments.
@Nullable ProgressNotifier progressNotifier = progressListener != null ? new ProgressNotifier(progressListener, contentLength, totalSegments, bytesDownloaded, segmentsDownloaded) : null;
pendingSegments.addAll(segments);
while (!isCanceled && !pendingSegments.isEmpty()) {
// Block until there aren't any higher priority tasks.
if (priorityTaskManager != null) {
priorityTaskManager.proceed(C.PRIORITY_DOWNLOAD);
}
// Create and execute a runnable to download the next segment.
CacheDataSource segmentDataSource;
byte[] temporaryBuffer;
if (!recycledRunnables.isEmpty()) {
SegmentDownloadRunnable recycledRunnable = recycledRunnables.removeFirst();
segmentDataSource = recycledRunnable.dataSource;
temporaryBuffer = recycledRunnable.temporaryBuffer;
} else {
segmentDataSource = cacheDataSourceFactory.createDataSourceForDownloading();
temporaryBuffer = new byte[BUFFER_SIZE_BYTES];
}
Segment segment = pendingSegments.removeFirst();
SegmentDownloadRunnable downloadRunnable = new SegmentDownloadRunnable(segment, segmentDataSource, progressNotifier, temporaryBuffer);
addActiveRunnable(downloadRunnable);
executor.execute(downloadRunnable);
// Clean up runnables that have finished.
for (int j = activeRunnables.size() - 1; j >= 0; j--) {
SegmentDownloadRunnable activeRunnable = (SegmentDownloadRunnable) activeRunnables.get(j);
// it's already finished.
if (pendingSegments.isEmpty() || activeRunnable.isDone()) {
try {
activeRunnable.get();
removeActiveRunnable(j);
recycledRunnables.addLast(activeRunnable);
} catch (ExecutionException e) {
Throwable cause = Assertions.checkNotNull(e.getCause());
if (cause instanceof PriorityTooLowException) {
// We need to schedule this segment again in a future loop iteration.
pendingSegments.addFirst(activeRunnable.segment);
removeActiveRunnable(j);
recycledRunnables.addLast(activeRunnable);
} else if (cause instanceof IOException) {
throw (IOException) cause;
} else {
// The cause must be an uncaught Throwable type.
Util.sneakyThrow(cause);
}
}
}
}
// Don't move on to the next segment until the runnable for this segment has started. This
// drip feeds runnables to the executor, rather than providing them all up front.
downloadRunnable.blockUntilStarted();
}
} finally {
// Cancel them to speed this up.
for (int i = 0; i < activeRunnables.size(); i++) {
activeRunnables.get(i).cancel(/* interruptIfRunning= */
true);
}
// do this for the case where the main download thread was interrupted as part of cancelation.
for (int i = activeRunnables.size() - 1; i >= 0; i--) {
activeRunnables.get(i).blockUntilFinished();
removeActiveRunnable(i);
}
if (priorityTaskManager != null) {
priorityTaskManager.remove(C.PRIORITY_DOWNLOAD);
}
}
}
Aggregations