Merge SampleSourceTrackRenderer into TrackRenderer.

TrackRenderer and SampleSourceTrackRenderer both now use a TrackStream
so they can be merged.

(This may also be useful for adding playlist support, in case TrackStreams need
to be replaced during playback.)
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=119743228
This commit is contained in:
andrewlewis 2016-04-13 07:13:38 -07:00 committed by Oliver Woodman
parent c2beffc6c5
commit e594eccd4d
11 changed files with 119 additions and 177 deletions

View file

@ -22,7 +22,6 @@ import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.MediaClock;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.audio.AudioTrack;
@ -35,8 +34,7 @@ import java.util.List;
/**
* Decodes and renders audio using the native Flac decoder.
*/
public final class LibflacAudioTrackRenderer extends SampleSourceTrackRenderer
implements MediaClock {
public final class LibflacAudioTrackRenderer extends TrackRenderer implements MediaClock {
/**
* Interface definition for a callback to be notified of {@link LibflacAudioTrackRenderer} events.

View file

@ -22,7 +22,6 @@ import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.MediaClock;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.audio.AudioTrack;
@ -35,8 +34,7 @@ import java.util.List;
/**
* Decodes and renders audio using the native Opus decoder.
*/
public final class LibopusAudioTrackRenderer extends SampleSourceTrackRenderer
implements MediaClock {
public final class LibopusAudioTrackRenderer extends TrackRenderer implements MediaClock {
/**
* Interface definition for a callback to be notified of {@link LibopusAudioTrackRenderer} events.

View file

@ -35,18 +35,13 @@ public final class DummyTrackRenderer extends TrackRenderer {
throw new IllegalStateException();
}
@Override
protected void checkForReset() throws ExoPlaybackException {
throw new IllegalStateException();
}
@Override
protected void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
throw new IllegalStateException();
}
@Override
protected void maybeThrowError() {
protected void reset(long positionUs) throws ExoPlaybackException {
throw new IllegalStateException();
}

View file

@ -102,6 +102,11 @@ import java.util.concurrent.atomic.AtomicInteger;
this.state = ExoPlayer.STATE_IDLE;
this.durationUs = C.UNKNOWN_TIME_US;
this.bufferedPositionUs = C.UNKNOWN_TIME_US;
for (int i = 0; i < renderers.length; i++) {
renderers[i].setIndex(i);
}
standaloneMediaClock = new StandaloneMediaClock();
pendingSeekCount = new AtomicInteger();
enabledRenderers = new TrackRenderer[0];

View file

@ -40,7 +40,7 @@ import java.util.List;
* An abstract {@link TrackRenderer} that uses {@link MediaCodec} to decode samples for rendering.
*/
@TargetApi(16)
public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer {
public abstract class MediaCodecTrackRenderer extends TrackRenderer {
/**
* Interface definition for a callback to be notified of {@link MediaCodecTrackRenderer} events.

View file

@ -260,9 +260,8 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
}
@Override
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs,
boolean joining) throws ExoPlaybackException {
super.onEnabled(formats, trackStream, positionUs, joining);
protected void onEnabled(Format[] formats, boolean joining) throws ExoPlaybackException {
super.onEnabled(formats, joining);
adaptiveMaxWidth = Format.NO_VALUE;
adaptiveMaxHeight = Format.NO_VALUE;
if (formats.length > 1) {

View file

@ -1,86 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer;
import com.google.android.exoplayer.util.Assertions;
import java.io.IOException;
/**
* Base class for {@link TrackRenderer} implementations that render samples obtained from a
* {@link SampleSource}.
*/
public abstract class SampleSourceTrackRenderer extends TrackRenderer {
private TrackStream trackStream;
@Override
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs,
boolean joining) throws ExoPlaybackException {
this.trackStream = Assertions.checkNotNull(trackStream);
reset(positionUs);
}
@Override
protected final void checkForReset() throws ExoPlaybackException {
long resetPositionUs = trackStream.readReset();
if (resetPositionUs != TrackStream.NO_RESET) {
reset(resetPositionUs);
return;
}
}
@Override
protected final void maybeThrowError() throws IOException {
trackStream.maybeThrowError();
}
@Override
protected void onDisabled() {
trackStream = null;
}
// Methods to be called by subclasses.
/**
* Reads from the enabled upstream source.
*
* @see TrackStream#readData(FormatHolder, DecoderInputBuffer)
*/
protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) {
return trackStream.readData(formatHolder, buffer);
}
/**
* Returns whether the upstream source is ready.
*
* @return True if the source is ready. False otherwise.
*/
protected final boolean isSourceReady() {
return trackStream.isReady();
}
// Abstract methods.
/**
* Invoked when a reset is encountered, and also when the renderer is enabled.
*
* @param positionUs The playback position in microseconds.
* @throws ExoPlaybackException If an error occurs handling the reset.
*/
protected abstract void reset(long positionUs) throws ExoPlaybackException;
}

View file

@ -161,27 +161,6 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
return ADAPTIVE_NOT_SUPPORTED;
}
/**
* Returns the extent to which the renderer supports a given format.
* <p>
* The returned value is the bitwise OR of two properties:
* <ul>
* <li>The level of support for the format itself. One of {@code}link #FORMAT_HANDLED},
* {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_SUBTYPE} and
* {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
* <li>The level of support for adapting from the format to another format of the same mimeType.
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
* </ul>
* The individual properties can be retrieved by performing a bitwise AND with
* {@link #FORMAT_SUPPORT_MASK} and {@link #ADAPTIVE_SUPPORT_MASK} respectively.
*
* @param format The format.
* @return The extent to which the renderer is capable of supporting the given format.
* @throws ExoPlaybackException If an error occurs.
*/
protected abstract int supportsFormat(Format format) throws ExoPlaybackException;
/**
* Enable the renderer to consume from the specified {@link TrackStream}.
*
@ -196,7 +175,8 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
Assertions.checkState(state == STATE_DISABLED);
state = STATE_ENABLED;
stream = trackStream;
onEnabled(formats, trackStream, positionUs, joining);
onEnabled(formats, joining);
reset(positionUs);
}
/**
@ -205,13 +185,10 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* The default implementation is a no-op.
*
* @param formats The enabled formats.
* @param trackStream The track stream from which the renderer should consume.
* @param positionUs The player's current position.
* @param joining Whether this renderer is being enabled to join an ongoing playback.
* @throws ExoPlaybackException If an error occurs.
*/
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs,
boolean joining) throws ExoPlaybackException {
protected void onEnabled(Format[] formats, boolean joining) throws ExoPlaybackException {
// Do nothing.
}
@ -238,6 +215,22 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
// Do nothing.
}
/**
* Attempts to read and process a pending reset from the {@link TrackStream}.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
*
* @throws ExoPlaybackException If an error occurs.
*/
/* package */ final void checkForReset() throws ExoPlaybackException {
long resetPositionUs = stream.readReset();
if (resetPositionUs != TrackStream.NO_RESET) {
reset(resetPositionUs);
return;
}
}
/**
* Stops the renderer.
*
@ -281,44 +274,73 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
// Do nothing.
}
/**
* 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
* returned by all of its {@link TrackRenderer}s.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
*
* @return Whether the renderer is ready for the player to transition to the ended state.
*/
protected abstract boolean isEnded();
// Methods to be called by subclasses.
/**
* Whether the renderer is able to immediately render media from the current position.
* <p>
* If the renderer is in the {@link #STATE_STARTED} state then returning true indicates that the
* renderer has everything that it needs to continue playback. Returning false indicates that
* the player should pause until the renderer is ready.
* <p>
* If the renderer is in the {@link #STATE_ENABLED} state then returning true indicates that the
* renderer is ready for playback to be started. Returning false indicates that it is not.
* Throws an error that's preventing the renderer from making progress or buffering more data at
* this point in time.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
* {@link #STATE_ENABLED}.
*
* @return True if the renderer is ready to render media. False otherwise.
* @throws IOException An error that's preventing the renderer from making progress or buffering
* more data.
*/
protected abstract boolean isReady();
protected final void maybeThrowError() throws IOException {
stream.maybeThrowError();
}
/**
* Attempts to read and process a pending reset from the {@link TrackStream}.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
* Reads from the enabled upstream source.
*
* @see TrackStream#readData(FormatHolder, DecoderInputBuffer)
*/
protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) {
return stream.readData(formatHolder, buffer);
}
/**
* Returns whether the upstream source is ready.
*
* @return True if the source is ready. False otherwise.
*/
protected final boolean isSourceReady() {
return stream.isReady();
}
// Abstract methods.
/**
* Returns the extent to which the renderer supports a given format.
* <p>
* The returned value is the bitwise OR of two properties:
* <ul>
* <li>The level of support for the format itself. One of {@code}link #FORMAT_HANDLED},
* {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_SUBTYPE} and
* {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
* <li>The level of support for adapting from the format to another format of the same mimeType.
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
* </ul>
* The individual properties can be retrieved by performing a bitwise AND with
* {@link #FORMAT_SUPPORT_MASK} and {@link #ADAPTIVE_SUPPORT_MASK} respectively.
*
* @param format The format.
* @return The extent to which the renderer is capable of supporting the given format.
* @throws ExoPlaybackException If an error occurs.
*/
protected abstract void checkForReset() throws ExoPlaybackException;
protected abstract int supportsFormat(Format format) throws ExoPlaybackException;
/**
* Invoked when a reset is encountered, and also when the renderer is enabled.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
*
* @param positionUs The playback position in microseconds.
* @throws ExoPlaybackException If an error occurs handling the reset.
*/
protected abstract void reset(long positionUs) throws ExoPlaybackException;
/**
* Incrementally renders the {@link TrackStream}.
@ -339,16 +361,35 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
throws ExoPlaybackException;
/**
* Throws an error that's preventing the renderer from making progress or buffering more data at
* this point in time.
* Whether the renderer is able to immediately render media from the current position.
* <p>
* If the renderer is in the {@link #STATE_STARTED} state then returning true indicates that the
* renderer has everything that it needs to continue playback. Returning false indicates that
* the player should pause until the renderer is ready.
* <p>
* If the renderer is in the {@link #STATE_ENABLED} state then returning true indicates that the
* renderer is ready for playback to be started. Returning false indicates that it is not.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}.
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
*
* @throws IOException An error that's preventing the renderer from making progress or buffering
* more data.
* @return True if the renderer is ready to render media. False otherwise.
*/
protected abstract void maybeThrowError() throws IOException;
protected abstract boolean isReady();
/**
* 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
* returned by all of its {@link TrackRenderer}s.
* <p>
* This method may be called when the renderer is in the following states:
* {@link #STATE_ENABLED}, {@link #STATE_STARTED}.
*
* @return Whether the renderer is ready for the player to transition to the ended state.
*/
protected abstract boolean isEnded();
// ExoPlayerComponent implementation.
@Override
public void handleMessage(int what, Object object) throws ExoPlaybackException {

View file

@ -19,7 +19,6 @@ import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.util.Assertions;
@ -36,7 +35,7 @@ import java.io.IOException;
*
* @param <T> The type of the metadata.
*/
public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer implements Callback {
public final class MetadataTrackRenderer<T> extends TrackRenderer implements Callback {
/**
* An interface for components that process metadata.

View file

@ -20,7 +20,6 @@ import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.util.Assertions;
@ -44,7 +43,7 @@ import java.util.List;
* {@link TextRenderer}.
*/
@TargetApi(16)
public final class TextTrackRenderer extends SampleSourceTrackRenderer implements Callback {
public final class TextTrackRenderer extends TrackRenderer implements Callback {
private static final int MSG_UPDATE_OVERLAY = 0;
@ -99,9 +98,8 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
}
@Override
protected void onEnabled(Format[] formats, TrackStream trackStream, long positionUs,
boolean joining) throws ExoPlaybackException {
super.onEnabled(formats, trackStream, positionUs, joining);
protected void onEnabled(Format[] formats, boolean joining) throws ExoPlaybackException {
super.onEnabled(formats, joining);
parser = parserFactory.createParser(formats[0]);
parser.start();
}
@ -120,9 +118,7 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
}
nextInputBuffer = null;
clearTextRenderer();
if (parser != null) {
parser.flush();
}
parser.flush();
}
@Override
@ -215,10 +211,8 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
nextSubtitle.release();
nextSubtitle = null;
}
if (parser != null) {
parser.release();
parser = null;
}
parser.release();
parser = null;
nextInputBuffer = null;
clearTextRenderer();
super.onDisabled();

View file

@ -20,7 +20,6 @@ import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream;
import com.google.android.exoplayer.text.Cue;
@ -39,7 +38,7 @@ import java.util.TreeSet;
/**
* A {@link TrackRenderer} for EIA-608 closed captions in a media stream.
*/
public final class Eia608TrackRenderer extends SampleSourceTrackRenderer implements Callback {
public final class Eia608TrackRenderer extends TrackRenderer implements Callback {
private static final int MSG_INVOKE_RENDERER = 0;