Clean up enabled renderers + processing of resets.

- Made enabledRenderers an array to avoid loads of method calls.
- Made if so that enabled renderers are always called in a consistent
  order, rather than their order changing if they're enabled/disabled
  over time. This is likely to make performance more predictable.
- Split out reading of resets into a separate method. This method is
  now called directly after seeking on the source, so as to ensure
  instant propagation of the new position from source->renderers in
  the common case.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=117225639
This commit is contained in:
olly 2016-03-15 04:27:59 -07:00 committed by Oliver Woodman
parent 9b467b7c1b
commit 9a40a4c77d
10 changed files with 118 additions and 100 deletions

View File

@ -36,7 +36,12 @@ public final class DummyTrackRenderer extends TrackRenderer {
} }
@Override @Override
protected void doSomeWork(long positionUs, long elapsedRealtimeUs) { protected void checkForReset() throws ExoPlaybackException {
throw new IllegalStateException();
}
@Override
protected void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
throw new IllegalStateException(); throw new IllegalStateException();
} }

View File

@ -32,9 +32,7 @@ import android.util.Log;
import android.util.Pair; import android.util.Pair;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
@ -73,7 +71,6 @@ import java.util.concurrent.atomic.AtomicInteger;
private final StandaloneMediaClock standaloneMediaClock; private final StandaloneMediaClock standaloneMediaClock;
private final long minBufferUs; private final long minBufferUs;
private final long minRebufferUs; private final long minRebufferUs;
private final List<TrackRenderer> enabledRenderers;
private final TrackSelection[] trackSelections; private final TrackSelection[] trackSelections;
private final Handler handler; private final Handler handler;
private final HandlerThread internalPlaybackThread; private final HandlerThread internalPlaybackThread;
@ -81,6 +78,7 @@ import java.util.concurrent.atomic.AtomicInteger;
private final AtomicInteger pendingSeekCount; private final AtomicInteger pendingSeekCount;
private SampleSource source; private SampleSource source;
private TrackRenderer[] enabledRenderers;
private boolean released; private boolean released;
private boolean playWhenReady; private boolean playWhenReady;
private boolean rebuffering; private boolean rebuffering;
@ -123,8 +121,8 @@ import java.util.concurrent.atomic.AtomicInteger;
standaloneMediaClock = new StandaloneMediaClock(); standaloneMediaClock = new StandaloneMediaClock();
pendingSeekCount = new AtomicInteger(); pendingSeekCount = new AtomicInteger();
enabledRenderers = new ArrayList<>(renderers.length);
trackSelections = new TrackSelection[renderers.length]; trackSelections = new TrackSelection[renderers.length];
enabledRenderers = new TrackRenderer[0];
trackSelector.init(this); trackSelector.init(this);
@ -361,21 +359,21 @@ import java.util.concurrent.atomic.AtomicInteger;
private void startRenderers() throws ExoPlaybackException { private void startRenderers() throws ExoPlaybackException {
rebuffering = false; rebuffering = false;
standaloneMediaClock.start(); standaloneMediaClock.start();
for (int i = 0; i < enabledRenderers.size(); i++) { for (TrackRenderer renderer : enabledRenderers) {
enabledRenderers.get(i).start(); renderer.start();
} }
} }
private void stopRenderers() throws ExoPlaybackException { private void stopRenderers() throws ExoPlaybackException {
standaloneMediaClock.stop(); standaloneMediaClock.stop();
for (int i = 0; i < enabledRenderers.size(); i++) { for (TrackRenderer renderer : enabledRenderers) {
ensureStopped(enabledRenderers.get(i)); ensureStopped(renderer);
} }
} }
private void updatePositionUs() { private void updatePositionUs() {
if (rendererMediaClock != null && enabledRenderers.contains(rendererMediaClockSource) if (rendererMediaClock != null
&& !rendererMediaClockSource.isEnded()) { && rendererMediaClockSource.getState() != TrackRenderer.STATE_DISABLED) {
positionUs = rendererMediaClock.getPositionUs(); positionUs = rendererMediaClock.getPositionUs();
standaloneMediaClock.setPositionUs(positionUs); standaloneMediaClock.setPositionUs(positionUs);
} else { } else {
@ -387,18 +385,23 @@ import java.util.concurrent.atomic.AtomicInteger;
private void doSomeWork() throws ExoPlaybackException, IOException { private void doSomeWork() throws ExoPlaybackException, IOException {
TraceUtil.beginSection("doSomeWork"); TraceUtil.beginSection("doSomeWork");
long operationStartTimeMs = SystemClock.elapsedRealtime(); long operationStartTimeMs = SystemClock.elapsedRealtime();
// Process resets.
for (TrackRenderer renderer : enabledRenderers) {
renderer.checkForReset();
}
updatePositionUs(); updatePositionUs();
bufferedPositionUs = source.getBufferedPositionUs(); bufferedPositionUs = source.getBufferedPositionUs();
source.continueBuffering(positionUs); source.continueBuffering(positionUs);
boolean allRenderersEnded = true; boolean allRenderersEnded = true;
boolean allRenderersReadyOrEnded = true; boolean allRenderersReadyOrEnded = true;
for (int i = 0; i < enabledRenderers.size(); i++) { for (TrackRenderer renderer : enabledRenderers) {
TrackRenderer renderer = enabledRenderers.get(i);
// TODO: Each renderer should return the maximum delay before which it wishes to be // TODO: Each renderer should return the maximum delay before which it wishes to be
// invoked again. The minimum of these values should then be used as the delay before the next // invoked again. The minimum of these values should then be used as the delay before the next
// invocation of this method. // invocation of this method.
renderer.doSomeWork(positionUs, elapsedRealtimeUs); renderer.render(positionUs, elapsedRealtimeUs);
allRenderersEnded = allRenderersEnded && renderer.isEnded(); allRenderersEnded = allRenderersEnded && renderer.isEnded();
// Determine whether the renderer is ready (or ended). If it's not, throw an error that's // Determine whether the renderer is ready (or ended). If it's not, throw an error that's
// preventing the renderer from making progress, if such an error exists. // preventing the renderer from making progress, if such an error exists.
@ -427,7 +430,7 @@ import java.util.concurrent.atomic.AtomicInteger;
handler.removeMessages(MSG_DO_SOME_WORK); handler.removeMessages(MSG_DO_SOME_WORK);
if ((playWhenReady && state == ExoPlayer.STATE_READY) || state == ExoPlayer.STATE_BUFFERING) { if ((playWhenReady && state == ExoPlayer.STATE_READY) || state == ExoPlayer.STATE_BUFFERING) {
scheduleNextOperation(MSG_DO_SOME_WORK, operationStartTimeMs, RENDERING_INTERVAL_MS); scheduleNextOperation(MSG_DO_SOME_WORK, operationStartTimeMs, RENDERING_INTERVAL_MS);
} else if (!enabledRenderers.isEmpty()) { } else if (enabledRenderers.length != 0) {
scheduleNextOperation(MSG_DO_SOME_WORK, operationStartTimeMs, IDLE_INTERVAL_MS); scheduleNextOperation(MSG_DO_SOME_WORK, operationStartTimeMs, IDLE_INTERVAL_MS);
} }
@ -459,12 +462,16 @@ import java.util.concurrent.atomic.AtomicInteger;
if (state == ExoPlayer.STATE_IDLE || state == ExoPlayer.STATE_PREPARING) { if (state == ExoPlayer.STATE_IDLE || state == ExoPlayer.STATE_PREPARING) {
return; return;
} }
for (int i = 0; i < enabledRenderers.size(); i++) {
TrackRenderer renderer = enabledRenderers.get(i); for (TrackRenderer renderer : enabledRenderers) {
ensureStopped(renderer); ensureStopped(renderer);
} }
setState(ExoPlayer.STATE_BUFFERING); setState(ExoPlayer.STATE_BUFFERING);
source.seekToUs(positionUs); source.seekToUs(positionUs);
for (TrackRenderer renderer : enabledRenderers) {
renderer.checkForReset();
}
handler.sendEmptyMessage(MSG_DO_SOME_WORK); handler.sendEmptyMessage(MSG_DO_SOME_WORK);
} finally { } finally {
pendingSeekCount.decrementAndGet(); pendingSeekCount.decrementAndGet();
@ -493,10 +500,10 @@ import java.util.concurrent.atomic.AtomicInteger;
if (renderers == null) { if (renderers == null) {
return; return;
} }
for (int i = 0; i < renderers.length; i++) { for (TrackRenderer renderer : renderers) {
resetRendererInternal(renderers[i]); resetRendererInternal(renderer);
} }
enabledRenderers.clear(); enabledRenderers = new TrackRenderer[0];
Arrays.fill(trackSelections, null); Arrays.fill(trackSelections, null);
source = null; source = null;
} }
@ -547,16 +554,19 @@ import java.util.concurrent.atomic.AtomicInteger;
// Disable renderers whose track selections have changed. // Disable renderers whose track selections have changed.
boolean[] rendererWasEnabledFlags = new boolean[renderers.length]; boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
int enabledRendererCount = 0;
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
TrackRenderer renderer = renderers[i]; TrackRenderer renderer = renderers[i];
TrackSelection previousTrackSelection = trackSelections[i]; TrackSelection previousTrackSelection = trackSelections[i];
trackSelections[i] = newTrackSelections.get(i); trackSelections[i] = newTrackSelections.get(i);
if (trackSelections[i] != null) {
enabledRendererCount++;
}
rendererWasEnabledFlags[i] = renderer.getState() != TrackRenderer.STATE_DISABLED;
if (!Util.areEqual(previousTrackSelection, trackSelections[i])) { if (!Util.areEqual(previousTrackSelection, trackSelections[i])) {
// The track selection has changed for this renderer. // The track selection has changed for this renderer.
int rendererState = renderer.getState(); if (rendererWasEnabledFlags[i]) {
boolean isEnabled = rendererState == TrackRenderer.STATE_ENABLED // We need to disable the renderer so that we can enable it with its new selection.
|| rendererState == TrackRenderer.STATE_STARTED;
if (isEnabled) {
if (trackSelections[i] == null && renderer == rendererMediaClockSource) { if (trackSelections[i] == null && renderer == rendererMediaClockSource) {
// We've been using rendererMediaClockSource to advance the current position, but it's // We've been using rendererMediaClockSource to advance the current position, but it's
// being disabled and won't be re-enabled. Sync standaloneMediaClock so that it can take // being disabled and won't be re-enabled. Sync standaloneMediaClock so that it can take
@ -564,21 +574,21 @@ import java.util.concurrent.atomic.AtomicInteger;
standaloneMediaClock.setPositionUs(rendererMediaClock.getPositionUs()); standaloneMediaClock.setPositionUs(rendererMediaClock.getPositionUs());
} }
ensureStopped(renderer); ensureStopped(renderer);
enabledRenderers.remove(renderer);
renderer.disable(); renderer.disable();
} }
rendererWasEnabledFlags[i] = isEnabled;
} }
} }
enabledRenderers = new TrackRenderer[enabledRendererCount];
enabledRendererCount = 0;
// Enable renderers with their new track selections. // Enable renderers with their new track selections.
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
TrackRenderer renderer = renderers[i]; TrackRenderer renderer = renderers[i];
TrackSelection trackSelection = trackSelections[i]; TrackSelection trackSelection = trackSelections[i];
int rendererState = renderer.getState(); if (trackSelection != null) {
boolean isEnabled = rendererState == TrackRenderer.STATE_ENABLED enabledRenderers[enabledRendererCount++] = renderer;
|| rendererState == TrackRenderer.STATE_STARTED; if (renderer.getState() == TrackRenderer.STATE_DISABLED) {
if (!isEnabled && trackSelection != null) {
// The renderer needs enabling with its new track selection. // The renderer needs enabling with its new track selection.
boolean playing = playWhenReady && state == ExoPlayer.STATE_READY; boolean playing = playWhenReady && state == ExoPlayer.STATE_READY;
// Consider as joining only if the renderer was previously disabled. // Consider as joining only if the renderer was previously disabled.
@ -592,12 +602,12 @@ import java.util.concurrent.atomic.AtomicInteger;
} }
// Enable the renderer. // Enable the renderer.
renderer.enable(formats, trackStream, positionUs, joining); renderer.enable(formats, trackStream, positionUs, joining);
enabledRenderers.add(renderer);
if (playing) { if (playing) {
renderer.start(); renderer.start();
} }
} }
} }
}
// The new selections have been activated. // The new selections have been activated.
trackSelector.onSelectionActivated(result.second); trackSelector.onSelectionActivated(result.second);

