Commit 9558a4cb by olly Committed by Oliver Woodman

Rename TrackRenderer -> Renderer

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127065122
parent 8e0354c0
Showing with 537 additions and 567 deletions
...@@ -22,10 +22,10 @@ import com.google.android.exoplayer2.DefaultTrackSelector.TrackInfo; ...@@ -22,10 +22,10 @@ import com.google.android.exoplayer2.DefaultTrackSelector.TrackInfo;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.TrackGroup; import com.google.android.exoplayer2.TrackGroup;
import com.google.android.exoplayer2.TrackGroupArray; import com.google.android.exoplayer2.TrackGroupArray;
import com.google.android.exoplayer2.TrackRenderer;
import com.google.android.exoplayer2.TrackSelection; import com.google.android.exoplayer2.TrackSelection;
import com.google.android.exoplayer2.drm.StreamingDrmSessionManager; import com.google.android.exoplayer2.drm.StreamingDrmSessionManager;
import com.google.android.exoplayer2.extractor.ExtractorMediaSource; import com.google.android.exoplayer2.extractor.ExtractorMediaSource;
...@@ -130,7 +130,7 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb ...@@ -130,7 +130,7 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb
TrackGroup trackGroup = trackGroups.get(groupIndex); TrackGroup trackGroup = trackGroups.get(groupIndex);
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
String status = getTrackStatusString(false); String status = getTrackStatusString(false);
String formatSupport = getFormatSupportString(TrackRenderer.FORMAT_UNSUPPORTED_TYPE); String formatSupport = getFormatSupportString(Renderer.FORMAT_UNSUPPORTED_TYPE);
Log.d(TAG, " " + status + " Track:" + trackIndex + ", " Log.d(TAG, " " + status + " Track:" + trackIndex + ", "
+ getFormatString(trackGroup.getFormat(trackIndex)) + getFormatString(trackGroup.getFormat(trackIndex))
+ ", supported=" + formatSupport); + ", supported=" + formatSupport);
...@@ -291,13 +291,13 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb ...@@ -291,13 +291,13 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb
private static String getFormatSupportString(int formatSupport) { private static String getFormatSupportString(int formatSupport) {
switch (formatSupport) { switch (formatSupport) {
case TrackRenderer.FORMAT_HANDLED: case Renderer.FORMAT_HANDLED:
return "YES"; return "YES";
case TrackRenderer.FORMAT_EXCEEDS_CAPABILITIES: case Renderer.FORMAT_EXCEEDS_CAPABILITIES:
return "NO_EXCEEDS_CAPABILITIES"; return "NO_EXCEEDS_CAPABILITIES";
case TrackRenderer.FORMAT_UNSUPPORTED_SUBTYPE: case Renderer.FORMAT_UNSUPPORTED_SUBTYPE:
return "NO_UNSUPPORTED_TYPE"; return "NO_UNSUPPORTED_TYPE";
case TrackRenderer.FORMAT_UNSUPPORTED_TYPE: case Renderer.FORMAT_UNSUPPORTED_TYPE:
return "NO"; return "NO";
default: default:
return "?"; return "?";
...@@ -309,11 +309,11 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb ...@@ -309,11 +309,11 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb
return "N/A"; return "N/A";
} }
switch (adaptiveSupport) { switch (adaptiveSupport) {
case TrackRenderer.ADAPTIVE_SEAMLESS: case Renderer.ADAPTIVE_SEAMLESS:
return "YES"; return "YES";
case TrackRenderer.ADAPTIVE_NOT_SEAMLESS: case Renderer.ADAPTIVE_NOT_SEAMLESS:
return "YES_NOT_SEAMLESS"; return "YES_NOT_SEAMLESS";
case TrackRenderer.ADAPTIVE_NOT_SUPPORTED: case Renderer.ADAPTIVE_NOT_SUPPORTED:
return "NO"; return "NO";
default: default:
return "?"; return "?";
......
...@@ -25,7 +25,7 @@ import com.google.android.exoplayer2.DefaultTrackSelector.TrackInfo; ...@@ -25,7 +25,7 @@ import com.google.android.exoplayer2.DefaultTrackSelector.TrackInfo;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.MediaCodecTrackRenderer.DecoderInitializationException; import com.google.android.exoplayer2.MediaCodecRenderer.DecoderInitializationException;
import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.MediaSource; import com.google.android.exoplayer2.MediaSource;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
......
...@@ -18,9 +18,9 @@ package com.google.android.exoplayer2.demo; ...@@ -18,9 +18,9 @@ package com.google.android.exoplayer2.demo;
import com.google.android.exoplayer2.DefaultTrackSelector; import com.google.android.exoplayer2.DefaultTrackSelector;
import com.google.android.exoplayer2.DefaultTrackSelector.TrackInfo; import com.google.android.exoplayer2.DefaultTrackSelector.TrackInfo;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.TrackGroup; import com.google.android.exoplayer2.TrackGroup;
import com.google.android.exoplayer2.TrackGroupArray; import com.google.android.exoplayer2.TrackGroupArray;
import com.google.android.exoplayer2.TrackRenderer;
import com.google.android.exoplayer2.TrackSelection; import com.google.android.exoplayer2.TrackSelection;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
...@@ -45,7 +45,7 @@ import java.util.Locale; ...@@ -45,7 +45,7 @@ import java.util.Locale;
DialogInterface.OnClickListener { DialogInterface.OnClickListener {
private final DefaultTrackSelector selector; private final DefaultTrackSelector selector;
private TrackInfo trackInfo; private TrackInfo trackInfo;
private int rendererIndex; private int rendererIndex;
private TrackGroupArray trackGroups; private TrackGroupArray trackGroups;
...@@ -81,7 +81,7 @@ import java.util.Locale; ...@@ -81,7 +81,7 @@ import java.util.Locale;
trackGroupsAdaptive = new boolean[trackGroups.length]; trackGroupsAdaptive = new boolean[trackGroups.length];
for (int i = 0; i < trackGroups.length; i++) { for (int i = 0; i < trackGroups.length; i++) {
trackGroupsAdaptive[i] = trackInfo.getAdaptiveSupport(rendererIndex, i, false) trackGroupsAdaptive[i] = trackInfo.getAdaptiveSupport(rendererIndex, i, false)
!= TrackRenderer.ADAPTIVE_NOT_SUPPORTED; != Renderer.ADAPTIVE_NOT_SUPPORTED;
} }
isDisabled = selector.getRendererDisabled(rendererIndex); isDisabled = selector.getRendererDisabled(rendererIndex);
override = selector.hasSelectionOverride(rendererIndex, trackGroups) override = selector.hasSelectionOverride(rendererIndex, trackGroups)
...@@ -133,7 +133,7 @@ import java.util.Locale; ...@@ -133,7 +133,7 @@ import java.util.Locale;
trackViewLayoutId, root, false); trackViewLayoutId, root, false);
trackView.setText(buildTrackName(group.getFormat(trackIndex))); trackView.setText(buildTrackName(group.getFormat(trackIndex)));
if (trackInfo.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex) if (trackInfo.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex)
== TrackRenderer.FORMAT_HANDLED) { == Renderer.FORMAT_HANDLED) {
haveSupportedTracks = true; haveSupportedTracks = true;
trackView.setTag(Pair.create(groupIndex, trackIndex)); trackView.setTag(Pair.create(groupIndex, trackIndex));
trackView.setOnClickListener(this); trackView.setOnClickListener(this);
......
# FfmpegAudioTrackRenderer # # FfmpegAudioRenderer #
## Description ## ## Description ##
The FFmpeg extension is a [TrackRenderer][] implementation that uses FFmpeg to The FFmpeg extension is a [Renderer][] implementation that uses FFmpeg to decode
decode audio. audio.
[TrackRenderer]: https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/TrackRenderer.html [Renderer]: https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/Renderer.html
## Build instructions ## ## Build instructions ##
......
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
*/ */
package com.google.android.exoplayer2.ext.ffmpeg; package com.google.android.exoplayer2.ext.ffmpeg;
import com.google.android.exoplayer2.AudioTrackRendererEventListener; import com.google.android.exoplayer2.AudioRendererEventListener;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.AudioCapabilities; import com.google.android.exoplayer2.audio.AudioCapabilities;
import com.google.android.exoplayer2.audio.AudioTrack; import com.google.android.exoplayer2.audio.AudioTrack;
import com.google.android.exoplayer2.extensions.AudioDecoderTrackRenderer; import com.google.android.exoplayer2.extensions.AudioDecoderRenderer;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import android.os.Handler; import android.os.Handler;
...@@ -28,14 +28,14 @@ import android.os.Handler; ...@@ -28,14 +28,14 @@ import android.os.Handler;
/** /**
* Decodes and renders audio using FFmpeg. * Decodes and renders audio using FFmpeg.
*/ */
public final class FfmpegAudioTrackRenderer extends AudioDecoderTrackRenderer { public final class FfmpegAudioRenderer extends AudioDecoderRenderer {
private static final int NUM_BUFFERS = 16; private static final int NUM_BUFFERS = 16;
private static final int INITIAL_INPUT_BUFFER_SIZE = 960 * 6; private static final int INITIAL_INPUT_BUFFER_SIZE = 960 * 6;
private FfmpegDecoder decoder; private FfmpegDecoder decoder;
public FfmpegAudioTrackRenderer() { public FfmpegAudioRenderer() {
this(null, null); this(null, null);
} }
...@@ -44,8 +44,7 @@ public final class FfmpegAudioTrackRenderer extends AudioDecoderTrackRenderer { ...@@ -44,8 +44,7 @@ public final class FfmpegAudioTrackRenderer extends AudioDecoderTrackRenderer {
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
*/ */
public FfmpegAudioTrackRenderer(Handler eventHandler, public FfmpegAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener) {
AudioTrackRendererEventListener eventListener) {
super(eventHandler, eventListener); super(eventHandler, eventListener);
} }
...@@ -57,9 +56,8 @@ public final class FfmpegAudioTrackRenderer extends AudioDecoderTrackRenderer { ...@@ -57,9 +56,8 @@ public final class FfmpegAudioTrackRenderer extends AudioDecoderTrackRenderer {
* default capabilities (no encoded audio passthrough support) should be assumed. * default capabilities (no encoded audio passthrough support) should be assumed.
* @param streamType The type of audio stream for the {@link AudioTrack}. * @param streamType The type of audio stream for the {@link AudioTrack}.
*/ */
public FfmpegAudioTrackRenderer(Handler eventHandler, public FfmpegAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener,
AudioTrackRendererEventListener eventListener, AudioCapabilities audioCapabilities, AudioCapabilities audioCapabilities, int streamType) {
int streamType) {
super(eventHandler, eventListener, audioCapabilities, streamType); super(eventHandler, eventListener, audioCapabilities, streamType);
} }
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
## Description ## ## Description ##
The Flac Extension is a [TrackRenderer][] implementation that helps you bundle The Flac Extension is a [Renderer][] implementation that helps you bundle
libFLAC (the Flac decoding library) into your app and use it along with libFLAC (the Flac decoding library) into your app and use it along with
ExoPlayer to play Flac audio on Android devices. ExoPlayer to play Flac audio on Android devices.
[TrackRenderer]: https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/TrackRenderer.html [Renderer]: https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/Renderer.html
## Build Instructions ## ## Build Instructions ##
......
...@@ -20,7 +20,7 @@ import com.google.android.exoplayer2.DefaultTrackSelector; ...@@ -20,7 +20,7 @@ import com.google.android.exoplayer2.DefaultTrackSelector;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.TrackRenderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.extractor.ExtractorMediaSource; import com.google.android.exoplayer2.extractor.ExtractorMediaSource;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
...@@ -31,7 +31,7 @@ import android.os.Looper; ...@@ -31,7 +31,7 @@ import android.os.Looper;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
/** /**
* Playback tests using {@link LibflacAudioTrackRenderer}. * Playback tests using {@link LibflacAudioRenderer}.
*/ */
public class FlacPlaybackTest extends InstrumentationTestCase { public class FlacPlaybackTest extends InstrumentationTestCase {
...@@ -71,10 +71,10 @@ public class FlacPlaybackTest extends InstrumentationTestCase { ...@@ -71,10 +71,10 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
@Override @Override
public void run() { public void run() {
Looper.prepare(); Looper.prepare();
LibflacAudioTrackRenderer audioRenderer = new LibflacAudioTrackRenderer(); LibflacAudioRenderer audioRenderer = new LibflacAudioRenderer();
DefaultTrackSelector trackSelector = new DefaultTrackSelector( DefaultTrackSelector trackSelector = new DefaultTrackSelector(
new DefaultTrackSelectionPolicy(), null); new DefaultTrackSelectionPolicy(), null);
player = ExoPlayerFactory.newInstance(new TrackRenderer[] {audioRenderer}, trackSelector); player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
player.addListener(this); player.addListener(this);
ExtractorMediaSource mediaSource = new ExtractorMediaSource( ExtractorMediaSource mediaSource = new ExtractorMediaSource(
uri, uri,
......
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
*/ */
package com.google.android.exoplayer2.ext.flac; package com.google.android.exoplayer2.ext.flac;
import com.google.android.exoplayer2.AudioTrackRendererEventListener; import com.google.android.exoplayer2.AudioRendererEventListener;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.AudioCapabilities; import com.google.android.exoplayer2.audio.AudioCapabilities;
import com.google.android.exoplayer2.audio.AudioTrack; import com.google.android.exoplayer2.audio.AudioTrack;
import com.google.android.exoplayer2.extensions.AudioDecoderTrackRenderer; import com.google.android.exoplayer2.extensions.AudioDecoderRenderer;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import android.os.Handler; import android.os.Handler;
...@@ -27,7 +27,7 @@ import android.os.Handler; ...@@ -27,7 +27,7 @@ import android.os.Handler;
/** /**
* Decodes and renders audio using the native Flac decoder. * Decodes and renders audio using the native Flac decoder.
*/ */
public class LibflacAudioTrackRenderer extends AudioDecoderTrackRenderer { public class LibflacAudioRenderer extends AudioDecoderRenderer {
private static final int NUM_BUFFERS = 16; private static final int NUM_BUFFERS = 16;
...@@ -38,7 +38,7 @@ public class LibflacAudioTrackRenderer extends AudioDecoderTrackRenderer { ...@@ -38,7 +38,7 @@ public class LibflacAudioTrackRenderer extends AudioDecoderTrackRenderer {
return FlacJni.IS_AVAILABLE; return FlacJni.IS_AVAILABLE;
} }
public LibflacAudioTrackRenderer() { public LibflacAudioRenderer() {
this(null, null); this(null, null);
} }
...@@ -47,8 +47,7 @@ public class LibflacAudioTrackRenderer extends AudioDecoderTrackRenderer { ...@@ -47,8 +47,7 @@ public class LibflacAudioTrackRenderer extends AudioDecoderTrackRenderer {
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
*/ */
public LibflacAudioTrackRenderer(Handler eventHandler, public LibflacAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener) {
AudioTrackRendererEventListener eventListener) {
super(eventHandler, eventListener); super(eventHandler, eventListener);
} }
...@@ -60,9 +59,8 @@ public class LibflacAudioTrackRenderer extends AudioDecoderTrackRenderer { ...@@ -60,9 +59,8 @@ public class LibflacAudioTrackRenderer extends AudioDecoderTrackRenderer {
* default capabilities (no encoded audio passthrough support) should be assumed. * default capabilities (no encoded audio passthrough support) should be assumed.
* @param streamType The type of audio stream for the {@link AudioTrack}. * @param streamType The type of audio stream for the {@link AudioTrack}.
*/ */
public LibflacAudioTrackRenderer(Handler eventHandler, public LibflacAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener,
AudioTrackRendererEventListener eventListener, AudioCapabilities audioCapabilities, AudioCapabilities audioCapabilities, int streamType) {
int streamType) {
super(eventHandler, eventListener, audioCapabilities, streamType); super(eventHandler, eventListener, audioCapabilities, streamType);
} }
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
## Description ## ## Description ##
The Opus Extension is a [TrackRenderer][] implementation that helps you bundle The Opus Extension is a [Renderer][] implementation that helps you bundle
libopus (the Opus decoding library) into your app and use it along with libopus (the Opus decoding library) into your app and use it along with
ExoPlayer to play Opus audio on Android devices. ExoPlayer to play Opus audio on Android devices.
[TrackRenderer]: https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/TrackRenderer.html [Renderer]: https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/Renderer.html
## Build Instructions ## ## Build Instructions ##
......
...@@ -20,7 +20,7 @@ import com.google.android.exoplayer2.DefaultTrackSelector; ...@@ -20,7 +20,7 @@ import com.google.android.exoplayer2.DefaultTrackSelector;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.TrackRenderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.extractor.ExtractorMediaSource; import com.google.android.exoplayer2.extractor.ExtractorMediaSource;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
...@@ -31,7 +31,7 @@ import android.os.Looper; ...@@ -31,7 +31,7 @@ import android.os.Looper;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
/** /**
* Playback tests using {@link LibopusAudioTrackRenderer}. * Playback tests using {@link LibopusAudioRenderer}.
*/ */
public class OpusPlaybackTest extends InstrumentationTestCase { public class OpusPlaybackTest extends InstrumentationTestCase {
...@@ -71,10 +71,10 @@ public class OpusPlaybackTest extends InstrumentationTestCase { ...@@ -71,10 +71,10 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
@Override @Override
public void run() { public void run() {
Looper.prepare(); Looper.prepare();
LibopusAudioTrackRenderer audioRenderer = new LibopusAudioTrackRenderer(); LibopusAudioRenderer audioRenderer = new LibopusAudioRenderer();
DefaultTrackSelector trackSelector = new DefaultTrackSelector( DefaultTrackSelector trackSelector = new DefaultTrackSelector(
new DefaultTrackSelectionPolicy(), null); new DefaultTrackSelectionPolicy(), null);
player = ExoPlayerFactory.newInstance(new TrackRenderer[] {audioRenderer}, trackSelector); player = ExoPlayerFactory.newInstance(new Renderer[] {audioRenderer}, trackSelector);
player.addListener(this); player.addListener(this);
ExtractorMediaSource mediaSource = new ExtractorMediaSource( ExtractorMediaSource mediaSource = new ExtractorMediaSource(
uri, uri,
......
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
*/ */
package com.google.android.exoplayer2.ext.opus; package com.google.android.exoplayer2.ext.opus;
import com.google.android.exoplayer2.AudioTrackRendererEventListener; import com.google.android.exoplayer2.AudioRendererEventListener;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.AudioCapabilities; import com.google.android.exoplayer2.audio.AudioCapabilities;
import com.google.android.exoplayer2.audio.AudioTrack; import com.google.android.exoplayer2.audio.AudioTrack;
import com.google.android.exoplayer2.extensions.AudioDecoderTrackRenderer; import com.google.android.exoplayer2.extensions.AudioDecoderRenderer;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import android.os.Handler; import android.os.Handler;
...@@ -27,7 +27,7 @@ import android.os.Handler; ...@@ -27,7 +27,7 @@ import android.os.Handler;
/** /**
* Decodes and renders audio using the native Opus decoder. * Decodes and renders audio using the native Opus decoder.
*/ */
public final class LibopusAudioTrackRenderer extends AudioDecoderTrackRenderer { public final class LibopusAudioRenderer extends AudioDecoderRenderer {
private static final int NUM_BUFFERS = 16; private static final int NUM_BUFFERS = 16;
private static final int INITIAL_INPUT_BUFFER_SIZE = 960 * 6; private static final int INITIAL_INPUT_BUFFER_SIZE = 960 * 6;
...@@ -46,7 +46,7 @@ public final class LibopusAudioTrackRenderer extends AudioDecoderTrackRenderer { ...@@ -46,7 +46,7 @@ public final class LibopusAudioTrackRenderer extends AudioDecoderTrackRenderer {
return isLibopusAvailable() ? OpusDecoder.getLibopusVersion() : null; return isLibopusAvailable() ? OpusDecoder.getLibopusVersion() : null;
} }
public LibopusAudioTrackRenderer() { public LibopusAudioRenderer() {
this(null, null); this(null, null);
} }
...@@ -55,8 +55,7 @@ public final class LibopusAudioTrackRenderer extends AudioDecoderTrackRenderer { ...@@ -55,8 +55,7 @@ public final class LibopusAudioTrackRenderer extends AudioDecoderTrackRenderer {
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
*/ */
public LibopusAudioTrackRenderer(Handler eventHandler, public LibopusAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener) {
AudioTrackRendererEventListener eventListener) {
super(eventHandler, eventListener); super(eventHandler, eventListener);
} }
...@@ -68,9 +67,8 @@ public final class LibopusAudioTrackRenderer extends AudioDecoderTrackRenderer { ...@@ -68,9 +67,8 @@ public final class LibopusAudioTrackRenderer extends AudioDecoderTrackRenderer {
* default capabilities (no encoded audio passthrough support) should be assumed. * default capabilities (no encoded audio passthrough support) should be assumed.
* @param streamType The type of audio stream for the {@link AudioTrack}. * @param streamType The type of audio stream for the {@link AudioTrack}.
*/ */
public LibopusAudioTrackRenderer(Handler eventHandler, public LibopusAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener,
AudioTrackRendererEventListener eventListener, AudioCapabilities audioCapabilities, AudioCapabilities audioCapabilities, int streamType) {
int streamType) {
super(eventHandler, eventListener, audioCapabilities, streamType); super(eventHandler, eventListener, audioCapabilities, streamType);
} }
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
## Description ## ## Description ##
The VP9 Extension is a [TrackRenderer][] implementation that helps you bundle The VP9 Extension is a [Renderer][] implementation that helps you bundle libvpx
libvpx (the VP9 decoding library) into your app and use it along with ExoPlayer (the VP9 decoding library) into your app and use it along with ExoPlayer to play
to play VP9 video on Android devices. VP9 video on Android devices.
[TrackRenderer]: https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/TrackRenderer.html [Renderer]: https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/Renderer.html
## Build Instructions ## ## Build Instructions ##
......
...@@ -20,7 +20,7 @@ import com.google.android.exoplayer2.DefaultTrackSelector; ...@@ -20,7 +20,7 @@ import com.google.android.exoplayer2.DefaultTrackSelector;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.TrackRenderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.extractor.ExtractorMediaSource; import com.google.android.exoplayer2.extractor.ExtractorMediaSource;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
...@@ -31,7 +31,7 @@ import android.os.Looper; ...@@ -31,7 +31,7 @@ import android.os.Looper;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
/** /**
* Playback tests using {@link LibvpxVideoTrackRenderer}. * Playback tests using {@link LibvpxVideoRenderer}.
*/ */
public class VpxPlaybackTest extends InstrumentationTestCase { public class VpxPlaybackTest extends InstrumentationTestCase {
...@@ -87,10 +87,10 @@ public class VpxPlaybackTest extends InstrumentationTestCase { ...@@ -87,10 +87,10 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
@Override @Override
public void run() { public void run() {
Looper.prepare(); Looper.prepare();
LibvpxVideoTrackRenderer videoRenderer = new LibvpxVideoTrackRenderer(true, 0); LibvpxVideoRenderer videoRenderer = new LibvpxVideoRenderer(true, 0);
DefaultTrackSelector trackSelector = new DefaultTrackSelector( DefaultTrackSelector trackSelector = new DefaultTrackSelector(
new DefaultTrackSelectionPolicy(), null); new DefaultTrackSelectionPolicy(), null);
player = ExoPlayerFactory.newInstance(new TrackRenderer[] {videoRenderer}, trackSelector); player = ExoPlayerFactory.newInstance(new Renderer[] {videoRenderer}, trackSelector);
player.addListener(this); player.addListener(this);
ExtractorMediaSource mediaSource = new ExtractorMediaSource( ExtractorMediaSource mediaSource = new ExtractorMediaSource(
uri, uri,
...@@ -100,7 +100,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase { ...@@ -100,7 +100,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
null, null,
null); null);
player.sendMessages(new ExoPlayer.ExoPlayerMessage(videoRenderer, player.sendMessages(new ExoPlayer.ExoPlayerMessage(videoRenderer,
LibvpxVideoTrackRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER, LibvpxVideoRenderer.MSG_SET_OUTPUT_BUFFER_RENDERER,
new VpxVideoSurfaceView(context))); new VpxVideoSurfaceView(context)));
player.setMediaSource(mediaSource); player.setMediaSource(mediaSource);
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
......
...@@ -22,10 +22,10 @@ import com.google.android.exoplayer2.ExoPlaybackException; ...@@ -22,10 +22,10 @@ import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.TrackRenderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.TrackStream; import com.google.android.exoplayer2.TrackStream;
import com.google.android.exoplayer2.VideoTrackRendererEventListener; import com.google.android.exoplayer2.VideoRendererEventListener;
import com.google.android.exoplayer2.VideoTrackRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.VideoRendererEventListener.EventDispatcher;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.TraceUtil;
...@@ -38,7 +38,7 @@ import android.view.Surface; ...@@ -38,7 +38,7 @@ import android.view.Surface;
/** /**
* Decodes and renders video using the native VP9 decoder. * Decodes and renders video using the native VP9 decoder.
*/ */
public final class LibvpxVideoTrackRenderer extends TrackRenderer { public final class LibvpxVideoRenderer extends Renderer {
/** /**
* The type of a message that can be passed to an instance of this class via * The type of a message that can be passed to an instance of this class via
...@@ -48,7 +48,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer { ...@@ -48,7 +48,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
public static final int MSG_SET_OUTPUT_BUFFER_RENDERER = C.MSG_CUSTOM_BASE; public static final int MSG_SET_OUTPUT_BUFFER_RENDERER = C.MSG_CUSTOM_BASE;
/** /**
* The number of input buffers and the number of output buffers. The track renderer may limit the * The number of input buffers and the number of output buffers. The renderer may limit the
* minimum possible value due to requiring multiple output buffers to be dequeued at a time for it * minimum possible value due to requiring multiple output buffers to be dequeued at a time for it
* to make progress. * to make progress.
*/ */
...@@ -90,7 +90,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer { ...@@ -90,7 +90,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer * @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* can attempt to seamlessly join an ongoing playback. * can attempt to seamlessly join an ongoing playback.
*/ */
public LibvpxVideoTrackRenderer(boolean scaleToFit, long allowedJoiningTimeMs) { public LibvpxVideoRenderer(boolean scaleToFit, long allowedJoiningTimeMs) {
this(scaleToFit, allowedJoiningTimeMs, null, null, 0); this(scaleToFit, allowedJoiningTimeMs, null, null, 0);
} }
...@@ -102,10 +102,10 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer { ...@@ -102,10 +102,10 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
* @param maxDroppedFrameCountToNotify The maximum number of frames that can be dropped between * @param maxDroppedFrameCountToNotify The maximum number of frames that can be dropped between
* invocations of {@link VideoTrackRendererEventListener#onDroppedFrames(int, long)}. * invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
*/ */
public LibvpxVideoTrackRenderer(boolean scaleToFit, long allowedJoiningTimeMs, public LibvpxVideoRenderer(boolean scaleToFit, long allowedJoiningTimeMs,
Handler eventHandler, VideoTrackRendererEventListener eventListener, Handler eventHandler, VideoRendererEventListener eventListener,
int maxDroppedFrameCountToNotify) { int maxDroppedFrameCountToNotify) {
this.scaleToFit = scaleToFit; this.scaleToFit = scaleToFit;
this.allowedJoiningTimeMs = allowedJoiningTimeMs; this.allowedJoiningTimeMs = allowedJoiningTimeMs;
...@@ -234,7 +234,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer { ...@@ -234,7 +234,7 @@ public final class LibvpxVideoTrackRenderer extends TrackRenderer {
return false; return false;
} }
if (getState() == TrackRenderer.STATE_STARTED if (getState() == Renderer.STATE_STARTED
&& outputBuffer.timestampUs <= positionUs + 30000) { && outputBuffer.timestampUs <= positionUs + 30000) {
renderBuffer(); renderBuffer();
} }
......
...@@ -22,9 +22,9 @@ import android.os.Handler; ...@@ -22,9 +22,9 @@ import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
/** /**
* Interface definition for a callback to be notified of audio {@link TrackRenderer} events. * Interface definition for a callback to be notified of audio {@link Renderer} events.
*/ */
public interface AudioTrackRendererEventListener { public interface AudioRendererEventListener {
/** /**
* Invoked when the renderer is enabled. * Invoked when the renderer is enabled.
...@@ -71,14 +71,14 @@ public interface AudioTrackRendererEventListener { ...@@ -71,14 +71,14 @@ public interface AudioTrackRendererEventListener {
void onAudioDisabled(CodecCounters counters); void onAudioDisabled(CodecCounters counters);
/** /**
* Dispatches events to a {@link AudioTrackRendererEventListener}. * Dispatches events to a {@link AudioRendererEventListener}.
*/ */
final class EventDispatcher { final class EventDispatcher {
private final Handler handler; private final Handler handler;
private final AudioTrackRendererEventListener listener; private final AudioRendererEventListener listener;
public EventDispatcher(Handler handler, AudioTrackRendererEventListener listener) { public EventDispatcher(Handler handler, AudioRendererEventListener listener) {
this.handler = listener != null ? Assertions.checkNotNull(handler) : null; this.handler = listener != null ? Assertions.checkNotNull(handler) : null;
this.listener = listener; this.listener = listener;
} }
......
...@@ -271,21 +271,21 @@ public interface C { ...@@ -271,21 +271,21 @@ public interface C {
UUID PLAYREADY_UUID = new UUID(0x9A04F07998404286L, 0xAB92E65BE0885F95L); UUID PLAYREADY_UUID = new UUID(0x9A04F07998404286L, 0xAB92E65BE0885F95L);
/** /**
* The type of a message that can be passed to a video {@link TrackRenderer} via * The type of a message that can be passed to a video {@link Renderer} via
* {@link ExoPlayer#sendMessages} or {@link ExoPlayer#blockingSendMessages}. The message object * {@link ExoPlayer#sendMessages} or {@link ExoPlayer#blockingSendMessages}. The message object
* should be the target {@link Surface}, or null. * should be the target {@link Surface}, or null.
*/ */
int MSG_SET_SURFACE = 1; int MSG_SET_SURFACE = 1;
/** /**
* The type of a message that can be passed to an audio {@link TrackRenderer} via * The type of a message that can be passed to an audio {@link Renderer} via
* {@link ExoPlayer#sendMessages} or {@link ExoPlayer#blockingSendMessages}. The message object * {@link ExoPlayer#sendMessages} or {@link ExoPlayer#blockingSendMessages}. The message object
* should be a {@link Float} with 0 being silence and 1 being unity gain. * should be a {@link Float} with 0 being silence and 1 being unity gain.
*/ */
int MSG_SET_VOLUME = 2; int MSG_SET_VOLUME = 2;
/** /**
* The type of a message that can be passed to an audio {@link TrackRenderer} via * The type of a message that can be passed to an audio {@link Renderer} via
* {@link ExoPlayer#sendMessages} or {@link ExoPlayer#blockingSendMessages}. The message object * {@link ExoPlayer#sendMessages} or {@link ExoPlayer#blockingSendMessages}. The message object
* should be a {@link android.media.PlaybackParams}, which will be used to configure the * should be a {@link android.media.PlaybackParams}, which will be used to configure the
* underlying {@link android.media.AudioTrack}. The message object should not be modified by the * underlying {@link android.media.AudioTrack}. The message object should not be modified by the
......
...@@ -103,7 +103,7 @@ public final class DefaultLoadControl implements LoadControl { ...@@ -103,7 +103,7 @@ public final class DefaultLoadControl implements LoadControl {
} }
@Override @Override
public void onTrackSelections(TrackRenderer[] renderers, TrackGroupArray trackGroups, public void onTrackSelections(Renderer[] renderers, TrackGroupArray trackGroups,
TrackSelectionArray trackSelections) { TrackSelectionArray trackSelections) {
targetBufferSize = 0; targetBufferSize = 0;
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
......
...@@ -122,7 +122,7 @@ public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy { ...@@ -122,7 +122,7 @@ public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy {
// TrackSelectionPolicy implementation. // TrackSelectionPolicy implementation.
@Override @Override
public TrackSelection[] selectTracks(TrackRenderer[] renderers, public TrackSelection[] selectTracks(Renderer[] renderers,
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports) TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports)
throws ExoPlaybackException { throws ExoPlaybackException {
// Make a track selection for each renderer. // Make a track selection for each renderer.
...@@ -157,13 +157,13 @@ public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy { ...@@ -157,13 +157,13 @@ public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy {
// Video track selection implementation. // Video track selection implementation.
private static TrackSelection selectTrackForVideoRenderer(TrackRenderer renderer, private static TrackSelection selectTrackForVideoRenderer(Renderer renderer,
TrackGroupArray trackGroups, int[][] formatSupport, int maxVideoWidth, int maxVideoHeight, TrackGroupArray trackGroups, int[][] formatSupport, int maxVideoWidth, int maxVideoHeight,
boolean allowNonSeamlessAdaptiveness, boolean allowMixedMimeAdaptiveness) boolean allowNonSeamlessAdaptiveness, boolean allowMixedMimeAdaptiveness)
throws ExoPlaybackException { throws ExoPlaybackException {
int requiredAdaptiveSupport = allowNonSeamlessAdaptiveness int requiredAdaptiveSupport = allowNonSeamlessAdaptiveness
? TrackRenderer.ADAPTIVE_NOT_SEAMLESS | TrackRenderer.ADAPTIVE_SEAMLESS ? (Renderer.ADAPTIVE_NOT_SEAMLESS | Renderer.ADAPTIVE_SEAMLESS)
: TrackRenderer.ADAPTIVE_SEAMLESS; : Renderer.ADAPTIVE_SEAMLESS;
boolean allowMixedMimeTypes = allowMixedMimeAdaptiveness boolean allowMixedMimeTypes = allowMixedMimeAdaptiveness
&& (renderer.supportsMixedMimeTypeAdaptation() & requiredAdaptiveSupport) != 0; && (renderer.supportsMixedMimeTypeAdaptation() & requiredAdaptiveSupport) != 0;
int largestAdaptiveGroup = -1; int largestAdaptiveGroup = -1;
...@@ -347,7 +347,7 @@ public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy { ...@@ -347,7 +347,7 @@ public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy {
} }
private static boolean isSupported(int formatSupport) { private static boolean isSupported(int formatSupport) {
return (formatSupport & TrackRenderer.FORMAT_SUPPORT_MASK) == TrackRenderer.FORMAT_HANDLED; return (formatSupport & Renderer.FORMAT_SUPPORT_MASK) == Renderer.FORMAT_HANDLED;
} }
private static boolean formatHasLanguage(Format format, String language) { private static boolean formatHasLanguage(Format format, String language) {
......
...@@ -31,7 +31,7 @@ public final class ExoPlaybackException extends Exception { ...@@ -31,7 +31,7 @@ public final class ExoPlaybackException extends Exception {
*/ */
public static final int TYPE_SOURCE = 0; public static final int TYPE_SOURCE = 0;
/** /**
* The error occurred in a {@link TrackRenderer}. * The error occurred in a {@link Renderer}.
* <p> * <p>
* Call {@link #getRendererException()} to retrieve the underlying cause. * Call {@link #getRendererException()} to retrieve the underlying cause.
*/ */
......
...@@ -32,11 +32,11 @@ package com.google.android.exoplayer2; ...@@ -32,11 +32,11 @@ package com.google.android.exoplayer2;
* <p>The implementation is designed to make no assumptions about (and hence impose no restrictions * <p>The implementation is designed to make no assumptions about (and hence impose no restrictions
* on) the type of the media being played, how and where it is stored, or how it is rendered. * on) the type of the media being played, how and where it is stored, or how it is rendered.
* Rather than implementing the loading and rendering of media directly, {@link ExoPlayer} instead * Rather than implementing the loading and rendering of media directly, {@link ExoPlayer} instead
* delegates this work to one or more {@link TrackRenderer}s, which are injected when the player * delegates this work to one or more {@link Renderer}s, which are injected when the player
* is created. Hence {@link ExoPlayer} is capable of loading and playing any media for which a * is created. Hence {@link ExoPlayer} is capable of loading and playing any media for which a
* {@link TrackRenderer} implementation can be provided. * {@link Renderer} implementation can be provided.
* *
* <p>{@link MediaCodecAudioTrackRenderer} and {@link MediaCodecVideoTrackRenderer} can be used for * <p>{@link MediaCodecAudioRenderer} and {@link MediaCodecVideoRenderer} can be used for
* the common cases of rendering audio and video. These components in turn require an * the common cases of rendering audio and video. These components in turn require an
* <i>upstream</i> {@link MediaPeriod} to be injected through their constructors, where upstream * <i>upstream</i> {@link MediaPeriod} to be injected through their constructors, where upstream
* is defined to denote a component that is closer to the source of the media. This pattern of * is defined to denote a component that is closer to the source of the media. This pattern of
...@@ -63,8 +63,8 @@ package com.google.android.exoplayer2; ...@@ -63,8 +63,8 @@ package com.google.android.exoplayer2;
* <li>Registered {@link EventListener}s are invoked on the thread that created the * <li>Registered {@link EventListener}s are invoked on the thread that created the
* {@link ExoPlayer} instance.</li> * {@link ExoPlayer} instance.</li>
* <li>An internal playback thread is responsible for managing playback and invoking the * <li>An internal playback thread is responsible for managing playback and invoking the
* {@link TrackRenderer}s in order to load and play the media.</li> * {@link Renderer}s in order to load and play the media.</li>
* <li>{@link TrackRenderer} implementations (or any upstream components that they depend on) may * <li>{@link Renderer} implementations (or any upstream components that they depend on) may
* use additional background threads (e.g. to load data). These are implementation specific.</li> * use additional background threads (e.g. to load data). These are implementation specific.</li>
* </ul> * </ul>
* *
...@@ -83,7 +83,7 @@ package com.google.android.exoplayer2; ...@@ -83,7 +83,7 @@ package com.google.android.exoplayer2;
* border="0"/></p> * border="0"/></p>
* *
* <p>The possible playback state transitions are shown below. Transitions can be triggered either * <p>The possible playback state transitions are shown below. Transitions can be triggered either
* by changes in the state of the {@link TrackRenderer}s being used, or as a result of * by changes in the state of the {@link Renderer}s being used, or as a result of
* {@link #setMediaSource(MediaSource)}, {@link #stop()} or {@link #release()} being invoked.</p> * {@link #setMediaSource(MediaSource)}, {@link #stop()} or {@link #release()} being invoked.</p>
* <p align="center"><img src="../../../../../images/exoplayer_playbackstate.png" * <p align="center"><img src="../../../../../images/exoplayer_playbackstate.png"
* alt="ExoPlayer playback state transitions" * alt="ExoPlayer playback state transitions"
...@@ -193,7 +193,7 @@ public interface ExoPlayer { ...@@ -193,7 +193,7 @@ public interface ExoPlayer {
int STATE_IDLE = 1; int STATE_IDLE = 1;
/** /**
* The player not able to immediately play from the current position. The cause is * The player not able to immediately play from the current position. The cause is
* {@link TrackRenderer} specific, but this state typically occurs when more data needs to be * {@link Renderer} specific, but this state typically occurs when more data needs to be
* loaded to be ready to play, or more data needs to be buffered for playback to resume. * loaded to be ready to play, or more data needs to be buffered for playback to resume.
*/ */
int STATE_BUFFERING = 2; int STATE_BUFFERING = 2;
......
...@@ -71,7 +71,7 @@ public final class ExoPlayerFactory { ...@@ -71,7 +71,7 @@ public final class ExoPlayerFactory {
* @param loadControl The {@link LoadControl} that will be used by the instance. * @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks. * will not be used for DRM protected playbacks.
* @param preferExtensionDecoders True to prefer {@link TrackRenderer} instances defined in * @param preferExtensionDecoders True to prefer {@link Renderer} instances defined in
* available extensions over those defined in the core library. Note that extensions must be * available extensions over those defined in the core library. Note that extensions must be
* included in the application build for setting this flag to have any effect. * included in the application build for setting this flag to have any effect.
*/ */
...@@ -92,7 +92,7 @@ public final class ExoPlayerFactory { ...@@ -92,7 +92,7 @@ public final class ExoPlayerFactory {
* @param loadControl The {@link LoadControl} that will be used by the instance. * @param loadControl The {@link LoadControl} that will be used by the instance.
* @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance * @param drmSessionManager An optional {@link DrmSessionManager}. May be null if the instance
* will not be used for DRM protected playbacks. * will not be used for DRM protected playbacks.
* @param preferExtensionDecoders True to prefer {@link TrackRenderer} instances defined in * @param preferExtensionDecoders True to prefer {@link Renderer} instances defined in
* available extensions over those defined in the core library. Note that extensions must be * available extensions over those defined in the core library. Note that extensions must be
* included in the application build for setting this flag to have any effect. * included in the application build for setting this flag to have any effect.
* @param allowedVideoJoiningTimeMs The maximum duration for which a video renderer can attempt to * @param allowedVideoJoiningTimeMs The maximum duration for which a video renderer can attempt to
...@@ -110,10 +110,10 @@ public final class ExoPlayerFactory { ...@@ -110,10 +110,10 @@ public final class ExoPlayerFactory {
* <p> * <p>
* Must be called from a thread that has an associated {@link Looper}. * Must be called from a thread that has an associated {@link Looper}.
* *
* @param renderers The {@link TrackRenderer}s that will be used by the instance. * @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
*/ */
public static ExoPlayer newInstance(TrackRenderer[] renderers, TrackSelector trackSelector) { public static ExoPlayer newInstance(Renderer[] renderers, TrackSelector trackSelector) {
return newInstance(renderers, trackSelector, new DefaultLoadControl()); return newInstance(renderers, trackSelector, new DefaultLoadControl());
} }
...@@ -122,11 +122,11 @@ public final class ExoPlayerFactory { ...@@ -122,11 +122,11 @@ public final class ExoPlayerFactory {
* <p> * <p>
* Must be called from a thread that has an associated {@link Looper}. * Must be called from a thread that has an associated {@link Looper}.
* *
* @param renderers The {@link TrackRenderer}s that will be used by the instance. * @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance. * @param loadControl The {@link LoadControl} that will be used by the instance.
*/ */
public static ExoPlayer newInstance(TrackRenderer[] renderers, TrackSelector trackSelector, public static ExoPlayer newInstance(Renderer[] renderers, TrackSelector trackSelector,
LoadControl loadControl) { LoadControl loadControl) {
return new ExoPlayerImpl(renderers, trackSelector, loadControl); return new ExoPlayerImpl(renderers, trackSelector, loadControl);
} }
......
...@@ -54,12 +54,12 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -54,12 +54,12 @@ import java.util.concurrent.CopyOnWriteArraySet;
/** /**
* Constructs an instance. Must be invoked from a thread that has an associated {@link Looper}. * Constructs an instance. Must be invoked from a thread that has an associated {@link Looper}.
* *
* @param renderers The {@link TrackRenderer}s that will be used by the instance. * @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance. * @param trackSelector The {@link TrackSelector} that will be used by the instance.
* @param loadControl The {@link LoadControl} that will be used by the instance. * @param loadControl The {@link LoadControl} that will be used by the instance.
*/ */
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
public ExoPlayerImpl(TrackRenderer[] renderers, TrackSelector trackSelector, public ExoPlayerImpl(Renderer[] renderers, TrackSelector trackSelector,
LoadControl loadControl) { LoadControl loadControl) {
Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION); Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION);
Assertions.checkNotNull(renderers); Assertions.checkNotNull(renderers);
......
...@@ -100,10 +100,10 @@ import java.util.ArrayList; ...@@ -100,10 +100,10 @@ import java.util.ArrayList;
private final Timeline timeline; private final Timeline timeline;
private PlaybackInfo playbackInfo; private PlaybackInfo playbackInfo;
private TrackRenderer rendererMediaClockSource; private Renderer rendererMediaClockSource;
private MediaClock rendererMediaClock; private MediaClock rendererMediaClock;
private MediaSource mediaSource; private MediaSource mediaSource;
private TrackRenderer[] enabledRenderers; private Renderer[] enabledRenderers;
private boolean released; private boolean released;
private boolean playWhenReady; private boolean playWhenReady;
private boolean rebuffering; private boolean rebuffering;
...@@ -115,7 +115,7 @@ import java.util.ArrayList; ...@@ -115,7 +115,7 @@ import java.util.ArrayList;
private long internalPositionUs; private long internalPositionUs;
public ExoPlayerImplInternal(TrackRenderer[] renderers, TrackSelector trackSelector, public ExoPlayerImplInternal(Renderer[] renderers, TrackSelector trackSelector,
LoadControl loadControl, boolean playWhenReady, Handler eventHandler) { LoadControl loadControl, boolean playWhenReady, Handler eventHandler) {
this.trackSelector = trackSelector; this.trackSelector = trackSelector;
this.loadControl = loadControl; this.loadControl = loadControl;
...@@ -128,7 +128,7 @@ import java.util.ArrayList; ...@@ -128,7 +128,7 @@ import java.util.ArrayList;
} }
standaloneMediaClock = new StandaloneMediaClock(); standaloneMediaClock = new StandaloneMediaClock();
enabledRenderers = new TrackRenderer[0]; enabledRenderers = new Renderer[0];
timeline = new Timeline(renderers); timeline = new Timeline(renderers);
playbackInfo = new PlaybackInfo(0); playbackInfo = new PlaybackInfo(0);
...@@ -335,14 +335,14 @@ import java.util.ArrayList; ...@@ -335,14 +335,14 @@ import java.util.ArrayList;
private void startRenderers() throws ExoPlaybackException { private void startRenderers() throws ExoPlaybackException {
rebuffering = false; rebuffering = false;
standaloneMediaClock.start(); standaloneMediaClock.start();
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
renderer.start(); renderer.start();
} }
} }
private void stopRenderers() throws ExoPlaybackException { private void stopRenderers() throws ExoPlaybackException {
standaloneMediaClock.stop(); standaloneMediaClock.stop();
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
ensureStopped(renderer); ensureStopped(renderer);
} }
} }
...@@ -400,7 +400,7 @@ import java.util.ArrayList; ...@@ -400,7 +400,7 @@ import java.util.ArrayList;
updatePlaybackPositions(); updatePlaybackPositions();
boolean allRenderersEnded = true; boolean allRenderersEnded = true;
boolean allRenderersReadyOrEnded = true; boolean allRenderersReadyOrEnded = true;
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
// TODO: Each renderer should return the maximum delay before which it wishes to be invoked // 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 // again. The minimum of these values should then be used as the delay before the next
// invocation of this method. // invocation of this method.
...@@ -494,7 +494,7 @@ import java.util.ArrayList; ...@@ -494,7 +494,7 @@ import java.util.ArrayList;
long sourceOffsetUs = timeline.playingPeriod == null ? 0 : timeline.playingPeriod.offsetUs; long sourceOffsetUs = timeline.playingPeriod == null ? 0 : timeline.playingPeriod.offsetUs;
internalPositionUs = sourceOffsetUs + periodPositionUs; internalPositionUs = sourceOffsetUs + periodPositionUs;
standaloneMediaClock.setPositionUs(internalPositionUs); standaloneMediaClock.setPositionUs(internalPositionUs);
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
renderer.reset(internalPositionUs); renderer.reset(internalPositionUs);
} }
} }
...@@ -519,7 +519,7 @@ import java.util.ArrayList; ...@@ -519,7 +519,7 @@ import java.util.ArrayList;
standaloneMediaClock.stop(); standaloneMediaClock.stop();
rendererMediaClock = null; rendererMediaClock = null;
rendererMediaClockSource = null; rendererMediaClockSource = null;
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
try { try {
ensureStopped(renderer); ensureStopped(renderer);
renderer.disable(); renderer.disable();
...@@ -528,7 +528,7 @@ import java.util.ArrayList; ...@@ -528,7 +528,7 @@ import java.util.ArrayList;
Log.e(TAG, "Stop failed.", e); Log.e(TAG, "Stop failed.", e);
} }
} }
enabledRenderers = new TrackRenderer[0]; enabledRenderers = new Renderer[0];
mediaSource = null; mediaSource = null;
timeline.reset(); timeline.reset();
loadControl.reset(); loadControl.reset();
...@@ -552,8 +552,8 @@ import java.util.ArrayList; ...@@ -552,8 +552,8 @@ import java.util.ArrayList;
} }
} }
private void ensureStopped(TrackRenderer renderer) throws ExoPlaybackException { private void ensureStopped(Renderer renderer) throws ExoPlaybackException {
if (renderer.getState() == TrackRenderer.STATE_STARTED) { if (renderer.getState() == Renderer.STATE_STARTED) {
renderer.stop(); renderer.stop();
} }
} }
...@@ -573,7 +573,7 @@ import java.util.ArrayList; ...@@ -573,7 +573,7 @@ import java.util.ArrayList;
*/ */
private final class Timeline { private final class Timeline {
private final TrackRenderer[] renderers; private final Renderer[] renderers;
public boolean isReady; public boolean isReady;
public boolean isEnded; public boolean isEnded;
...@@ -585,7 +585,7 @@ import java.util.ArrayList; ...@@ -585,7 +585,7 @@ import java.util.ArrayList;
private int pendingPeriodIndex; private int pendingPeriodIndex;
private long playingPeriodEndPositionUs; private long playingPeriodEndPositionUs;
public Timeline(TrackRenderer[] renderers) { public Timeline(Renderer[] renderers) {
this.renderers = renderers; this.renderers = renderers;
playingPeriodEndPositionUs = C.UNSET_TIME_US; playingPeriodEndPositionUs = C.UNSET_TIME_US;
} }
...@@ -615,7 +615,7 @@ import java.util.ArrayList; ...@@ -615,7 +615,7 @@ import java.util.ArrayList;
public void maybeThrowPeriodPrepareError() throws IOException { public void maybeThrowPeriodPrepareError() throws IOException {
if (loadingPeriod != null && !loadingPeriod.prepared if (loadingPeriod != null && !loadingPeriod.prepared
&& (readingPeriod == null || readingPeriod.nextPeriod == loadingPeriod)) { && (readingPeriod == null || readingPeriod.nextPeriod == loadingPeriod)) {
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
if (!renderer.hasReadStreamToEnd()) { if (!renderer.hasReadStreamToEnd()) {
return; return;
} }
...@@ -682,7 +682,7 @@ import java.util.ArrayList; ...@@ -682,7 +682,7 @@ import java.util.ArrayList;
// The renderers have their final TrackStreams. // The renderers have their final TrackStreams.
return; return;
} }
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
if (!renderer.hasReadStreamToEnd()) { if (!renderer.hasReadStreamToEnd()) {
return; return;
} }
...@@ -693,7 +693,7 @@ import java.util.ArrayList; ...@@ -693,7 +693,7 @@ import java.util.ArrayList;
TrackSelectionArray newTrackSelections = readingPeriod.trackSelections; TrackSelectionArray newTrackSelections = readingPeriod.trackSelections;
TrackGroupArray groups = readingPeriod.mediaPeriod.getTrackGroups(); TrackGroupArray groups = readingPeriod.mediaPeriod.getTrackGroups();
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
TrackRenderer renderer = renderers[i]; Renderer renderer = renderers[i];
TrackSelection oldSelection = oldTrackSelections.get(i); TrackSelection oldSelection = oldTrackSelections.get(i);
TrackSelection newSelection = newTrackSelections.get(i); TrackSelection newSelection = newTrackSelections.get(i);
if (oldSelection != null) { if (oldSelection != null) {
...@@ -717,7 +717,7 @@ import java.util.ArrayList; ...@@ -717,7 +717,7 @@ import java.util.ArrayList;
&& readingPeriod.index == periodCount - 1) { && readingPeriod.index == periodCount - 1) {
readingPeriod = null; readingPeriod = null;
// This is the last period, so signal the renderers to read the end of the stream. // This is the last period, so signal the renderers to read the end of the stream.
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
renderer.setCurrentTrackStreamIsFinal(); renderer.setCurrentTrackStreamIsFinal();
} }
} }
...@@ -789,11 +789,11 @@ import java.util.ArrayList; ...@@ -789,11 +789,11 @@ import java.util.ArrayList;
resetInternalPosition(seekPositionUs); resetInternalPosition(seekPositionUs);
maybeContinueLoading(); maybeContinueLoading();
} else { } else {
for (TrackRenderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
ensureStopped(renderer); ensureStopped(renderer);
renderer.disable(); renderer.disable();
} }
enabledRenderers = new TrackRenderer[0]; enabledRenderers = new Renderer[0];
playingPeriod = null; playingPeriod = null;
readingPeriod = null; readingPeriod = null;
loadingPeriod = null; loadingPeriod = null;
...@@ -844,8 +844,8 @@ import java.util.ArrayList; ...@@ -844,8 +844,8 @@ import java.util.ArrayList;
int enabledRendererCount = 0; int enabledRendererCount = 0;
boolean[] rendererWasEnabledFlags = new boolean[renderers.length]; boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
TrackRenderer renderer = renderers[i]; Renderer renderer = renderers[i];
rendererWasEnabledFlags[i] = renderer.getState() != TrackRenderer.STATE_DISABLED; rendererWasEnabledFlags[i] = renderer.getState() != Renderer.STATE_DISABLED;
TrackSelection oldSelection = playingPeriodOldTrackSelections.get(i); TrackSelection oldSelection = playingPeriodOldTrackSelections.get(i);
TrackSelection newSelection = playingPeriod.trackSelections.get(i); TrackSelection newSelection = playingPeriod.trackSelections.get(i);
if (newSelection != null) { if (newSelection != null) {
...@@ -906,8 +906,8 @@ import java.util.ArrayList; ...@@ -906,8 +906,8 @@ import java.util.ArrayList;
int enabledRendererCount = 0; int enabledRendererCount = 0;
boolean[] rendererWasEnabledFlags = new boolean[renderers.length]; boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
TrackRenderer renderer = renderers[i]; Renderer renderer = renderers[i];
rendererWasEnabledFlags[i] = renderer.getState() != TrackRenderer.STATE_DISABLED; rendererWasEnabledFlags[i] = renderer.getState() != Renderer.STATE_DISABLED;
TrackSelection newSelection = period.trackSelections.get(i); TrackSelection newSelection = period.trackSelections.get(i);
if (newSelection != null) { if (newSelection != null) {
// The renderer should be enabled when playing the new period. // The renderer should be enabled when playing the new period.
...@@ -942,15 +942,15 @@ import java.util.ArrayList; ...@@ -942,15 +942,15 @@ import java.util.ArrayList;
private void enableRenderers(boolean[] rendererWasEnabledFlags, int enabledRendererCount) private void enableRenderers(boolean[] rendererWasEnabledFlags, int enabledRendererCount)
throws ExoPlaybackException { throws ExoPlaybackException {
enabledRenderers = new TrackRenderer[enabledRendererCount]; enabledRenderers = new Renderer[enabledRendererCount];
enabledRendererCount = 0; enabledRendererCount = 0;
TrackGroupArray trackGroups = playingPeriod.mediaPeriod.getTrackGroups(); TrackGroupArray trackGroups = playingPeriod.mediaPeriod.getTrackGroups();
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
TrackRenderer renderer = renderers[i]; Renderer renderer = renderers[i];
TrackSelection newSelection = playingPeriod.trackSelections.get(i); TrackSelection newSelection = playingPeriod.trackSelections.get(i);
if (newSelection != null) { if (newSelection != null) {
enabledRenderers[enabledRendererCount++] = renderer; enabledRenderers[enabledRendererCount++] = renderer;
if (renderer.getState() == TrackRenderer.STATE_DISABLED) { if (renderer.getState() == Renderer.STATE_DISABLED) {
// 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.
...@@ -988,7 +988,7 @@ import java.util.ArrayList; ...@@ -988,7 +988,7 @@ import java.util.ArrayList;
*/ */
private static final class Period { private static final class Period {
private final TrackRenderer[] renderers; private final Renderer[] renderers;
private final TrackSelector trackSelector; private final TrackSelector trackSelector;
public final MediaPeriod mediaPeriod; public final MediaPeriod mediaPeriod;
...@@ -1005,7 +1005,7 @@ import java.util.ArrayList; ...@@ -1005,7 +1005,7 @@ import java.util.ArrayList;
private TrackSelectionArray trackSelections; private TrackSelectionArray trackSelections;
private TrackSelectionArray periodTrackSelections; private TrackSelectionArray periodTrackSelections;
public Period(TrackRenderer[] renderers, TrackSelector trackSelector, MediaPeriod mediaPeriod, public Period(Renderer[] renderers, TrackSelector trackSelector, MediaPeriod mediaPeriod,
int index) { int index) {
this.renderers = renderers; this.renderers = renderers;
this.trackSelector = trackSelector; this.trackSelector = trackSelector;
......
...@@ -29,7 +29,7 @@ public interface LoadControl { ...@@ -29,7 +29,7 @@ public interface LoadControl {
* @param trackGroups The available {@link TrackGroup}s. * @param trackGroups The available {@link TrackGroup}s.
* @param trackSelections The {@link TrackSelection}s that were made. * @param trackSelections The {@link TrackSelection}s that were made.
*/ */
void onTrackSelections(TrackRenderer[] renderers, TrackGroupArray trackGroups, void onTrackSelections(Renderer[] renderers, TrackGroupArray trackGroups,
TrackSelectionArray trackSelections); TrackSelectionArray trackSelections);
/** /**
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
*/ */
package com.google.android.exoplayer2; package com.google.android.exoplayer2;
import com.google.android.exoplayer2.AudioTrackRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.AudioRendererEventListener.EventDispatcher;
import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.audio.AudioCapabilities; import com.google.android.exoplayer2.audio.AudioCapabilities;
import com.google.android.exoplayer2.audio.AudioTrack; import com.google.android.exoplayer2.audio.AudioTrack;
...@@ -39,7 +39,7 @@ import java.nio.ByteBuffer; ...@@ -39,7 +39,7 @@ import java.nio.ByteBuffer;
* Decodes and renders audio using {@link MediaCodec} and {@link android.media.AudioTrack}. * Decodes and renders audio using {@link MediaCodec} and {@link android.media.AudioTrack}.
*/ */
@TargetApi(16) @TargetApi(16)
public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implements MediaClock { public class MediaCodecAudioRenderer extends MediaCodecRenderer implements MediaClock {
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final AudioTrack audioTrack; private final AudioTrack audioTrack;
...@@ -57,7 +57,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -57,7 +57,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
/** /**
* @param mediaCodecSelector A decoder selector. * @param mediaCodecSelector A decoder selector.
*/ */
public MediaCodecAudioTrackRenderer(MediaCodecSelector mediaCodecSelector) { public MediaCodecAudioRenderer(MediaCodecSelector mediaCodecSelector) {
this(mediaCodecSelector, null, true); this(mediaCodecSelector, null, true);
} }
...@@ -71,7 +71,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -71,7 +71,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* permitted to play clear regions of encrypted media files before {@code drmSessionManager} * permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media. * has obtained the keys necessary to decrypt encrypted regions of the media.
*/ */
public MediaCodecAudioTrackRenderer(MediaCodecSelector mediaCodecSelector, public MediaCodecAudioRenderer(MediaCodecSelector mediaCodecSelector,
DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys) { DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys) {
this(mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys, null, null); this(mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys, null, null);
} }
...@@ -82,8 +82,8 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -82,8 +82,8 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
*/ */
public MediaCodecAudioTrackRenderer(MediaCodecSelector mediaCodecSelector, Handler eventHandler, public MediaCodecAudioRenderer(MediaCodecSelector mediaCodecSelector, Handler eventHandler,
AudioTrackRendererEventListener eventListener) { AudioRendererEventListener eventListener) {
this(mediaCodecSelector, null, true, eventHandler, eventListener); this(mediaCodecSelector, null, true, eventHandler, eventListener);
} }
...@@ -100,9 +100,9 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -100,9 +100,9 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
*/ */
public MediaCodecAudioTrackRenderer(MediaCodecSelector mediaCodecSelector, public MediaCodecAudioRenderer(MediaCodecSelector mediaCodecSelector,
DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys, DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys,
Handler eventHandler, AudioTrackRendererEventListener eventListener) { Handler eventHandler, AudioRendererEventListener eventListener) {
this(mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, this(mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys, eventHandler,
eventListener, null, AudioManager.STREAM_MUSIC); eventListener, null, AudioManager.STREAM_MUSIC);
} }
...@@ -123,9 +123,9 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -123,9 +123,9 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
* default capabilities (no encoded audio passthrough support) should be assumed. * default capabilities (no encoded audio passthrough support) should be assumed.
* @param streamType The type of audio stream for the {@link AudioTrack}. * @param streamType The type of audio stream for the {@link AudioTrack}.
*/ */
public MediaCodecAudioTrackRenderer(MediaCodecSelector mediaCodecSelector, public MediaCodecAudioRenderer(MediaCodecSelector mediaCodecSelector,
DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys, DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys,
Handler eventHandler, AudioTrackRendererEventListener eventListener, Handler eventHandler, AudioRendererEventListener eventListener,
AudioCapabilities audioCapabilities, int streamType) { AudioCapabilities audioCapabilities, int streamType) {
super(mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys); super(mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys);
audioSessionId = AudioTrack.SESSION_ID_NOT_SET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
...@@ -344,14 +344,14 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem ...@@ -344,14 +344,14 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
} catch (AudioTrack.InitializationException e) { } catch (AudioTrack.InitializationException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex()); throw ExoPlaybackException.createForRenderer(e, getIndex());
} }
if (getState() == TrackRenderer.STATE_STARTED) { if (getState() == Renderer.STATE_STARTED) {
audioTrack.play(); audioTrack.play();
} }
} else { } else {
// Check for AudioTrack underrun. // Check for AudioTrack underrun.
boolean audioTrackHadData = audioTrackHasData; boolean audioTrackHadData = audioTrackHasData;
audioTrackHasData = audioTrack.hasPendingData(); audioTrackHasData = audioTrack.hasPendingData();
if (audioTrackHadData && !audioTrackHasData && getState() == TrackRenderer.STATE_STARTED) { if (audioTrackHadData && !audioTrackHasData && getState() == Renderer.STATE_STARTED) {
long elapsedSinceLastFeedMs = SystemClock.elapsedRealtime() - lastFeedElapsedRealtimeMs; long elapsedSinceLastFeedMs = SystemClock.elapsedRealtime() - lastFeedElapsedRealtimeMs;
long bufferSizeUs = audioTrack.getBufferSizeUs(); long bufferSizeUs = audioTrack.getBufferSizeUs();
long bufferSizeMs = bufferSizeUs == C.UNSET_TIME_US ? -1 : bufferSizeUs / 1000; long bufferSizeMs = bufferSizeUs == C.UNSET_TIME_US ? -1 : bufferSizeUs / 1000;
......
...@@ -37,10 +37,10 @@ import java.util.ArrayList; ...@@ -37,10 +37,10 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* An abstract {@link TrackRenderer} that uses {@link MediaCodec} to decode samples for rendering. * An abstract {@link Renderer} that uses {@link MediaCodec} to decode samples for rendering.
*/ */
@TargetApi(16) @TargetApi(16)
public abstract class MediaCodecTrackRenderer extends TrackRenderer { public abstract class MediaCodecRenderer extends Renderer {
/** /**
* Thrown when a failure occurs instantiating a decoder. * Thrown when a failure occurs instantiating a decoder.
...@@ -192,7 +192,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { ...@@ -192,7 +192,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
* permitted to play clear regions of encrypted media files before {@code drmSessionManager} * permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media. * has obtained the keys necessary to decrypt encrypted regions of the media.
*/ */
public MediaCodecTrackRenderer(MediaCodecSelector mediaCodecSelector, public MediaCodecRenderer(MediaCodecSelector mediaCodecSelector,
DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys) { DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys) {
Assertions.checkState(Util.SDK_INT >= 16); Assertions.checkState(Util.SDK_INT >= 16);
this.mediaCodecSelector = Assertions.checkNotNull(mediaCodecSelector); this.mediaCodecSelector = Assertions.checkNotNull(mediaCodecSelector);
...@@ -338,7 +338,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer { ...@@ -338,7 +338,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
throwDecoderInitError(new DecoderInitializationException(format, e, throwDecoderInitError(new DecoderInitializationException(format, e,
drmSessionRequiresSecureDecoder, codecName)); drmSessionRequiresSecureDecoder, codecName));
} }
codecHotswapDeadlineMs = getState() == TrackRenderer.STATE_STARTED codecHotswapDeadlineMs = getState() == Renderer.STATE_STARTED
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS) : -1; ? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS) : -1;
inputIndex = -1; inputIndex = -1;
outputIndex = -1; outputIndex = -1;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package com.google.android.exoplayer2; package com.google.android.exoplayer2;
import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.VideoTrackRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.VideoRendererEventListener.EventDispatcher;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.TraceUtil;
...@@ -39,7 +39,7 @@ import java.nio.ByteBuffer; ...@@ -39,7 +39,7 @@ import java.nio.ByteBuffer;
* Decodes and renders video using {@link MediaCodec}. * Decodes and renders video using {@link MediaCodec}.
*/ */
@TargetApi(16) @TargetApi(16)
public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { public class MediaCodecVideoRenderer extends MediaCodecRenderer {
private static final String TAG = "MediaCodecVideoRenderer"; private static final String TAG = "MediaCodecVideoRenderer";
private static final String KEY_CROP_LEFT = "crop-left"; private static final String KEY_CROP_LEFT = "crop-left";
...@@ -82,7 +82,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { ...@@ -82,7 +82,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
* @param videoScalingMode The scaling mode to pass to * @param videoScalingMode The scaling mode to pass to
* {@link MediaCodec#setVideoScalingMode(int)}. * {@link MediaCodec#setVideoScalingMode(int)}.
*/ */
public MediaCodecVideoTrackRenderer(Context context, MediaCodecSelector mediaCodecSelector, public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector,
int videoScalingMode) { int videoScalingMode) {
this(context, mediaCodecSelector, videoScalingMode, 0); this(context, mediaCodecSelector, videoScalingMode, 0);
} }
...@@ -95,7 +95,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { ...@@ -95,7 +95,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer * @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* can attempt to seamlessly join an ongoing playback. * can attempt to seamlessly join an ongoing playback.
*/ */
public MediaCodecVideoTrackRenderer(Context context, MediaCodecSelector mediaCodecSelector, public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector,
int videoScalingMode, long allowedJoiningTimeMs) { int videoScalingMode, long allowedJoiningTimeMs) {
this(context, mediaCodecSelector, videoScalingMode, allowedJoiningTimeMs, null, null, -1); this(context, mediaCodecSelector, videoScalingMode, allowedJoiningTimeMs, null, null, -1);
} }
...@@ -111,11 +111,11 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { ...@@ -111,11 +111,11 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
* @param maxDroppedFrameCountToNotify The maximum number of frames that can be dropped between * @param maxDroppedFrameCountToNotify The maximum number of frames that can be dropped between
* invocations of {@link VideoTrackRendererEventListener#onDroppedFrames(int, long)}. * invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
*/ */
public MediaCodecVideoTrackRenderer(Context context, MediaCodecSelector mediaCodecSelector, public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector,
int videoScalingMode, long allowedJoiningTimeMs, Handler eventHandler, int videoScalingMode, long allowedJoiningTimeMs, Handler eventHandler,
VideoTrackRendererEventListener eventListener, int maxDroppedFrameCountToNotify) { VideoRendererEventListener eventListener, int maxDroppedFrameCountToNotify) {
this(context, mediaCodecSelector, videoScalingMode, allowedJoiningTimeMs, null, false, this(context, mediaCodecSelector, videoScalingMode, allowedJoiningTimeMs, null, false,
eventHandler, eventListener, maxDroppedFrameCountToNotify); eventHandler, eventListener, maxDroppedFrameCountToNotify);
} }
...@@ -138,12 +138,12 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { ...@@ -138,12 +138,12 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
* @param maxDroppedFrameCountToNotify The maximum number of frames that can be dropped between * @param maxDroppedFrameCountToNotify The maximum number of frames that can be dropped between
* invocations of {@link VideoTrackRendererEventListener#onDroppedFrames(int, long)}. * invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
*/ */
public MediaCodecVideoTrackRenderer(Context context, MediaCodecSelector mediaCodecSelector, public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector,
int videoScalingMode, long allowedJoiningTimeMs, DrmSessionManager drmSessionManager, int videoScalingMode, long allowedJoiningTimeMs, DrmSessionManager drmSessionManager,
boolean playClearSamplesWithoutKeys, Handler eventHandler, boolean playClearSamplesWithoutKeys, Handler eventHandler,
VideoTrackRendererEventListener eventListener, int maxDroppedFrameCountToNotify) { VideoRendererEventListener eventListener, int maxDroppedFrameCountToNotify) {
super(mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys); super(mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys);
this.videoScalingMode = videoScalingMode; this.videoScalingMode = videoScalingMode;
this.allowedJoiningTimeMs = allowedJoiningTimeMs; this.allowedJoiningTimeMs = allowedJoiningTimeMs;
...@@ -307,7 +307,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { ...@@ -307,7 +307,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
this.surface = surface; this.surface = surface;
this.reportedDrawnToSurface = false; this.reportedDrawnToSurface = false;
int state = getState(); int state = getState();
if (state == TrackRenderer.STATE_ENABLED || state == TrackRenderer.STATE_STARTED) { if (state == Renderer.STATE_ENABLED || state == Renderer.STATE_STARTED) {
releaseCodec(); releaseCodec();
maybeInitCodec(); maybeInitCodec();
} }
...@@ -403,7 +403,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer { ...@@ -403,7 +403,7 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
return true; return true;
} }
if (getState() != TrackRenderer.STATE_STARTED) { if (getState() != Renderer.STATE_STARTED) {
return false; return false;
} }
......
...@@ -23,16 +23,16 @@ import java.io.IOException; ...@@ -23,16 +23,16 @@ import java.io.IOException;
/** /**
* Renders a single component of media. * Renders a single component of media.
* * <p>
* <p>Internally, a renderer's lifecycle is managed by the owning {@link ExoPlayer}. The player * Internally, a renderer's lifecycle is managed by the owning {@link ExoPlayer}. The player will
* will transition its renderers through various states as the overall playback state changes. The * transition its renderers through various states as the overall playback state changes. The valid
* valid state transitions are shown below, annotated with the methods that are invoked during each * state transitions are shown below, annotated with the methods that are invoked during each
* transition. * transition.
* <p align="center"><img src="../../../../../images/trackrenderer_state.png" * <p align="center"><img src="../../../../../images/trackrenderer_state.png"
* alt="TrackRenderer state transitions" * alt="Renderer state transitions"
* border="0"/></p> * border="0"/></p>
*/ */
public abstract class TrackRenderer implements ExoPlayerComponent { public abstract class Renderer implements ExoPlayerComponent {
/** /**
* A mask to apply to the result of {@link #supportsFormat(Format)} to obtain one of * A mask to apply to the result of {@link #supportsFormat(Format)} to obtain one of
...@@ -41,33 +41,33 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -41,33 +41,33 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
*/ */
public static final int FORMAT_SUPPORT_MASK = 0b11; public static final int FORMAT_SUPPORT_MASK = 0b11;
/** /**
* The {@link TrackRenderer} is capable of rendering the format. * The {@link Renderer} is capable of rendering the format.
*/ */
public static final int FORMAT_HANDLED = 0b11; public static final int FORMAT_HANDLED = 0b11;
/** /**
* The {@link TrackRenderer} is capable of rendering formats with the same mimeType, but the * The {@link Renderer} is capable of rendering formats with the same mimeType, but the
* properties of the format exceed the renderer's capability. * properties of the format exceed the renderer's capability.
* <p> * <p>
* Example: The {@link TrackRenderer} is capable of rendering H264 and the format's mimeType is * Example: The {@link Renderer} is capable of rendering H264 and the format's mimeType is
* {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported * {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported
* by the underlying H264 decoder. * by the underlying H264 decoder.
*/ */
public static final int FORMAT_EXCEEDS_CAPABILITIES = 0b10; public static final int FORMAT_EXCEEDS_CAPABILITIES = 0b10;
/** /**
* The {@link TrackRenderer} is a general purpose renderer for formats of the same top-level type, * The {@link Renderer} is a general purpose renderer for formats of the same top-level type,
* but is not capable of rendering the format or any other format with the same mimeType because * but is not capable of rendering the format or any other format with the same mimeType because
* the sub-type is not supported. * the sub-type is not supported.
* <p> * <p>
* Example: The {@link TrackRenderer} is a general purpose audio renderer and the format's * Example: The {@link Renderer} is a general purpose audio renderer and the format's
* mimeType matches audio/[subtype], but there does not exist a suitable decoder for [subtype]. * mimeType matches audio/[subtype], but there does not exist a suitable decoder for [subtype].
*/ */
public static final int FORMAT_UNSUPPORTED_SUBTYPE = 0b01; public static final int FORMAT_UNSUPPORTED_SUBTYPE = 0b01;
/** /**
* The {@link TrackRenderer} is not capable of rendering the format, either because it does not * The {@link Renderer} is not capable of rendering the format, either because it does not
* support the format's top-level type, or because it's a specialized renderer for a different * support the format's top-level type, or because it's a specialized renderer for a different
* mimeType. * mimeType.
* <p> * <p>
* Example: The {@link TrackRenderer} is a general purpose video renderer, but the format has an * Example: The {@link Renderer} is a general purpose video renderer, but the format has an
* audio mimeType. * audio mimeType.
*/ */
public static final int FORMAT_UNSUPPORTED_TYPE = 0b00; public static final int FORMAT_UNSUPPORTED_TYPE = 0b00;
...@@ -78,16 +78,16 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -78,16 +78,16 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
*/ */
public static final int ADAPTIVE_SUPPORT_MASK = 0b1100; public static final int ADAPTIVE_SUPPORT_MASK = 0b1100;
/** /**
* The {@link TrackRenderer} can seamlessly adapt between formats. * The {@link Renderer} can seamlessly adapt between formats.
*/ */
public static final int ADAPTIVE_SEAMLESS = 0b1000; public static final int ADAPTIVE_SEAMLESS = 0b1000;
/** /**
* The {@link TrackRenderer} can adapt between formats, but may suffer a brief discontinuity * The {@link Renderer} can adapt between formats, but may suffer a brief discontinuity
* (~50-100ms) when adaptation occurs. * (~50-100ms) when adaptation occurs.
*/ */
public static final int ADAPTIVE_NOT_SEAMLESS = 0b0100; public static final int ADAPTIVE_NOT_SEAMLESS = 0b0100;
/** /**
* The {@link TrackRenderer} does not support adaptation between formats. * The {@link Renderer} does not support adaptation between formats.
*/ */
public static final int ADAPTIVE_NOT_SUPPORTED = 0b0000; public static final int ADAPTIVE_NOT_SUPPORTED = 0b0000;
...@@ -112,7 +112,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -112,7 +112,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
private boolean readEndOfStream; private boolean readEndOfStream;
private boolean streamIsFinal; private boolean streamIsFinal;
public TrackRenderer() { public Renderer() {
readEndOfStream = true; readEndOfStream = true;
} }
...@@ -447,7 +447,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -447,7 +447,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
/** /**
* 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
* returned by all of its {@link TrackRenderer}s. * returned by all of its {@link Renderer}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}.
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package com.google.android.exoplayer2; package com.google.android.exoplayer2;
/** /**
* Defines a policy for selecting the track rendered by each {@link TrackRenderer}. * Defines a policy for selecting the track rendered by each {@link Renderer}.
*/ */
public abstract class TrackSelectionPolicy { public abstract class TrackSelectionPolicy {
...@@ -49,17 +49,17 @@ public abstract class TrackSelectionPolicy { ...@@ -49,17 +49,17 @@ public abstract class TrackSelectionPolicy {
} }
/** /**
* Given an array of {@link TrackRenderer}s and a set of {@link TrackGroup}s assigned to each of * Given an array of {@link Renderer}s and a set of {@link TrackGroup}s assigned to each of
* them, provides a {@link TrackSelection} per renderer. * them, provides a {@link TrackSelection} per renderer.
* *
* @param renderers The available {@link TrackRenderer}s. * @param renderers The available {@link Renderer}s.
* @param rendererTrackGroupArrays An array of {@link TrackGroupArray}s where each entry * @param rendererTrackGroupArrays An array of {@link TrackGroupArray}s where each entry
* corresponds to the {@link TrackRenderer} of equal index in {@code renderers}. * corresponds to the {@link Renderer} of equal index in {@code renderers}.
* @param rendererFormatSupports Maps every available track to a specific level of support as * @param rendererFormatSupports Maps every available track to a specific level of support as
* defined by the {@link TrackRenderer} {@code FORMAT_*} constants. * defined by the {@link Renderer} {@code FORMAT_*} constants.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected abstract TrackSelection[] selectTracks(TrackRenderer[] renderers, protected abstract TrackSelection[] selectTracks(Renderer[] renderers,
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports) TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports)
throws ExoPlaybackException; throws ExoPlaybackException;
......
...@@ -18,7 +18,7 @@ package com.google.android.exoplayer2; ...@@ -18,7 +18,7 @@ package com.google.android.exoplayer2;
import android.util.Pair; import android.util.Pair;
/** /**
* Selects tracks to be consumed by available {@link TrackRenderer}s. * Selects tracks to be consumed by available {@link Renderer}s.
*/ */
public abstract class TrackSelector { public abstract class TrackSelector {
...@@ -63,12 +63,12 @@ public abstract class TrackSelector { ...@@ -63,12 +63,12 @@ public abstract class TrackSelector {
* if the selection is activated. * if the selection is activated.
* @throws ExoPlaybackException If an error occurs selecting tracks. * @throws ExoPlaybackException If an error occurs selecting tracks.
*/ */
protected abstract Pair<TrackSelectionArray, Object> selectTracks(TrackRenderer[] renderers, protected abstract Pair<TrackSelectionArray, Object> selectTracks(Renderer[] renderers,
TrackGroupArray trackGroups) throws ExoPlaybackException; TrackGroupArray trackGroups) throws ExoPlaybackException;
/** /**
* Invoked when a selection previously generated by * Invoked when a selection previously generated by
* {@link #selectTracks(TrackRenderer[], TrackGroupArray)} is activated. * {@link #selectTracks(Renderer[], TrackGroupArray)} is activated.
* *
* @param selectionInfo The opaque object associated with the selection. * @param selectionInfo The opaque object associated with the selection.
*/ */
......
...@@ -23,9 +23,9 @@ import android.view.Surface; ...@@ -23,9 +23,9 @@ import android.view.Surface;
import android.view.TextureView; import android.view.TextureView;
/** /**
* Interface definition for a callback to be notified of video {@link TrackRenderer} events. * Interface definition for a callback to be notified of video {@link Renderer} events.
*/ */
public interface VideoTrackRendererEventListener { public interface VideoRendererEventListener {
/** /**
* Invoked when the renderer is enabled. * Invoked when the renderer is enabled.
...@@ -101,14 +101,14 @@ public interface VideoTrackRendererEventListener { ...@@ -101,14 +101,14 @@ public interface VideoTrackRendererEventListener {
void onVideoDisabled(CodecCounters counters); void onVideoDisabled(CodecCounters counters);
/** /**
* Dispatches events to a {@link VideoTrackRendererEventListener}. * Dispatches events to a {@link VideoRendererEventListener}.
*/ */
final class EventDispatcher { final class EventDispatcher {
private final Handler handler; private final Handler handler;
private final VideoTrackRendererEventListener listener; private final VideoRendererEventListener listener;
public EventDispatcher(Handler handler, VideoTrackRendererEventListener listener) { public EventDispatcher(Handler handler, VideoRendererEventListener listener) {
this.handler = listener != null ? Assertions.checkNotNull(handler) : null; this.handler = listener != null ? Assertions.checkNotNull(handler) : null;
this.listener = listener; this.listener = listener;
} }
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
*/ */
package com.google.android.exoplayer2.extensions; package com.google.android.exoplayer2.extensions;
import com.google.android.exoplayer2.AudioTrackRendererEventListener; import com.google.android.exoplayer2.AudioRendererEventListener;
import com.google.android.exoplayer2.AudioTrackRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.AudioRendererEventListener.EventDispatcher;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.CodecCounters; import com.google.android.exoplayer2.CodecCounters;
import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.DecoderInputBuffer;
...@@ -24,7 +24,7 @@ import com.google.android.exoplayer2.ExoPlaybackException; ...@@ -24,7 +24,7 @@ import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.MediaClock; import com.google.android.exoplayer2.MediaClock;
import com.google.android.exoplayer2.TrackRenderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.TrackStream; import com.google.android.exoplayer2.TrackStream;
import com.google.android.exoplayer2.audio.AudioCapabilities; import com.google.android.exoplayer2.audio.AudioCapabilities;
import com.google.android.exoplayer2.audio.AudioTrack; import com.google.android.exoplayer2.audio.AudioTrack;
...@@ -39,7 +39,7 @@ import android.os.SystemClock; ...@@ -39,7 +39,7 @@ import android.os.SystemClock;
/** /**
* Decodes and renders audio using a {@link SimpleDecoder}. * Decodes and renders audio using a {@link SimpleDecoder}.
*/ */
public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements MediaClock { public abstract class AudioDecoderRenderer extends Renderer implements MediaClock {
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final FormatHolder formatHolder; private final FormatHolder formatHolder;
...@@ -62,7 +62,7 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements ...@@ -62,7 +62,7 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
private boolean audioTrackHasData; private boolean audioTrackHasData;
private long lastFeedElapsedRealtimeMs; private long lastFeedElapsedRealtimeMs;
public AudioDecoderTrackRenderer() { public AudioDecoderRenderer() {
this(null, null); this(null, null);
} }
...@@ -71,8 +71,8 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements ...@@ -71,8 +71,8 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
* null if delivery of events is not required. * null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required.
*/ */
public AudioDecoderTrackRenderer(Handler eventHandler, public AudioDecoderRenderer(Handler eventHandler,
AudioTrackRendererEventListener eventListener) { AudioRendererEventListener eventListener) {
this (eventHandler, eventListener, null, AudioManager.STREAM_MUSIC); this (eventHandler, eventListener, null, AudioManager.STREAM_MUSIC);
} }
...@@ -84,8 +84,8 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements ...@@ -84,8 +84,8 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
* default capabilities (no encoded audio passthrough support) should be assumed. * default capabilities (no encoded audio passthrough support) should be assumed.
* @param streamType The type of audio stream for the {@link AudioTrack}. * @param streamType The type of audio stream for the {@link AudioTrack}.
*/ */
public AudioDecoderTrackRenderer(Handler eventHandler, public AudioDecoderRenderer(Handler eventHandler,
AudioTrackRendererEventListener eventListener, AudioCapabilities audioCapabilities, AudioRendererEventListener eventListener, AudioCapabilities audioCapabilities,
int streamType) { int streamType) {
eventDispatcher = new EventDispatcher(eventHandler, eventListener); eventDispatcher = new EventDispatcher(eventHandler, eventListener);
audioSessionId = AudioTrack.SESSION_ID_NOT_SET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
...@@ -193,14 +193,14 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements ...@@ -193,14 +193,14 @@ public abstract class AudioDecoderTrackRenderer extends TrackRenderer implements
onAudioSessionId(audioSessionId); onAudioSessionId(audioSessionId);
} }
audioTrackHasData = false; audioTrackHasData = false;
if (getState() == TrackRenderer.STATE_STARTED) { if (getState() == Renderer.STATE_STARTED) {
audioTrack.play(); audioTrack.play();
} }
} else { } else {
// Check for AudioTrack underrun. // Check for AudioTrack underrun.
boolean audioTrackHadData = audioTrackHasData; boolean audioTrackHadData = audioTrackHasData;
audioTrackHasData = audioTrack.hasPendingData(); audioTrackHasData = audioTrack.hasPendingData();
if (audioTrackHadData && !audioTrackHasData && getState() == TrackRenderer.STATE_STARTED) { if (audioTrackHadData && !audioTrackHasData && getState() == Renderer.STATE_STARTED) {
long elapsedSinceLastFeedMs = SystemClock.elapsedRealtime() - lastFeedElapsedRealtimeMs; long elapsedSinceLastFeedMs = SystemClock.elapsedRealtime() - lastFeedElapsedRealtimeMs;
long bufferSizeUs = audioTrack.getBufferSizeUs(); long bufferSizeUs = audioTrack.getBufferSizeUs();
long bufferSizeMs = bufferSizeUs == C.UNSET_TIME_US ? -1 : bufferSizeUs / 1000; long bufferSizeMs = bufferSizeUs == C.UNSET_TIME_US ? -1 : bufferSizeUs / 1000;
......
...@@ -20,7 +20,7 @@ import com.google.android.exoplayer2.DecoderInputBuffer; ...@@ -20,7 +20,7 @@ import com.google.android.exoplayer2.DecoderInputBuffer;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.TrackRenderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.TrackStream; import com.google.android.exoplayer2.TrackStream;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
...@@ -33,18 +33,18 @@ import java.io.IOException; ...@@ -33,18 +33,18 @@ import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** /**
* A {@link TrackRenderer} for metadata embedded in a media stream. * A {@link Renderer} for metadata embedded in a media stream.
* *
* @param <T> The type of the metadata. * @param <T> The type of the metadata.
*/ */
public final class MetadataTrackRenderer<T> extends TrackRenderer implements Callback { public final class MetadataRenderer<T> extends Renderer implements Callback {
/** /**
* An interface for components that process metadata. * An output for the renderer.
* *
* @param <T> The type of the metadata. * @param <T> The type of the metadata.
*/ */
public interface MetadataRenderer<T> { public interface Output<T> {
/** /**
* Invoked each time there is a metadata associated with current playback time. * Invoked each time there is a metadata associated with current playback time.
...@@ -58,8 +58,8 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal ...@@ -58,8 +58,8 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal
private static final int MSG_INVOKE_RENDERER = 0; private static final int MSG_INVOKE_RENDERER = 0;
private final MetadataParser<T> metadataParser; private final MetadataParser<T> metadataParser;
private final MetadataRenderer<T> metadataRenderer; private final Output<T> output;
private final Handler metadataHandler; private final Handler outputHandler;
private final FormatHolder formatHolder; private final FormatHolder formatHolder;
private final DecoderInputBuffer buffer; private final DecoderInputBuffer buffer;
...@@ -68,20 +68,18 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal ...@@ -68,20 +68,18 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal
private T pendingMetadata; private T pendingMetadata;
/** /**
* @param output The output.
* @param outputLooper The looper associated with the thread on which the output should be
* invoked. If the output makes use of standard Android UI components, then this should
* normally be the looper associated with the application's main thread, which can be obtained
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the output
* should be invoked directly on the player's internal rendering thread.
* @param metadataParser A parser for parsing the metadata. * @param metadataParser A parser for parsing the metadata.
* @param metadataRenderer The metadata renderer to receive the parsed metadata.
* @param metadataRendererLooper The looper associated with the thread on which metadataRenderer
* should be invoked. If the renderer makes use of standard Android UI components, then this
* should normally be the looper associated with the applications' main thread, which can be
* obtained using {@link android.app.Activity#getMainLooper()}. Null may be passed if the
* renderer should be invoked directly on the player's internal rendering thread.
*/ */
public MetadataTrackRenderer(MetadataParser<T> metadataParser, public MetadataRenderer(Output<T> output, Looper outputLooper, MetadataParser<T> metadataParser) {
MetadataRenderer<T> metadataRenderer, Looper metadataRendererLooper) { this.output = Assertions.checkNotNull(output);
this.outputHandler = outputLooper == null ? null : new Handler(outputLooper, this);
this.metadataParser = Assertions.checkNotNull(metadataParser); this.metadataParser = Assertions.checkNotNull(metadataParser);
this.metadataRenderer = Assertions.checkNotNull(metadataRenderer);
this.metadataHandler = metadataRendererLooper == null ? null
: new Handler(metadataRendererLooper, this);
formatHolder = new FormatHolder(); formatHolder = new FormatHolder();
buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL); buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
} }
...@@ -93,8 +91,8 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal ...@@ -93,8 +91,8 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal
@Override @Override
protected int supportsFormat(Format format) { protected int supportsFormat(Format format) {
return metadataParser.canParse(format.sampleMimeType) ? TrackRenderer.FORMAT_HANDLED return metadataParser.canParse(format.sampleMimeType) ? Renderer.FORMAT_HANDLED
: TrackRenderer.FORMAT_UNSUPPORTED_TYPE; : Renderer.FORMAT_UNSUPPORTED_TYPE;
} }
@Override @Override
...@@ -147,8 +145,8 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal ...@@ -147,8 +145,8 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal
} }
private void invokeRenderer(T metadata) { private void invokeRenderer(T metadata) {
if (metadataHandler != null) { if (outputHandler != null) {
metadataHandler.obtainMessage(MSG_INVOKE_RENDERER, metadata).sendToTarget(); outputHandler.obtainMessage(MSG_INVOKE_RENDERER, metadata).sendToTarget();
} else { } else {
invokeRendererInternal(metadata); invokeRendererInternal(metadata);
} }
...@@ -166,7 +164,7 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal ...@@ -166,7 +164,7 @@ public final class MetadataTrackRenderer<T> extends TrackRenderer implements Cal
} }
private void invokeRendererInternal(T metadata) { private void invokeRendererInternal(T metadata) {
metadataRenderer.onMetadata(metadata); output.onMetadata(metadata);
} }
} }
...@@ -15,18 +15,274 @@ ...@@ -15,18 +15,274 @@
*/ */
package com.google.android.exoplayer2.text; package com.google.android.exoplayer2.text;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.TrackStream;
import com.google.android.exoplayer2.extensions.Decoder;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import android.annotation.TargetApi;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Looper;
import android.os.Message;
import java.io.IOException;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
* An interface for components that render text. * A {@link Renderer} for subtitles.
* <p>
* Text is parsed from sample data using {@link Decoder} instances obtained from a
* {@link SubtitleParserFactory}. The actual rendering of each line of text is delegated to a
* {@link Output}.
*/ */
public interface TextRenderer { @TargetApi(16)
public final class TextRenderer extends Renderer implements Callback {
/**
* An output for the renderer.
*/
public interface Output {
/**
* Invoked each time there is a change in the {@link Cue}s.
*
* @param cues The {@link Cue}s.
*/
void onCues(List<Cue> cues);
}
private static final int MSG_UPDATE_OUTPUT = 0;
private final Handler outputHandler;
private final Output output;
private final SubtitleParserFactory parserFactory;
private final FormatHolder formatHolder;
private boolean inputStreamEnded;
private boolean outputStreamEnded;
private SubtitleParser parser;
private SubtitleInputBuffer nextInputBuffer;
private SubtitleOutputBuffer subtitle;
private SubtitleOutputBuffer nextSubtitle;
private int nextSubtitleEventIndex;
/**
* @param output The output.
* @param outputLooper The looper associated with the thread on which the output should be
* invoked. If the output makes use of standard Android UI components, then this should
* normally be the looper associated with the application's main thread, which can be obtained
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the output
* should be invoked directly on the player's internal rendering thread.
*/
public TextRenderer(Output output, Looper outputLooper) {
this(output, outputLooper, SubtitleParserFactory.DEFAULT);
}
/** /**
* Invoked each time there is a change in the {@link Cue}s to be rendered. * @param output The output.
* * @param outputLooper The looper associated with the thread on which the output should be
* @param cues The {@link Cue}s to be rendered, or an empty list if no cues are to be rendered. * invoked. If the output makes use of standard Android UI components, then this should
* normally be the looper associated with the application's main thread, which can be obtained
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the output
* should be invoked directly on the player's internal rendering thread.
* @param parserFactory A factory from which to obtain {@link Decoder} instances.
*/ */
void onCues(List<Cue> cues); public TextRenderer(Output output, Looper outputLooper, SubtitleParserFactory parserFactory) {
this.output = Assertions.checkNotNull(output);
this.outputHandler = outputLooper == null ? null : new Handler(outputLooper, this);
this.parserFactory = parserFactory;
formatHolder = new FormatHolder();
}
@Override
public int getTrackType() {
return C.TRACK_TYPE_TEXT;
}
@Override
protected int supportsFormat(Format format) {
return parserFactory.supportsFormat(format) ? Renderer.FORMAT_HANDLED
: (MimeTypes.isText(format.sampleMimeType) ? FORMAT_UNSUPPORTED_SUBTYPE
: FORMAT_UNSUPPORTED_TYPE);
}
@Override
protected void onStreamChanged(Format[] formats) throws ExoPlaybackException {
if (parser != null) {
parser.release();
}
parser = parserFactory.createParser(formats[0]);
}
@Override
protected void onReset(long positionUs, boolean joining) {
inputStreamEnded = false;
outputStreamEnded = false;
if (subtitle != null) {
subtitle.release();
subtitle = null;
}
if (nextSubtitle != null) {
nextSubtitle.release();
nextSubtitle = null;
}
nextInputBuffer = null;
clearOutput();
parser.flush();
}
@Override
protected void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
if (outputStreamEnded) {
return;
}
if (nextSubtitle == null) {
parser.setPositionUs(positionUs);
try {
nextSubtitle = parser.dequeueOutputBuffer();
} catch (IOException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
if (getState() != Renderer.STATE_STARTED) {
return;
}
boolean textRendererNeedsUpdate = false;
if (subtitle != null) {
// We're iterating through the events in a subtitle. Set textRendererNeedsUpdate if we
// advance to the next event.
long subtitleNextEventTimeUs = getNextEventTime();
while (subtitleNextEventTimeUs <= positionUs) {
nextSubtitleEventIndex++;
subtitleNextEventTimeUs = getNextEventTime();
textRendererNeedsUpdate = true;
}
}
if (nextSubtitle != null && nextSubtitle.timestampUs <= positionUs) {
// Advance to the next subtitle. Sync the next event index and trigger an update.
if (subtitle != null) {
subtitle.release();
}
subtitle = nextSubtitle;
nextSubtitle = null;
if (subtitle.isEndOfStream()) {
outputStreamEnded = true;
subtitle.release();
subtitle = null;
return;
}
nextSubtitleEventIndex = subtitle.getNextEventTimeIndex(positionUs);
textRendererNeedsUpdate = true;
}
if (textRendererNeedsUpdate) {
// textRendererNeedsUpdate is set and we're playing. Update the renderer.
updateOutput(subtitle.getCues(positionUs));
}
try {
while (!inputStreamEnded) {
if (nextInputBuffer == null) {
nextInputBuffer = parser.dequeueInputBuffer();
if (nextInputBuffer == null) {
return;
}
}
// Try and read the next subtitle from the source.
int result = readSource(formatHolder, nextInputBuffer);
if (result == TrackStream.BUFFER_READ) {
// Clear BUFFER_FLAG_DECODE_ONLY (see [Internal: b/27893809]) and queue the buffer.
nextInputBuffer.clearFlag(C.BUFFER_FLAG_DECODE_ONLY);
if (nextInputBuffer.isEndOfStream()) {
inputStreamEnded = true;
} else {
nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
nextInputBuffer.flip();
}
parser.queueInputBuffer(nextInputBuffer);
nextInputBuffer = null;
} else if (result == TrackStream.NOTHING_READ) {
break;
}
}
} catch (ParserException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
@Override
protected void onDisabled() {
if (subtitle != null) {
subtitle.release();
subtitle = null;
}
if (nextSubtitle != null) {
nextSubtitle.release();
nextSubtitle = null;
}
parser.release();
parser = null;
nextInputBuffer = null;
clearOutput();
super.onDisabled();
}
@Override
protected boolean isEnded() {
return outputStreamEnded;
}
@Override
protected boolean isReady() {
// Don't block playback whilst subtitles are loading.
// Note: To change this behavior, it will be necessary to consider [Internal: b/12949941].
return true;
}
private long getNextEventTime() {
return ((nextSubtitleEventIndex == -1)
|| (nextSubtitleEventIndex >= subtitle.getEventTimeCount())) ? Long.MAX_VALUE
: (subtitle.getEventTime(nextSubtitleEventIndex));
}
private void updateOutput(List<Cue> cues) {
if (outputHandler != null) {
outputHandler.obtainMessage(MSG_UPDATE_OUTPUT, cues).sendToTarget();
} else {
invokeUpdateOutputInternal(cues);
}
}
private void clearOutput() {
updateOutput(Collections.<Cue>emptyList());
}
@SuppressWarnings("unchecked")
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_OUTPUT:
invokeUpdateOutputInternal((List<Cue>) msg.obj);
return true;
}
return false;
}
private void invokeUpdateOutputInternal(List<Cue> cues) {
output.onCues(cues);
}
} }
/*
* Copyright (C) 2016 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.exoplayer2.text;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.TrackRenderer;
import com.google.android.exoplayer2.TrackStream;
import com.google.android.exoplayer2.extensions.Decoder;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import android.annotation.TargetApi;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Looper;
import android.os.Message;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
/**
* A {@link TrackRenderer} for subtitles.
* <p>
* Text is parsed from sample data using {@link Decoder} instances obtained from a
* {@link SubtitleParserFactory}. The actual rendering of each line of text is delegated to a
* {@link TextRenderer}.
*/
@TargetApi(16)
public final class TextTrackRenderer extends TrackRenderer implements Callback {
private static final int MSG_UPDATE_OVERLAY = 0;
private final Handler textRendererHandler;
private final TextRenderer textRenderer;
private final SubtitleParserFactory parserFactory;
private final FormatHolder formatHolder;
private boolean inputStreamEnded;
private boolean outputStreamEnded;
private SubtitleParser parser;
private SubtitleInputBuffer nextInputBuffer;
private SubtitleOutputBuffer subtitle;
private SubtitleOutputBuffer nextSubtitle;
private int nextSubtitleEventIndex;
/**
* @param textRenderer The text renderer.
* @param textRendererLooper The looper associated with the thread on which textRenderer should be
* invoked. If the renderer makes use of standard Android UI components, then this should
* normally be the looper associated with the application's main thread, which can be obtained
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the renderer
* should be invoked directly on the player's internal rendering thread.
*/
public TextTrackRenderer(TextRenderer textRenderer, Looper textRendererLooper) {
this(textRenderer, textRendererLooper, SubtitleParserFactory.DEFAULT);
}
/**
* @param textRenderer The text renderer.
* @param textRendererLooper The looper associated with the thread on which textRenderer should be
* invoked. If the renderer makes use of standard Android UI components, then this should
* normally be the looper associated with the application's main thread, which can be obtained
* using {@link android.app.Activity#getMainLooper()}. Null may be passed if the renderer
* should be invoked directly on the player's internal rendering thread.
* @param parserFactory A factory from which to obtain {@link Decoder} instances.
*/
public TextTrackRenderer(TextRenderer textRenderer, Looper textRendererLooper,
SubtitleParserFactory parserFactory) {
this.textRenderer = Assertions.checkNotNull(textRenderer);
this.textRendererHandler = textRendererLooper == null ? null
: new Handler(textRendererLooper, this);
this.parserFactory = parserFactory;
formatHolder = new FormatHolder();
}
@Override
public int getTrackType() {
return C.TRACK_TYPE_TEXT;
}
@Override
protected int supportsFormat(Format format) {
return parserFactory.supportsFormat(format) ? TrackRenderer.FORMAT_HANDLED
: (MimeTypes.isText(format.sampleMimeType) ? FORMAT_UNSUPPORTED_SUBTYPE
: FORMAT_UNSUPPORTED_TYPE);
}
@Override
protected void onStreamChanged(Format[] formats) throws ExoPlaybackException {
if (parser != null) {
parser.release();
}
parser = parserFactory.createParser(formats[0]);
}
@Override
protected void onReset(long positionUs, boolean joining) {
inputStreamEnded = false;
outputStreamEnded = false;
if (subtitle != null) {
subtitle.release();
subtitle = null;
}
if (nextSubtitle != null) {
nextSubtitle.release();
nextSubtitle = null;
}
nextInputBuffer = null;
clearTextRenderer();
parser.flush();
}
@Override
protected void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
if (outputStreamEnded) {
return;
}
if (nextSubtitle == null) {
parser.setPositionUs(positionUs);
try {
nextSubtitle = parser.dequeueOutputBuffer();
} catch (IOException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
if (getState() != TrackRenderer.STATE_STARTED) {
return;
}
boolean textRendererNeedsUpdate = false;
if (subtitle != null) {
// We're iterating through the events in a subtitle. Set textRendererNeedsUpdate if we
// advance to the next event.
long subtitleNextEventTimeUs = getNextEventTime();
while (subtitleNextEventTimeUs <= positionUs) {
nextSubtitleEventIndex++;
subtitleNextEventTimeUs = getNextEventTime();
textRendererNeedsUpdate = true;
}
}
if (nextSubtitle != null && nextSubtitle.timestampUs <= positionUs) {
// Advance to the next subtitle. Sync the next event index and trigger an update.
if (subtitle != null) {
subtitle.release();
}
subtitle = nextSubtitle;
nextSubtitle = null;
if (subtitle.isEndOfStream()) {
outputStreamEnded = true;
subtitle.release();
subtitle = null;
return;
}
nextSubtitleEventIndex = subtitle.getNextEventTimeIndex(positionUs);
textRendererNeedsUpdate = true;
}
if (textRendererNeedsUpdate) {
// textRendererNeedsUpdate is set and we're playing. Update the renderer.
updateTextRenderer(subtitle.getCues(positionUs));
}
try {
while (!inputStreamEnded) {
if (nextInputBuffer == null) {
nextInputBuffer = parser.dequeueInputBuffer();
if (nextInputBuffer == null) {
return;
}
}
// Try and read the next subtitle from the source.
int result = readSource(formatHolder, nextInputBuffer);
if (result == TrackStream.BUFFER_READ) {
// Clear BUFFER_FLAG_DECODE_ONLY (see [Internal: b/27893809]) and queue the buffer.
nextInputBuffer.clearFlag(C.BUFFER_FLAG_DECODE_ONLY);
if (nextInputBuffer.isEndOfStream()) {
inputStreamEnded = true;
} else {
nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
nextInputBuffer.flip();
}
parser.queueInputBuffer(nextInputBuffer);
nextInputBuffer = null;
} else if (result == TrackStream.NOTHING_READ) {
break;
}
}
} catch (ParserException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
}
@Override
protected void onDisabled() {
if (subtitle != null) {
subtitle.release();
subtitle = null;
}
if (nextSubtitle != null) {
nextSubtitle.release();
nextSubtitle = null;
}
parser.release();
parser = null;
nextInputBuffer = null;
clearTextRenderer();
super.onDisabled();
}
@Override
protected boolean isEnded() {
return outputStreamEnded;
}
@Override
protected boolean isReady() {
// Don't block playback whilst subtitles are loading.
// Note: To change this behavior, it will be necessary to consider [Internal: b/12949941].
return true;
}
private long getNextEventTime() {
return ((nextSubtitleEventIndex == -1)
|| (nextSubtitleEventIndex >= subtitle.getEventTimeCount())) ? Long.MAX_VALUE
: (subtitle.getEventTime(nextSubtitleEventIndex));
}
private void updateTextRenderer(List<Cue> cues) {
if (textRendererHandler != null) {
textRendererHandler.obtainMessage(MSG_UPDATE_OVERLAY, cues).sendToTarget();
} else {
invokeRendererInternalCues(cues);
}
}
private void clearTextRenderer() {
updateTextRenderer(Collections.<Cue>emptyList());
}
@SuppressWarnings("unchecked")
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_OVERLAY:
invokeRendererInternalCues((List<Cue>) msg.obj);
return true;
}
return false;
}
private void invokeRendererInternalCues(List<Cue> cues) {
textRenderer.onCues(cues);
}
}
...@@ -147,7 +147,7 @@ import java.util.regex.Pattern; ...@@ -147,7 +147,7 @@ import java.util.regex.Pattern;
* @param id Id of the cue, {@code null} if it is not present. * @param id Id of the cue, {@code null} if it is not present.
* @param markup The markup text to be parsed. * @param markup The markup text to be parsed.
* @param styles List of styles defined by the CSS style blocks preceeding the cues. * @param styles List of styles defined by the CSS style blocks preceeding the cues.
* @param builder Target builder. * @param builder Output builder.
*/ */
/* package */ static void parseCueText(String id, String markup, WebvttCue.Builder builder, /* package */ static void parseCueText(String id, String markup, WebvttCue.Builder builder,
List<WebvttCssStyle> styles) { List<WebvttCssStyle> styles) {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.util; package com.google.android.exoplayer2.util;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaCodecAudioRenderer;
import android.widget.MediaController.MediaPlayerControl; import android.widget.MediaController.MediaPlayerControl;
...@@ -52,9 +53,8 @@ public class PlayerControl implements MediaPlayerControl { ...@@ -52,9 +53,8 @@ public class PlayerControl implements MediaPlayerControl {
* This is an unsupported operation. * This is an unsupported operation.
* <p> * <p>
* Application of audio effects is dependent on the audio renderer used. When using * Application of audio effects is dependent on the audio renderer used. When using
* {@link com.google.android.exoplayer2.MediaCodecAudioTrackRenderer}, the recommended approach is * {@link MediaCodecAudioRenderer}, the recommended approach is to extend the class and override
* to extend the class and override * {@link MediaCodecAudioRenderer#onAudioSessionId}.
* {@link com.google.android.exoplayer2.MediaCodecAudioTrackRenderer#onAudioSessionId}.
* *
* @throws UnsupportedOperationException Always thrown. * @throws UnsupportedOperationException Always thrown.
*/ */
......
...@@ -23,9 +23,9 @@ import com.google.android.exoplayer2.ExoPlayer; ...@@ -23,9 +23,9 @@ import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaCodecUtil; import com.google.android.exoplayer2.MediaCodecUtil;
import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.MediaSource; import com.google.android.exoplayer2.MediaSource;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.TrackGroup; import com.google.android.exoplayer2.TrackGroup;
import com.google.android.exoplayer2.TrackGroupArray; import com.google.android.exoplayer2.TrackGroupArray;
import com.google.android.exoplayer2.TrackRenderer;
import com.google.android.exoplayer2.TrackSelection; import com.google.android.exoplayer2.TrackSelection;
import com.google.android.exoplayer2.TrackSelectionPolicy; import com.google.android.exoplayer2.TrackSelectionPolicy;
import com.google.android.exoplayer2.dash.DashMediaSource; import com.google.android.exoplayer2.dash.DashMediaSource;
...@@ -444,7 +444,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -444,7 +444,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
// We shouldn't have skipped any output buffers. // We shouldn't have skipped any output buffers.
CodecCountersUtil.assertSkippedOutputBufferCount(AUDIO_TAG, audioCounters, 0); CodecCountersUtil.assertSkippedOutputBufferCount(AUDIO_TAG, audioCounters, 0);
CodecCountersUtil.assertSkippedOutputBufferCount(VIDEO_TAG, videoCounters, 0); CodecCountersUtil.assertSkippedOutputBufferCount(VIDEO_TAG, videoCounters, 0);
// We allow one fewer output buffer due to the way that MediaCodecTrackRenderer and the // We allow one fewer output buffer due to the way that MediaCodecRenderer and the
// underlying decoders handle the end of stream. This should be tightened up in the future. // underlying decoders handle the end of stream. This should be tightened up in the future.
CodecCountersUtil.assertTotalOutputBufferCount(AUDIO_TAG, audioCounters, CodecCountersUtil.assertTotalOutputBufferCount(AUDIO_TAG, audioCounters,
audioCounters.inputBufferCount - 1, audioCounters.inputBufferCount); audioCounters.inputBufferCount - 1, audioCounters.inputBufferCount);
...@@ -490,7 +490,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -490,7 +490,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
@Override @Override
protected TrackSelection[] selectTracks(TrackRenderer[] renderers, protected TrackSelection[] selectTracks(Renderer[] renderers,
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports) TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports)
throws ExoPlaybackException { throws ExoPlaybackException {
Assertions.checkState(renderers[VIDEO_RENDERER_INDEX].getTrackType() == C.TRACK_TYPE_VIDEO); Assertions.checkState(renderers[VIDEO_RENDERER_INDEX].getTrackType() == C.TRACK_TYPE_VIDEO);
...@@ -531,8 +531,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -531,8 +531,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
// Select additional video representations, if supported by the device. // Select additional video representations, if supported by the device.
if (canIncludeAdditionalFormats) { if (canIncludeAdditionalFormats) {
for (int i = 0; i < trackGroup.length; i++) { for (int i = 0; i < trackGroup.length; i++) {
if (!trackIndices.contains(i) && (formatSupport[i] & TrackRenderer.FORMAT_SUPPORT_MASK) if (!trackIndices.contains(i) && (formatSupport[i] & Renderer.FORMAT_SUPPORT_MASK)
== TrackRenderer.FORMAT_HANDLED) { == Renderer.FORMAT_HANDLED) {
Log.d(TAG, "Adding video format: " + trackGroup.getFormat(i).id); Log.d(TAG, "Adding video format: " + trackGroup.getFormat(i).id);
trackIndices.add(i); trackIndices.add(i);
} }
......
...@@ -18,19 +18,19 @@ package com.google.android.exoplayer2.playbacktests.util; ...@@ -18,19 +18,19 @@ package com.google.android.exoplayer2.playbacktests.util;
import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.DecoderInputBuffer;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.MediaCodecSelector; import com.google.android.exoplayer2.MediaCodecSelector;
import com.google.android.exoplayer2.MediaCodecVideoTrackRenderer; import com.google.android.exoplayer2.MediaCodecVideoRenderer;
import com.google.android.exoplayer2.VideoTrackRendererEventListener; import com.google.android.exoplayer2.VideoRendererEventListener;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.os.Handler; import android.os.Handler;
/** /**
* Decodes and renders video using {@link MediaCodecVideoTrackRenderer}. Provides buffer timestamp * Decodes and renders video using {@link MediaCodecVideoRenderer}. Provides buffer timestamp
* assertions. * assertions.
*/ */
@TargetApi(16) @TargetApi(16)
public class DebugMediaCodecVideoTrackRenderer extends MediaCodecVideoTrackRenderer { public class DebugMediaCodecVideoRenderer extends MediaCodecVideoRenderer {
private static final int ARRAY_SIZE = 1000; private static final int ARRAY_SIZE = 1000;
...@@ -40,9 +40,9 @@ public class DebugMediaCodecVideoTrackRenderer extends MediaCodecVideoTrackRende ...@@ -40,9 +40,9 @@ public class DebugMediaCodecVideoTrackRenderer extends MediaCodecVideoTrackRende
private int queueSize; private int queueSize;
private int bufferCount; private int bufferCount;
public DebugMediaCodecVideoTrackRenderer(Context context, MediaCodecSelector mediaCodecSelector, public DebugMediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector,
int videoScalingMode, long allowedJoiningTimeMs, Handler eventHandler, int videoScalingMode, long allowedJoiningTimeMs, Handler eventHandler,
VideoTrackRendererEventListener eventListener, int maxDroppedFrameCountToNotify) { VideoRendererEventListener eventListener, int maxDroppedFrameCountToNotify) {
super(context, mediaCodecSelector, videoScalingMode, allowedJoiningTimeMs, null, false, super(context, mediaCodecSelector, videoScalingMode, allowedJoiningTimeMs, null, false,
eventHandler, eventListener, maxDroppedFrameCountToNotify); eventHandler, eventListener, maxDroppedFrameCountToNotify);
startIndex = 0; startIndex = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment