use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project ExoPlayer by google.
the class MediaPeriodQueueTest method setupTimeline.
private void setupTimeline(Timeline timeline) {
fakeMediaSource = new FakeMediaSource(timeline);
MediaSourceList.MediaSourceHolder mediaSourceHolder = new MediaSourceList.MediaSourceHolder(fakeMediaSource, /* useLazyPreparation= */
false);
mediaSourceList.setMediaSources(ImmutableList.of(mediaSourceHolder), new FakeShuffleOrder(/* length= */
1));
mediaSourceHolder.mediaSource.prepareSource(mock(MediaSourceCaller.class), /* mediaTransferListener */
null, PlayerId.UNSET);
Timeline playlistTimeline = mediaSourceList.createTimeline();
firstPeriodUid = playlistTimeline.getUidOfPeriod(/* periodIndex= */
0);
playbackInfo = new PlaybackInfo(playlistTimeline, mediaPeriodQueue.resolveMediaPeriodIdForAds(playlistTimeline, firstPeriodUid, /* positionUs= */
0), /* requestedContentPositionUs= */
C.TIME_UNSET, /* discontinuityStartPositionUs= */
0, Player.STATE_READY, /* playbackError= */
null, /* isLoading= */
false, /* trackGroups= */
null, /* trackSelectorResult= */
null, /* staticMetadata= */
ImmutableList.of(), /* loadingMediaPeriodId= */
null, /* playWhenReady= */
false, Player.PLAYBACK_SUPPRESSION_REASON_NONE, /* playbackParameters= */
PlaybackParameters.DEFAULT, /* bufferedPositionUs= */
0, /* totalBufferedDurationUs= */
0, /* positionUs= */
0, /* offloadSchedulingEnabled= */
false, /* sleepingForOffload= */
false);
}
use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project Telegram-FOSS by Telegram-FOSS-Team.
the class ExoPlayerImplInternal method maybeUpdateReadingPeriod.
private void maybeUpdateReadingPeriod() throws ExoPlaybackException {
MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
if (readingPeriodHolder == null) {
return;
}
if (readingPeriodHolder.getNext() == null) {
// We don't have a successor to advance the reading period to.
if (readingPeriodHolder.info.isFinal) {
for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i];
SampleStream sampleStream = readingPeriodHolder.sampleStreams[i];
// stream in case of playlist changes that cause the stream to be no longer final.
if (sampleStream != null && renderer.getStream() == sampleStream && renderer.hasReadStreamToEnd()) {
renderer.setCurrentStreamFinal();
}
}
}
return;
}
if (!hasReadingPeriodFinishedReading()) {
return;
}
if (!readingPeriodHolder.getNext().prepared) {
// The successor is not prepared yet.
return;
}
TrackSelectorResult oldTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();
readingPeriodHolder = queue.advanceReadingPeriod();
TrackSelectorResult newTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();
if (readingPeriodHolder.mediaPeriod.readDiscontinuity() != C.TIME_UNSET) {
// The new period starts with a discontinuity, so the renderers will play out all data, then
// be disabled and re-enabled when they start playing the next period.
setAllRendererStreamsFinal();
return;
}
for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i];
boolean rendererWasEnabled = oldTrackSelectorResult.isRendererEnabled(i);
if (rendererWasEnabled && !renderer.isCurrentStreamFinal()) {
// The renderer is enabled and its stream is not final, so we still have a chance to replace
// the sample streams.
TrackSelection newSelection = newTrackSelectorResult.selections.get(i);
boolean newRendererEnabled = newTrackSelectorResult.isRendererEnabled(i);
boolean isNoSampleRenderer = rendererCapabilities[i].getTrackType() == C.TRACK_TYPE_NONE;
RendererConfiguration oldConfig = oldTrackSelectorResult.rendererConfigurations[i];
RendererConfiguration newConfig = newTrackSelectorResult.rendererConfigurations[i];
if (newRendererEnabled && newConfig.equals(oldConfig) && !isNoSampleRenderer) {
// Replace the renderer's SampleStream so the transition to playing the next period can
// be seamless.
// This should be avoided for no-sample renderer, because skipping ahead for such
// renderer doesn't have any benefit (the renderer does not consume the sample stream),
// and it will change the provided rendererOffsetUs while the renderer is still
// rendering from the playing media period.
Format[] formats = getFormats(newSelection);
renderer.replaceStream(formats, readingPeriodHolder.sampleStreams[i], readingPeriodHolder.getRendererOffset());
} else {
// The renderer will be disabled when transitioning to playing the next period, because
// there's no new selection, or because a configuration change is required, or because
// it's a no-sample renderer for which rendererOffsetUs should be updated only when
// starting to play the next period. Mark the SampleStream as final to play out any
// remaining data.
renderer.setCurrentStreamFinal();
}
}
}
}
use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project Telegram-FOSS by Telegram-FOSS-Team.
the class ExoPlayerImplInternal method enableRenderers.
private void enableRenderers(boolean[] rendererWasEnabledFlags, int totalEnabledRendererCount) throws ExoPlaybackException {
enabledRenderers = new Renderer[totalEnabledRendererCount];
int enabledRendererCount = 0;
TrackSelectorResult trackSelectorResult = queue.getPlayingPeriod().getTrackSelectorResult();
// by the disabled renderers will be available to renderers that are being enabled.
for (int i = 0; i < renderers.length; i++) {
if (!trackSelectorResult.isRendererEnabled(i)) {
renderers[i].reset();
}
}
// Enable the renderers.
for (int i = 0; i < renderers.length; i++) {
if (trackSelectorResult.isRendererEnabled(i)) {
enableRenderer(i, rendererWasEnabledFlags[i], enabledRendererCount++);
}
}
}
use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project Telegram-FOSS by Telegram-FOSS-Team.
the class ExoPlayerImplInternal method reselectTracksInternal.
private void reselectTracksInternal() throws ExoPlaybackException {
float playbackSpeed = mediaClock.getPlaybackParameters().speed;
// Reselect tracks on each period in turn, until the selection changes.
MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
boolean selectionsChangedForReadPeriod = true;
TrackSelectorResult newTrackSelectorResult;
while (true) {
if (periodHolder == null || !periodHolder.prepared) {
// The reselection did not change any prepared periods.
return;
}
newTrackSelectorResult = periodHolder.selectTracks(playbackSpeed, playbackInfo.timeline);
if (!newTrackSelectorResult.isEquivalent(periodHolder.getTrackSelectorResult())) {
// Selected tracks have changed for this period.
break;
}
if (periodHolder == readingPeriodHolder) {
// The track reselection didn't affect any period that has been read.
selectionsChangedForReadPeriod = false;
}
periodHolder = periodHolder.getNext();
}
if (selectionsChangedForReadPeriod) {
// Update streams and rebuffer for the new selection, recreating all streams if reading ahead.
MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
boolean recreateStreams = queue.removeAfter(playingPeriodHolder);
boolean[] streamResetFlags = new boolean[renderers.length];
long periodPositionUs = playingPeriodHolder.applyTrackSelection(newTrackSelectorResult, playbackInfo.positionUs, recreateStreams, streamResetFlags);
if (playbackInfo.playbackState != Player.STATE_ENDED && periodPositionUs != playbackInfo.positionUs) {
playbackInfo = copyWithNewPosition(playbackInfo.periodId, periodPositionUs, playbackInfo.contentPositionUs);
playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL);
resetRendererPosition(periodPositionUs);
}
int enabledRendererCount = 0;
boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i];
rendererWasEnabledFlags[i] = renderer.getState() != Renderer.STATE_DISABLED;
SampleStream sampleStream = playingPeriodHolder.sampleStreams[i];
if (sampleStream != null) {
enabledRendererCount++;
}
if (rendererWasEnabledFlags[i]) {
if (sampleStream != renderer.getStream()) {
// We need to disable the renderer.
disableRenderer(renderer);
} else if (streamResetFlags[i]) {
// The renderer will continue to consume from its current stream, but needs to be reset.
renderer.resetPosition(rendererPositionUs);
}
}
}
playbackInfo = playbackInfo.copyWithTrackInfo(playingPeriodHolder.getTrackGroups(), playingPeriodHolder.getTrackSelectorResult());
enableRenderers(rendererWasEnabledFlags, enabledRendererCount);
} else {
// Release and re-prepare/buffer periods after the one whose selection changed.
queue.removeAfter(periodHolder);
if (periodHolder.prepared) {
long loadingPeriodPositionUs = Math.max(periodHolder.info.startPositionUs, periodHolder.toPeriodTime(rendererPositionUs));
periodHolder.applyTrackSelection(newTrackSelectorResult, loadingPeriodPositionUs, false);
}
}
handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */
true);
if (playbackInfo.playbackState != Player.STATE_ENDED) {
maybeContinueLoading();
updatePlaybackPositions();
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
}
}
use of com.google.android.exoplayer2.trackselection.TrackSelectorResult in project Telegram-FOSS by Telegram-FOSS-Team.
the class MediaPeriodHolder method handlePrepared.
/**
* Handles period preparation.
*
* @param playbackSpeed The current playback speed.
* @param timeline The current {@link Timeline}.
* @throws ExoPlaybackException If an error occurs during track selection.
*/
public void handlePrepared(float playbackSpeed, Timeline timeline) throws ExoPlaybackException {
prepared = true;
trackGroups = mediaPeriod.getTrackGroups();
TrackSelectorResult selectorResult = selectTracks(playbackSpeed, timeline);
long newStartPositionUs = applyTrackSelection(selectorResult, info.startPositionUs, /* forceRecreateStreams= */
false);
rendererPositionOffsetUs += info.startPositionUs - newStartPositionUs;
info = info.copyWithStartPositionUs(newStartPositionUs);
}
Aggregations