View File

@ -319,8 +319,8 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
} }
@Override @Override
protected void onReset(long positionUs) throws ExoPlaybackException { protected void reset(long positionUs) throws ExoPlaybackException {
super.onReset(positionUs); super.reset(positionUs);
audioTrack.reset(); audioTrack.reset();
currentPositionUs = positionUs; currentPositionUs = positionUs;
allowPositionDiscontinuity = true; allowPositionDiscontinuity = true;

View File

@ -461,7 +461,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
} }
@Override @Override
protected void onReset(long positionUs) throws ExoPlaybackException { protected void reset(long positionUs) throws ExoPlaybackException {
sourceState = SOURCE_STATE_NOT_READY; sourceState = SOURCE_STATE_NOT_READY;
inputStreamEnded = false; inputStreamEnded = false;
outputStreamEnded = false; outputStreamEnded = false;
@ -481,7 +481,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
} }
@Override @Override
protected void doSomeWork(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady) protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
throws ExoPlaybackException { throws ExoPlaybackException {
sourceState = sourceIsReady sourceState = sourceIsReady
? (sourceState == SOURCE_STATE_NOT_READY ? SOURCE_STATE_READY : sourceState) ? (sourceState == SOURCE_STATE_NOT_READY ? SOURCE_STATE_READY : sourceState)
@ -537,7 +537,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
/** /**
* @param firstFeed True if this is the first call to this method from the current invocation of * @param firstFeed True if this is the first call to this method from the current invocation of
* {@link #doSomeWork(long, long)}. False otherwise. * {@link #render(long, long)}. False otherwise.
* @return True if it may be possible to feed more input data. False otherwise. * @return True if it may be possible to feed more input data. False otherwise.
* @throws ExoPlaybackException If an error occurs feeding the input buffer. * @throws ExoPlaybackException If an error occurs feeding the input buffer.
*/ */

View File

@ -284,8 +284,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
} }
@Override @Override
protected void onReset(long positionUs) throws ExoPlaybackException { protected void reset(long positionUs) throws ExoPlaybackException {
super.onReset(positionUs); super.reset(positionUs);
renderedFirstFrame = false; renderedFirstFrame = false;
consecutiveDroppedFrameCount = 0; consecutiveDroppedFrameCount = 0;
joiningDeadlineUs = -1; joiningDeadlineUs = -1;
@ -293,8 +293,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
@Override @Override
protected boolean isReady() { protected boolean isReady() {
if (super.isReady() && (renderedFirstFrame || !codecInitialized() if (super.isReady()
|| getSourceState() == SOURCE_STATE_READY_READ_MAY_FAIL)) { && (renderedFirstFrame || getSourceState() == SOURCE_STATE_READY_READ_MAY_FAIL)) {
// Ready. If we were joining then we've now joined, so clear the joining deadline. // Ready. If we were joining then we've now joined, so clear the joining deadline.
joiningDeadlineUs = -1; joiningDeadlineUs = -1;
return true; return true;

View File

@ -31,23 +31,26 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs, protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs,
boolean joining) throws ExoPlaybackException { boolean joining) throws ExoPlaybackException {
this.trackStream = Assertions.checkNotNull(trackStream); this.trackStream = Assertions.checkNotNull(trackStream);
onReset(positionUs); reset(positionUs);
} }
@Override @Override
protected final void doSomeWork(long positionUs, long elapsedRealtimeUs) protected final void checkForReset() throws ExoPlaybackException {
throws ExoPlaybackException {
// TODO[REFACTOR]: Consider splitting reading of resets into a separate method?
long resetPositionUs = trackStream.readReset(); long resetPositionUs = trackStream.readReset();
if (resetPositionUs != TrackStream.NO_RESET) { if (resetPositionUs != TrackStream.NO_RESET) {
onReset(resetPositionUs); reset(resetPositionUs);
return; return;
} }
doSomeWork(positionUs, elapsedRealtimeUs, trackStream.isReady());
} }
@Override @Override
protected void maybeThrowError() throws IOException { protected final void render(long positionUs, long elapsedRealtimeUs)
throws ExoPlaybackException {
render(positionUs, elapsedRealtimeUs, trackStream.isReady());
}
@Override
protected final void maybeThrowError() throws IOException {
trackStream.maybeThrowError(); trackStream.maybeThrowError();
} }
@ -77,15 +80,15 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
// Abstract methods. // Abstract methods.
/** /**
* Invoked when a reset is encountered. Also invoked when the renderer is enabled. * Invoked when a reset is encountered, and also when the renderer is enabled.
* *
* @param positionUs The playback position in microseconds. * @param positionUs The playback position in microseconds.
* @throws ExoPlaybackException If an error occurs handling the reset. * @throws ExoPlaybackException If an error occurs handling the reset.
*/ */
protected abstract void onReset(long positionUs) throws ExoPlaybackException; protected abstract void reset(long positionUs) throws ExoPlaybackException;
/** /**
* Called by {@link #doSomeWork(long, long)}. * Called by {@link #render(long, long)}.
* *
* @param positionUs The current media time in microseconds, measured at the start of the * @param positionUs The current media time in microseconds, measured at the start of the
* current iteration of the rendering loop. * current iteration of the rendering loop.
@ -93,9 +96,8 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
* measured at the start of the current iteration of the rendering loop. * measured at the start of the current iteration of the rendering loop.
* @param sourceIsReady The result of the most recent call to {@link TrackStream#isReady()}. * @param sourceIsReady The result of the most recent call to {@link TrackStream#isReady()}.
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
* @throws ExoPlaybackException
*/ */
protected abstract void doSomeWork(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady) protected abstract void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
throws ExoPlaybackException; throws ExoPlaybackException;
} }

View File

@ -92,19 +92,16 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
public static final int ADAPTIVE_NOT_SUPPORTED = 0b0000; public static final int ADAPTIVE_NOT_SUPPORTED = 0b0000;
/** /**
* The renderer is idle. * The renderer is disabled.
*/ */
protected static final int STATE_IDLE = 0; protected static final int STATE_DISABLED = 0;
/** /**
* The renderer is enabled. It should either be ready to be started, or be actively working * The renderer is enabled but not started. A renderer in this state will typically hold any
* towards this state (e.g. a renderer in this state will typically hold any resources that it * resources that it requires for rendering (e.g. media decoders).
* requires, such as media decoders, and will have buffered or be buffering any media data that
* is required to start playback).
*/ */
protected static final int STATE_ENABLED = 1; protected static final int STATE_ENABLED = 1;
/** /**
* The renderer is started. Calls to {@link #doSomeWork(long, long)} should cause the media to be * The renderer is started. Calls to {@link #render(long, long)} will cause media to be rendered.
* rendered.
*/ */
protected static final int STATE_STARTED = 2; protected static final int STATE_STARTED = 2;
@ -195,7 +192,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
*/ */
/* package */ final void enable(Format[] formats, TrackStream trackStream, long positionUs, /* package */ final void enable(Format[] formats, TrackStream trackStream, long positionUs,
boolean joining) throws ExoPlaybackException { boolean joining) throws ExoPlaybackException {
Assertions.checkState(state == STATE_IDLE); Assertions.checkState(state == STATE_DISABLED);
state = STATE_ENABLED; state = STATE_ENABLED;
onEnabled(formats, trackStream, positionUs, joining); onEnabled(formats, trackStream, positionUs, joining);
} }
@ -217,8 +214,8 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
} }
/** /**
* Starts the renderer, meaning that calls to {@link #doSomeWork(long, long)} will cause the * Starts the renderer, meaning that calls to {@link #render(long, long)} will cause media to be
* track to be rendered. * rendered.
* *
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
*/ */
@ -268,7 +265,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
*/ */
/* package */ final void disable() throws ExoPlaybackException { /* package */ final void disable() throws ExoPlaybackException {
Assertions.checkState(state == STATE_ENABLED); Assertions.checkState(state == STATE_ENABLED);
state = STATE_IDLE; state = STATE_DISABLED;
onDisabled(); onDisabled();
} }
@ -289,7 +286,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* returned by all of its {@link TrackRenderer}s. * returned by all of its {@link TrackRenderer}s.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED} * {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
* *
* @return Whether the renderer is ready for the player to transition to the ended state. * @return Whether the renderer is ready for the player to transition to the ended state.
*/ */
@ -306,26 +303,30 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* renderer is ready for playback to be started. Returning false indicates that it is not. * renderer is ready for playback to be started. Returning false indicates that it is not.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED} * {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
* *
* @return True if the renderer is ready to render media. False otherwise. * @return True if the renderer is ready to render media. False otherwise.
*/ */
protected abstract boolean isReady(); protected abstract boolean isReady();
/** /**
* Invoked to make progress when the renderer is in the {@link #STATE_ENABLED} or * Attempts to read and process a pending reset from the {@link TrackStream}.
* {@link #STATE_STARTED} states.
* <p>
* If the renderer's state is {@link #STATE_STARTED}, then repeated calls to this method should
* cause the media track to be rendered. If the state is {@link #STATE_ENABLED}, then repeated
* calls should make progress towards getting the renderer into a position where it is ready to
* render the track.
* <p>
* This method should return quickly, and should not block if the renderer is currently unable to
* make any useful progress.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED} * {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
*
* @throws ExoPlaybackException If an error occurs.
*/
protected abstract void checkForReset() throws ExoPlaybackException;
/**
* Incrementally renders the {@link TrackStream}.
* <p>
* This method should return quickly, and should not block if the renderer is unable to make
* useful progress.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
* *
* @param positionUs The current media time in microseconds, measured at the start of the * @param positionUs The current media time in microseconds, measured at the start of the
* current iteration of the rendering loop. * current iteration of the rendering loop.
@ -333,7 +334,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* measured at the start of the current iteration of the rendering loop. * measured at the start of the current iteration of the rendering loop.
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
*/ */
protected abstract void doSomeWork(long positionUs, long elapsedRealtimeUs) protected abstract void render(long positionUs, long elapsedRealtimeUs)
throws ExoPlaybackException; throws ExoPlaybackException;
/** /**
@ -341,7 +342,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* this point in time. * this point in time.
* <p> * <p>
* This method may be called when the renderer is in the following states: * This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED} * {@link #STATE_ENABLED}.
* *
* @throws IOException An error that's preventing the renderer from making progress or buffering * @throws IOException An error that's preventing the renderer from making progress or buffering
* more data. * more data.

View File

@ -92,13 +92,13 @@ public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer im
} }
@Override @Override
protected void onReset(long positionUs) { protected void reset(long positionUs) {
pendingMetadata = null; pendingMetadata = null;
inputStreamEnded = false; inputStreamEnded = false;
} }
@Override @Override
protected void doSomeWork(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady) protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
throws ExoPlaybackException { throws ExoPlaybackException {
if (!inputStreamEnded && pendingMetadata == null) { if (!inputStreamEnded && pendingMetadata == null) {
sampleHolder.clearData(); sampleHolder.clearData();

View File

@ -173,7 +173,7 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
} }
@Override @Override
protected void onReset(long positionUs) { protected void reset(long positionUs) {
inputStreamEnded = false; inputStreamEnded = false;
subtitle = null; subtitle = null;
nextSubtitle = null; nextSubtitle = null;
@ -184,7 +184,7 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
} }
@Override @Override
protected void doSomeWork(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady) protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
throws ExoPlaybackException { throws ExoPlaybackException {
if (nextSubtitle == null) { if (nextSubtitle == null) {
try { try {

View File

@ -93,7 +93,7 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
} }
@Override @Override
protected void onReset(long positionUs) { protected void reset(long positionUs) {
inputStreamEnded = false; inputStreamEnded = false;
repeatableControl = null; repeatableControl = null;
pendingCaptionLists.clear(); pendingCaptionLists.clear();
@ -104,7 +104,7 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
} }
@Override @Override
protected void doSomeWork(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady) protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
throws ExoPlaybackException { throws ExoPlaybackException {
if (isSamplePending()) { if (isSamplePending()) {
maybeParsePendingSample(positionUs); maybeParsePendingSample(positionUs);