ExoPlayer V2 Refactor - Step 3
Move binding of tracks<->renderers to ExoPlayerImplInternal. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=113046018
This commit is contained in:
parent
cdae9ac5d2
commit
6cb20525cb
@ -17,26 +17,12 @@ package com.google.android.exoplayer;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link TrackRenderer} that does nothing.
|
* A {@link TrackRenderer} that does nothing.
|
||||||
* <p>
|
|
||||||
* This renderer returns 0 from {@link #getTrackCount()} in order to request that it should be
|
|
||||||
* ignored. {@link IllegalStateException} is thrown from all other methods documented to indicate
|
|
||||||
* that they should not be invoked unless the renderer is prepared.
|
|
||||||
*/
|
*/
|
||||||
public final class DummyTrackRenderer extends TrackRenderer {
|
public final class DummyTrackRenderer extends TrackRenderer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPrepare(SampleSource sampleSource) throws ExoPlaybackException {
|
protected boolean handlesTrack(MediaFormat mediaFormat) throws ExoPlaybackException {
|
||||||
// Do nothing.
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getTrackCount() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MediaFormat getFormat(int track) {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer;
|
package com.google.android.exoplayer;
|
||||||
|
|
||||||
import com.google.android.exoplayer.ExoPlayer.ExoPlayerComponent;
|
import com.google.android.exoplayer.ExoPlayer.ExoPlayerComponent;
|
||||||
|
import com.google.android.exoplayer.SampleSource.TrackStream;
|
||||||
import com.google.android.exoplayer.util.Assertions;
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
import com.google.android.exoplayer.util.PriorityHandlerThread;
|
import com.google.android.exoplayer.util.PriorityHandlerThread;
|
||||||
import com.google.android.exoplayer.util.TraceUtil;
|
import com.google.android.exoplayer.util.TraceUtil;
|
||||||
@ -74,7 +75,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
private final long minBufferUs;
|
private final long minBufferUs;
|
||||||
private final long minRebufferUs;
|
private final long minRebufferUs;
|
||||||
private final List<TrackRenderer> enabledRenderers;
|
private final List<TrackRenderer> enabledRenderers;
|
||||||
private final MediaFormat[][] trackFormats;
|
private final int[][] trackIndices;
|
||||||
private final int[] selectedTrackIndices;
|
private final int[] selectedTrackIndices;
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
private final HandlerThread internalPlaybackThread;
|
private final HandlerThread internalPlaybackThread;
|
||||||
@ -123,8 +124,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
standaloneMediaClock = new StandaloneMediaClock();
|
standaloneMediaClock = new StandaloneMediaClock();
|
||||||
pendingSeekCount = new AtomicInteger();
|
pendingSeekCount = new AtomicInteger();
|
||||||
enabledRenderers = new ArrayList<>(selectedTrackIndices.length);
|
enabledRenderers = new ArrayList<>(renderers.length);
|
||||||
trackFormats = new MediaFormat[selectedTrackIndices.length][];
|
trackIndices = new int[renderers.length][];
|
||||||
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
|
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
|
||||||
// not normally change to this priority" is incorrect.
|
// not normally change to this priority" is incorrect.
|
||||||
internalPlaybackThread = new PriorityHandlerThread("ExoPlayerImplInternal:Handler",
|
internalPlaybackThread = new PriorityHandlerThread("ExoPlayerImplInternal:Handler",
|
||||||
@ -299,25 +300,42 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
boolean allRenderersEnded = true;
|
boolean allRenderersEnded = true;
|
||||||
boolean allRenderersReadyOrEnded = true;
|
boolean allRenderersReadyOrEnded = true;
|
||||||
|
|
||||||
|
// Establish the mapping from renderer to track index (trackIndices), and build a list of
|
||||||
|
// formats corresponding to each renderer (trackFormats).
|
||||||
|
int trackCount = source.getTrackCount();
|
||||||
|
boolean[] trackMappedFlags = new boolean[trackCount];
|
||||||
|
MediaFormat[][] trackFormats = new MediaFormat[renderers.length][];
|
||||||
for (int rendererIndex = 0; rendererIndex < renderers.length; rendererIndex++) {
|
for (int rendererIndex = 0; rendererIndex < renderers.length; rendererIndex++) {
|
||||||
TrackRenderer renderer = renderers[rendererIndex];
|
TrackRenderer renderer = renderers[rendererIndex];
|
||||||
renderer.prepare(source);
|
int rendererTrackCount = 0;
|
||||||
int rendererTrackCount = renderer.getTrackCount();
|
int[] rendererTrackIndices = new int[trackCount];
|
||||||
MediaFormat[] rendererTrackFormats = new MediaFormat[rendererTrackCount];
|
MediaFormat[] rendererTrackFormats = new MediaFormat[trackCount];
|
||||||
for (int trackIndex = 0; trackIndex < rendererTrackCount; trackIndex++) {
|
for (int trackIndex = 0; trackIndex < trackCount; trackIndex++) {
|
||||||
rendererTrackFormats[trackIndex] = renderer.getFormat(trackIndex);
|
MediaFormat trackFormat = source.getFormat(trackIndex);
|
||||||
|
if (!trackMappedFlags[trackIndex] && renderer.handlesTrack(trackFormat)) {
|
||||||
|
trackMappedFlags[trackIndex] = true;
|
||||||
|
rendererTrackIndices[rendererTrackCount] = trackIndex;
|
||||||
|
rendererTrackFormats[rendererTrackCount++] = trackFormat;
|
||||||
}
|
}
|
||||||
trackFormats[rendererIndex] = rendererTrackFormats;
|
}
|
||||||
if (rendererTrackCount > 0) {
|
trackIndices[rendererIndex] = Arrays.copyOf(rendererTrackIndices, rendererTrackCount);
|
||||||
|
trackFormats[rendererIndex] = Arrays.copyOf(rendererTrackFormats, rendererTrackCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable renderers where appropriate.
|
||||||
|
for (int rendererIndex = 0; rendererIndex < renderers.length; rendererIndex++) {
|
||||||
|
TrackRenderer renderer = renderers[rendererIndex];
|
||||||
int trackIndex = selectedTrackIndices[rendererIndex];
|
int trackIndex = selectedTrackIndices[rendererIndex];
|
||||||
if (0 <= trackIndex && trackIndex < rendererTrackFormats.length) {
|
if (0 <= trackIndex && trackIndex < trackIndices[rendererIndex].length) {
|
||||||
renderer.enable(trackIndex, positionUs, false);
|
int sourceTrackIndex = trackIndices[rendererIndex][trackIndex];
|
||||||
|
TrackStream trackStream = source.enable(sourceTrackIndex, positionUs);
|
||||||
|
renderer.enable(trackStream, positionUs, false);
|
||||||
enabledRenderers.add(renderer);
|
enabledRenderers.add(renderer);
|
||||||
allRenderersEnded = allRenderersEnded && renderer.isEnded();
|
allRenderersEnded = allRenderersEnded && renderer.isEnded();
|
||||||
allRenderersReadyOrEnded = allRenderersReadyOrEnded && isReadyOrEnded(renderer);
|
allRenderersReadyOrEnded = allRenderersReadyOrEnded && isReadyOrEnded(renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (allRenderersEnded && (durationUs == C.UNKNOWN_TIME_US || durationUs <= positionUs)) {
|
if (allRenderersEnded && (durationUs == C.UNKNOWN_TIME_US || durationUs <= positionUs)) {
|
||||||
// We don't expect this case, but handle it anyway.
|
// We don't expect this case, but handle it anyway.
|
||||||
@ -507,20 +525,18 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < renderers.length; i++) {
|
for (int i = 0; i < renderers.length; i++) {
|
||||||
unprepare(renderers[i]);
|
resetRendererInternal(renderers[i]);
|
||||||
}
|
}
|
||||||
enabledRenderers.clear();
|
enabledRenderers.clear();
|
||||||
|
Arrays.fill(trackIndices, null);
|
||||||
source = null;
|
source = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unprepare(TrackRenderer renderer) {
|
private void resetRendererInternal(TrackRenderer renderer) {
|
||||||
try {
|
try {
|
||||||
ensureStopped(renderer);
|
ensureStopped(renderer);
|
||||||
if (renderer.getState() == TrackRenderer.STATE_ENABLED) {
|
if (renderer.getState() == TrackRenderer.STATE_ENABLED) {
|
||||||
renderer.disable();
|
renderer.disable();
|
||||||
renderer.unprepare();
|
|
||||||
} else if (renderer.getState() == TrackRenderer.STATE_PREPARED) {
|
|
||||||
renderer.unprepare();
|
|
||||||
}
|
}
|
||||||
} catch (ExoPlaybackException e) {
|
} catch (ExoPlaybackException e) {
|
||||||
// There's nothing we can do.
|
// There's nothing we can do.
|
||||||
@ -562,13 +578,13 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
TrackRenderer renderer = renderers[rendererIndex];
|
TrackRenderer renderer = renderers[rendererIndex];
|
||||||
int rendererState = renderer.getState();
|
int rendererState = renderer.getState();
|
||||||
if (rendererState == TrackRenderer.STATE_UNPREPARED || renderer.getTrackCount() == 0) {
|
if (trackIndices[rendererIndex].length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isEnabled = rendererState == TrackRenderer.STATE_ENABLED
|
boolean isEnabled = rendererState == TrackRenderer.STATE_ENABLED
|
||||||
|| rendererState == TrackRenderer.STATE_STARTED;
|
|| rendererState == TrackRenderer.STATE_STARTED;
|
||||||
boolean shouldEnable = 0 <= trackIndex && trackIndex < trackFormats[rendererIndex].length;
|
boolean shouldEnable = 0 <= trackIndex && trackIndex < trackIndices[rendererIndex].length;
|
||||||
|
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
// The renderer is currently enabled. We need to disable it, so that we can either re-enable
|
// The renderer is currently enabled. We need to disable it, so that we can either re-enable
|
||||||
@ -590,7 +606,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
boolean playing = playWhenReady && state == ExoPlayer.STATE_READY;
|
boolean playing = playWhenReady && state == ExoPlayer.STATE_READY;
|
||||||
// Consider as joining if the renderer was previously disabled, but not when switching tracks.
|
// Consider as joining if the renderer was previously disabled, but not when switching tracks.
|
||||||
boolean joining = !isEnabled && playing;
|
boolean joining = !isEnabled && playing;
|
||||||
renderer.enable(trackIndex, positionUs, joining);
|
int sourceTrackIndex = trackIndices[rendererIndex][trackIndex];
|
||||||
|
TrackStream trackStream = source.enable(sourceTrackIndex, positionUs);
|
||||||
|
renderer.enable(trackStream, positionUs, joining);
|
||||||
enabledRenderers.add(renderer);
|
enabledRenderers.add(renderer);
|
||||||
if (playing) {
|
if (playing) {
|
||||||
renderer.start();
|
renderer.start();
|
||||||
|
@ -262,8 +262,12 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final boolean handlesTrack(MediaFormat mediaFormat) throws DecoderQueryException {
|
protected final boolean handlesTrack(MediaFormat mediaFormat) throws ExoPlaybackException {
|
||||||
|
try {
|
||||||
return handlesTrack(mediaCodecSelector, mediaFormat);
|
return handlesTrack(mediaCodecSelector, mediaFormat);
|
||||||
|
} catch (DecoderQueryException e) {
|
||||||
|
throw new ExoPlaybackException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,6 +43,7 @@ public final class MediaCodecUtil {
|
|||||||
* Such failures are not expected in normal operation and are normally temporary (e.g. if the
|
* Such failures are not expected in normal operation and are normally temporary (e.g. if the
|
||||||
* mediaserver process has crashed and is yet to restart).
|
* mediaserver process has crashed and is yet to restart).
|
||||||
*/
|
*/
|
||||||
|
// TODO[REFACTOR]: Shouldn't implement IOException.
|
||||||
public static class DecoderQueryException extends IOException {
|
public static class DecoderQueryException extends IOException {
|
||||||
|
|
||||||
private DecoderQueryException(Throwable cause) {
|
private DecoderQueryException(Throwable cause) {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer;
|
package com.google.android.exoplayer;
|
||||||
|
|
||||||
import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException;
|
import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException;
|
||||||
|
import com.google.android.exoplayer.SampleSource.TrackStream;
|
||||||
import com.google.android.exoplayer.drm.DrmSessionManager;
|
import com.google.android.exoplayer.drm.DrmSessionManager;
|
||||||
import com.google.android.exoplayer.util.MimeTypes;
|
import com.google.android.exoplayer.util.MimeTypes;
|
||||||
import com.google.android.exoplayer.util.TraceUtil;
|
import com.google.android.exoplayer.util.TraceUtil;
|
||||||
@ -220,9 +221,9 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onEnabled(int track, long positionUs, boolean joining)
|
protected void onEnabled(TrackStream trackStream, long positionUs, boolean joining)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
super.onEnabled(track, positionUs, joining);
|
super.onEnabled(trackStream, positionUs, joining);
|
||||||
if (joining && allowedJoiningTimeUs > 0) {
|
if (joining && allowedJoiningTimeUs > 0) {
|
||||||
joiningDeadlineUs = SystemClock.elapsedRealtime() * 1000L + allowedJoiningTimeUs;
|
joiningDeadlineUs = SystemClock.elapsedRealtime() * 1000L + allowedJoiningTimeUs;
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer;
|
package com.google.android.exoplayer;
|
||||||
|
|
||||||
import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException;
|
|
||||||
import com.google.android.exoplayer.SampleSource.TrackStream;
|
import com.google.android.exoplayer.SampleSource.TrackStream;
|
||||||
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for {@link TrackRenderer} implementations that render samples obtained from a
|
* Base class for {@link TrackRenderer} implementations that render samples obtained from a
|
||||||
@ -27,36 +26,12 @@ import java.util.Arrays;
|
|||||||
*/
|
*/
|
||||||
public abstract class SampleSourceTrackRenderer extends TrackRenderer {
|
public abstract class SampleSourceTrackRenderer extends TrackRenderer {
|
||||||
|
|
||||||
private SampleSource source;
|
|
||||||
private TrackStream trackStream;
|
private TrackStream trackStream;
|
||||||
private int[] handledTrackIndices;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void doPrepare(SampleSource source) throws ExoPlaybackException {
|
protected void onEnabled(TrackStream trackStream, long positionUs, boolean joining)
|
||||||
int sourceTrackCount = source.getTrackCount();
|
|
||||||
int[] handledTrackIndices = new int[sourceTrackCount];
|
|
||||||
int handledTrackCount = 0;
|
|
||||||
for (int trackIndex = 0; trackIndex < sourceTrackCount; trackIndex++) {
|
|
||||||
MediaFormat format = source.getFormat(trackIndex);
|
|
||||||
boolean handlesTrack;
|
|
||||||
try {
|
|
||||||
handlesTrack = handlesTrack(format);
|
|
||||||
} catch (DecoderQueryException e) {
|
|
||||||
throw new ExoPlaybackException(e);
|
|
||||||
}
|
|
||||||
if (handlesTrack) {
|
|
||||||
handledTrackIndices[handledTrackCount] = trackIndex;
|
|
||||||
handledTrackCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.source = source;
|
|
||||||
this.handledTrackIndices = Arrays.copyOf(handledTrackIndices, handledTrackCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onEnabled(int track, long positionUs, boolean joining)
|
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
trackStream = source.enable(handledTrackIndices[track], positionUs);
|
this.trackStream = Assertions.checkNotNull(trackStream);
|
||||||
onReset(positionUs);
|
onReset(positionUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,10 +49,8 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void maybeThrowError() throws IOException {
|
protected void maybeThrowError() throws IOException {
|
||||||
if (source != null) {
|
|
||||||
trackStream.maybeThrowError();
|
trackStream.maybeThrowError();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDisabled() throws ExoPlaybackException {
|
protected void onDisabled() throws ExoPlaybackException {
|
||||||
@ -85,22 +58,6 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
|
|||||||
trackStream = null;
|
trackStream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onUnprepared() {
|
|
||||||
source = null;
|
|
||||||
handledTrackIndices = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected final int getTrackCount() {
|
|
||||||
return handledTrackIndices.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected final MediaFormat getFormat(int track) {
|
|
||||||
return source.getFormat(handledTrackIndices[track]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods to be called by subclasses.
|
// Methods to be called by subclasses.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,15 +77,6 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
|
|||||||
|
|
||||||
// Abstract methods.
|
// Abstract methods.
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether this renderer is capable of handling the provided track.
|
|
||||||
*
|
|
||||||
* @param mediaFormat The format of the track.
|
|
||||||
* @return True if the renderer can handle the track, false otherwise.
|
|
||||||
* @throws DecoderQueryException Thrown if there was an error querying decoders.
|
|
||||||
*/
|
|
||||||
protected abstract boolean handlesTrack(MediaFormat mediaFormat) throws DecoderQueryException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when a reset is encountered. Also invoked when the renderer is enabled.
|
* Invoked when a reset is encountered. Also invoked when the renderer is enabled.
|
||||||
*
|
*
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer;
|
package com.google.android.exoplayer;
|
||||||
|
|
||||||
import com.google.android.exoplayer.ExoPlayer.ExoPlayerComponent;
|
import com.google.android.exoplayer.ExoPlayer.ExoPlayerComponent;
|
||||||
|
import com.google.android.exoplayer.SampleSource.TrackStream;
|
||||||
import com.google.android.exoplayer.util.Assertions;
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -34,29 +35,21 @@ import java.io.IOException;
|
|||||||
public abstract class TrackRenderer implements ExoPlayerComponent {
|
public abstract class TrackRenderer implements ExoPlayerComponent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The renderer has not yet been prepared.
|
* The renderer is idle.
|
||||||
*/
|
*/
|
||||||
protected static final int STATE_UNPREPARED = 0;
|
protected static final int STATE_IDLE = 0;
|
||||||
/**
|
|
||||||
* The renderer has completed necessary preparation. Preparation may include, for example,
|
|
||||||
* reading the header of a media file to determine the track format and duration.
|
|
||||||
* <p>
|
|
||||||
* The renderer should not hold scarce or expensive system resources (e.g. media decoders) and
|
|
||||||
* should not be actively buffering media data when in this state.
|
|
||||||
*/
|
|
||||||
protected static final int STATE_PREPARED = 1;
|
|
||||||
/**
|
/**
|
||||||
* The renderer is enabled. It should either be ready to be started, or be actively working
|
* The renderer is enabled. It should either be ready to be started, or be actively working
|
||||||
* towards this state (e.g. a renderer in this state will typically hold any resources that it
|
* towards this state (e.g. a renderer in this state will typically hold any resources that it
|
||||||
* requires, such as media decoders, and will have buffered or be buffering any media data that
|
* requires, such as media decoders, and will have buffered or be buffering any media data that
|
||||||
* is required to start playback).
|
* is required to start playback).
|
||||||
*/
|
*/
|
||||||
protected static final int STATE_ENABLED = 2;
|
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 #doSomeWork(long, long)} should cause the media to be
|
||||||
* rendered.
|
* rendered.
|
||||||
*/
|
*/
|
||||||
protected static final int STATE_STARTED = 3;
|
protected static final int STATE_STARTED = 2;
|
||||||
|
|
||||||
private int state;
|
private int state;
|
||||||
|
|
||||||
@ -82,56 +75,27 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares the renderer to read from the provided {@link SampleSource}.
|
* Returns whether this renderer is capable of handling the provided track.
|
||||||
* <p>
|
|
||||||
* The {@link SampleSource} must itself be prepared before it is passed to this method.
|
|
||||||
*
|
*
|
||||||
* @param sampleSource The {@link SampleSource} from which to read.
|
* @param mediaFormat The format of the track.
|
||||||
|
* @return True if the renderer can handle the track, false otherwise.
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
* @throws ExoPlaybackException If an error occurs.
|
||||||
*/
|
*/
|
||||||
/* package */ final void prepare(SampleSource sampleSource) throws ExoPlaybackException {
|
protected abstract boolean handlesTrack(MediaFormat mediaFormat) throws ExoPlaybackException;
|
||||||
Assertions.checkState(state == STATE_UNPREPARED);
|
|
||||||
Assertions.checkState(sampleSource.isPrepared());
|
|
||||||
doPrepare(sampleSource);
|
|
||||||
state = STATE_PREPARED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the renderer is prepared.
|
* Enable the renderer to consume from the specified {@link TrackStream}.
|
||||||
*
|
*
|
||||||
* @param sampleSource The {@link SampleSource} from which to read.
|
* @param trackStream The track stream from which the renderer should consume.
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
|
||||||
*/
|
|
||||||
protected abstract void doPrepare(SampleSource sampleSource) throws ExoPlaybackException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of tracks exposed by the renderer.
|
|
||||||
*
|
|
||||||
* @return The number of tracks.
|
|
||||||
*/
|
|
||||||
protected abstract int getTrackCount();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the format of the specified track.
|
|
||||||
*
|
|
||||||
* @param track The track index.
|
|
||||||
* @return The format of the specified track.
|
|
||||||
*/
|
|
||||||
protected abstract MediaFormat getFormat(int track);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable the renderer for a specified track.
|
|
||||||
*
|
|
||||||
* @param track The track for which the renderer is being enabled.
|
|
||||||
* @param positionUs The player's current position.
|
* @param positionUs The player's current position.
|
||||||
* @param joining Whether this renderer is being enabled to join an ongoing playback.
|
* @param joining Whether this renderer is being enabled to join an ongoing playback.
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
* @throws ExoPlaybackException If an error occurs.
|
||||||
*/
|
*/
|
||||||
/* package */ final void enable(int track, long positionUs, boolean joining)
|
/* package */ final void enable(TrackStream trackStream, long positionUs, boolean joining)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
Assertions.checkState(state == STATE_PREPARED);
|
Assertions.checkState(state == STATE_IDLE);
|
||||||
state = STATE_ENABLED;
|
state = STATE_ENABLED;
|
||||||
onEnabled(track, positionUs, joining);
|
onEnabled(trackStream, positionUs, joining);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,12 +103,12 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
|
|||||||
* <p>
|
* <p>
|
||||||
* The default implementation is a no-op.
|
* The default implementation is a no-op.
|
||||||
*
|
*
|
||||||
* @param track The track for which the renderer is being enabled.
|
* @param trackStream The track stream from which the renderer should consume.
|
||||||
* @param positionUs The player's current position.
|
* @param positionUs The player's current position.
|
||||||
* @param joining Whether this renderer is being enabled to join an ongoing playback.
|
* @param joining Whether this renderer is being enabled to join an ongoing playback.
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
* @throws ExoPlaybackException If an error occurs.
|
||||||
*/
|
*/
|
||||||
protected void onEnabled(int track, long positionUs, boolean joining)
|
protected void onEnabled(TrackStream trackStream, long positionUs, boolean joining)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
@ -201,7 +165,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_PREPARED;
|
state = STATE_IDLE;
|
||||||
onDisabled();
|
onDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,28 +180,6 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unprepares the renderer.
|
|
||||||
*
|
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
|
||||||
*/
|
|
||||||
/* package */ final void unprepare() throws ExoPlaybackException {
|
|
||||||
Assertions.checkState(state == STATE_PREPARED);
|
|
||||||
state = STATE_UNPREPARED;
|
|
||||||
onUnprepared();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the renderer is unprepared.
|
|
||||||
* <p>
|
|
||||||
* The default implementation is a no-op.
|
|
||||||
*
|
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
|
||||||
*/
|
|
||||||
protected void onUnprepared() throws ExoPlaybackException {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the renderer is ready for the {@link ExoPlayer} instance to transition to
|
* Whether the renderer is ready for the {@link ExoPlayer} instance to transition to
|
||||||
* {@link ExoPlayer#STATE_ENDED}. The player will make this transition as soon as {@code true} is
|
* {@link ExoPlayer#STATE_ENDED}. The player will make this transition as soon as {@code true} is
|
||||||
|
@ -159,16 +159,6 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
|
|||||||
return getParserIndex(mediaFormat) != -1;
|
return getParserIndex(mediaFormat) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onEnabled(int track, long positionUs, boolean joining)
|
|
||||||
throws ExoPlaybackException {
|
|
||||||
super.onEnabled(track, positionUs, joining);
|
|
||||||
parserIndex = getParserIndex(getFormat(track));
|
|
||||||
parserThread = new HandlerThread("textParser");
|
|
||||||
parserThread.start();
|
|
||||||
parserHelper = new SubtitleParserHelper(parserThread.getLooper(), subtitleParsers[parserIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onReset(long positionUs) {
|
protected void onReset(long positionUs) {
|
||||||
inputStreamEnded = false;
|
inputStreamEnded = false;
|
||||||
@ -227,7 +217,15 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
|
|||||||
sampleHolder.clearData();
|
sampleHolder.clearData();
|
||||||
int result = readSource(formatHolder, sampleHolder);
|
int result = readSource(formatHolder, sampleHolder);
|
||||||
if (result == TrackStream.FORMAT_READ) {
|
if (result == TrackStream.FORMAT_READ) {
|
||||||
|
if (parserHelper == null) {
|
||||||
|
// This is the first format we've seen since the renderer was enabled.
|
||||||
|
parserIndex = getParserIndex(formatHolder.format);
|
||||||
|
parserThread = new HandlerThread("textParser");
|
||||||
|
parserThread.start();
|
||||||
|
parserHelper = new SubtitleParserHelper(parserThread.getLooper(),
|
||||||
|
subtitleParsers[parserIndex]);
|
||||||
parserHelper.setFormat(formatHolder.format);
|
parserHelper.setFormat(formatHolder.format);
|
||||||
|
}
|
||||||
} else if (result == TrackStream.SAMPLE_READ) {
|
} else if (result == TrackStream.SAMPLE_READ) {
|
||||||
parserHelper.startParseOperation();
|
parserHelper.startParseOperation();
|
||||||
} else if (result == TrackStream.END_OF_STREAM) {
|
} else if (result == TrackStream.END_OF_STREAM) {
|
||||||
|
@ -90,12 +90,6 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
|
|||||||
return eia608Parser.canParse(mediaFormat.mimeType);
|
return eia608Parser.canParse(mediaFormat.mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onEnabled(int track, long positionUs, boolean joining)
|
|
||||||
throws ExoPlaybackException {
|
|
||||||
super.onEnabled(track, positionUs, joining);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onReset(long positionUs) {
|
protected void onReset(long positionUs) {
|
||||||
inputStreamEnded = false;
|
inputStreamEnded = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user