diff --git a/demo/src/main/java/com/google/android/exoplayer2/demo/EventLogger.java b/demo/src/main/java/com/google/android/exoplayer2/demo/EventLogger.java index 7a6e68c169..5c741cb2bf 100644 --- a/demo/src/main/java/com/google/android/exoplayer2/demo/EventLogger.java +++ b/demo/src/main/java/com/google/android/exoplayer2/demo/EventLogger.java @@ -15,12 +15,12 @@ */ package com.google.android.exoplayer2.demo; -import com.google.android.exoplayer2.CodecCounters; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.drm.StreamingDrmSessionManager; import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener; import com.google.android.exoplayer2.source.ExtractorMediaSource; @@ -145,7 +145,7 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb // SimpleExoPlayer.DebugListener @Override - public void onAudioEnabled(CodecCounters counters) { + public void onAudioEnabled(DecoderCounters counters) { Log.d(TAG, "audioEnabled [" + getSessionTimeString() + "]"); } @@ -167,12 +167,12 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb } @Override - public void onAudioDisabled(CodecCounters counters) { + public void onAudioDisabled(DecoderCounters counters) { Log.d(TAG, "audioDisabled [" + getSessionTimeString() + "]"); } @Override - public void onVideoEnabled(CodecCounters counters) { + public void onVideoEnabled(DecoderCounters counters) { Log.d(TAG, "videoEnabled [" + getSessionTimeString() + "]"); } @@ -189,7 +189,7 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb } @Override - public void onVideoDisabled(CodecCounters counters) { + public void onVideoDisabled(DecoderCounters counters) { Log.d(TAG, "videoDisabled [" + getSessionTimeString() + "]"); } diff --git a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index 049bb77236..6dbf4e85c6 100644 --- a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -20,13 +20,13 @@ import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayerFactory; -import com.google.android.exoplayer2.MediaCodecRenderer.DecoderInitializationException; -import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.StreamingDrmSessionManager; import com.google.android.exoplayer2.drm.UnsupportedDrmException; import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; +import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException; +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.metadata.id3.ApicFrame; import com.google.android.exoplayer2.metadata.id3.GeobFrame; import com.google.android.exoplayer2.metadata.id3.Id3Frame; @@ -52,7 +52,7 @@ import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.DataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; -import com.google.android.exoplayer2.util.DebugTextViewHelper; +import com.google.android.exoplayer2.ui.DebugTextViewHelper; import com.google.android.exoplayer2.util.Util; import android.Manifest.permission; diff --git a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioRenderer.java b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioRenderer.java index e7062a7046..3a19a348e0 100644 --- a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioRenderer.java +++ b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioRenderer.java @@ -15,12 +15,12 @@ */ package com.google.android.exoplayer2.ext.ffmpeg; -import com.google.android.exoplayer2.AudioRendererEventListener; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.audio.AudioCapabilities; +import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioTrack; -import com.google.android.exoplayer2.extensions.AudioDecoderRenderer; +import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer; import com.google.android.exoplayer2.util.MimeTypes; import android.os.Handler; @@ -28,7 +28,7 @@ import android.os.Handler; /** * Decodes and renders audio using FFmpeg. */ -public final class FfmpegAudioRenderer extends AudioDecoderRenderer { +public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer { private static final int NUM_BUFFERS = 16; private static final int INITIAL_INPUT_BUFFER_SIZE = 960 * 6; diff --git a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegDecoder.java b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegDecoder.java index 376385226f..994b06244f 100644 --- a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegDecoder.java +++ b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegDecoder.java @@ -15,9 +15,9 @@ */ package com.google.android.exoplayer2.ext.ffmpeg; -import com.google.android.exoplayer2.DecoderInputBuffer; -import com.google.android.exoplayer2.extensions.SimpleDecoder; -import com.google.android.exoplayer2.extensions.SimpleOutputBuffer; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; +import com.google.android.exoplayer2.decoder.SimpleDecoder; +import com.google.android.exoplayer2.decoder.SimpleOutputBuffer; import com.google.android.exoplayer2.util.MimeTypes; import java.nio.ByteBuffer; diff --git a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegDecoderException.java b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegDecoderException.java index a00c1f9c12..b4cf327198 100644 --- a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegDecoderException.java +++ b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegDecoderException.java @@ -15,7 +15,7 @@ */ package com.google.android.exoplayer2.ext.ffmpeg; -import com.google.android.exoplayer2.extensions.AudioDecoderException; +import com.google.android.exoplayer2.audio.AudioDecoderException; /** * Thrown when an FFmpeg decoder error occurs. diff --git a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java index fe99a1fe9c..91f7f6b304 100644 --- a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java +++ b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java @@ -15,9 +15,9 @@ */ package com.google.android.exoplayer2.ext.flac; -import com.google.android.exoplayer2.DecoderInputBuffer; -import com.google.android.exoplayer2.extensions.SimpleDecoder; -import com.google.android.exoplayer2.extensions.SimpleOutputBuffer; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; +import com.google.android.exoplayer2.decoder.SimpleDecoder; +import com.google.android.exoplayer2.decoder.SimpleOutputBuffer; import com.google.android.exoplayer2.util.FlacStreamInfo; import java.io.IOException; diff --git a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderException.java b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderException.java index 384343cd9d..2bdff62935 100644 --- a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderException.java +++ b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderException.java @@ -15,7 +15,7 @@ */ package com.google.android.exoplayer2.ext.flac; -import com.google.android.exoplayer2.extensions.AudioDecoderException; +import com.google.android.exoplayer2.audio.AudioDecoderException; /** * Thrown when an Flac decoder error occurs. diff --git a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java index 728f64bbc9..0bbd9178a3 100644 --- a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java +++ b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java @@ -15,11 +15,11 @@ */ package com.google.android.exoplayer2.ext.flac; -import com.google.android.exoplayer2.AudioRendererEventListener; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.audio.AudioCapabilities; +import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioTrack; -import com.google.android.exoplayer2.extensions.AudioDecoderRenderer; +import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer; import com.google.android.exoplayer2.util.MimeTypes; import android.os.Handler; @@ -27,7 +27,7 @@ import android.os.Handler; /** * Decodes and renders audio using the native Flac decoder. */ -public class LibflacAudioRenderer extends AudioDecoderRenderer { +public class LibflacAudioRenderer extends SimpleDecoderAudioRenderer { private static final int NUM_BUFFERS = 16; diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/LibopusAudioRenderer.java b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/LibopusAudioRenderer.java index 9f7c8780a5..c51045cca7 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/LibopusAudioRenderer.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/LibopusAudioRenderer.java @@ -15,11 +15,11 @@ */ package com.google.android.exoplayer2.ext.opus; -import com.google.android.exoplayer2.AudioRendererEventListener; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.audio.AudioCapabilities; +import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioTrack; -import com.google.android.exoplayer2.extensions.AudioDecoderRenderer; +import com.google.android.exoplayer2.audio.SimpleDecoderAudioRenderer; import com.google.android.exoplayer2.util.MimeTypes; import android.os.Handler; @@ -27,7 +27,7 @@ import android.os.Handler; /** * Decodes and renders audio using the native Opus decoder. */ -public final class LibopusAudioRenderer extends AudioDecoderRenderer { +public final class LibopusAudioRenderer extends SimpleDecoderAudioRenderer { private static final int NUM_BUFFERS = 16; private static final int INITIAL_INPUT_BUFFER_SIZE = 960 * 6; diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java index f9bbdefeb5..51007adcd5 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java @@ -16,9 +16,9 @@ package com.google.android.exoplayer2.ext.opus; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; -import com.google.android.exoplayer2.extensions.SimpleDecoder; -import com.google.android.exoplayer2.extensions.SimpleOutputBuffer; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; +import com.google.android.exoplayer2.decoder.SimpleDecoder; +import com.google.android.exoplayer2.decoder.SimpleOutputBuffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoderException.java b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoderException.java index 8eb4473e6e..338f3ea94e 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoderException.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoderException.java @@ -15,7 +15,7 @@ */ package com.google.android.exoplayer2.ext.opus; -import com.google.android.exoplayer2.extensions.AudioDecoderException; +import com.google.android.exoplayer2.audio.AudioDecoderException; /** * Thrown when an Opus decoder error occurs. diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java index bc3ecad6de..5a2bfb14f4 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java @@ -16,17 +16,17 @@ package com.google.android.exoplayer2.ext.vp9; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.CodecCounters; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.Renderer; -import com.google.android.exoplayer2.VideoRendererEventListener; -import com.google.android.exoplayer2.VideoRendererEventListener.EventDispatcher; +import com.google.android.exoplayer2.decoder.DecoderCounters; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.TraceUtil; +import com.google.android.exoplayer2.video.VideoRendererEventListener; +import com.google.android.exoplayer2.video.VideoRendererEventListener.EventDispatcher; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -60,7 +60,7 @@ public final class LibvpxVideoRenderer extends Renderer { private final EventDispatcher eventDispatcher; private final FormatHolder formatHolder; - private CodecCounters codecCounters; + private DecoderCounters decoderCounters; private Format format; private VpxDecoder decoder; private DecoderInputBuffer inputBuffer; @@ -172,7 +172,7 @@ public final class LibvpxVideoRenderer extends Renderer { long codecInitializedTimestamp = SystemClock.elapsedRealtime(); eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp, codecInitializedTimestamp - codecInitializingTimestamp); - codecCounters.codecInitCount++; + decoderCounters.codecInitCount++; } TraceUtil.beginSection("drainAndFeed"); while (drainOutputBuffer(positionUs)) {} @@ -181,7 +181,7 @@ public final class LibvpxVideoRenderer extends Renderer { } catch (VpxDecoderException e) { throw ExoPlaybackException.createForRenderer(e, getIndex()); } - codecCounters.ensureUpdated(); + decoderCounters.ensureUpdated(); } private boolean drainOutputBuffer(long positionUs) throws VpxDecoderException { @@ -200,7 +200,7 @@ public final class LibvpxVideoRenderer extends Renderer { if (outputBuffer == null) { return false; } - codecCounters.skippedOutputBufferCount += outputBuffer.skippedOutputBufferCount; + decoderCounters.skippedOutputBufferCount += outputBuffer.skippedOutputBufferCount; } if (nextOutputBuffer == null) { @@ -219,11 +219,12 @@ public final class LibvpxVideoRenderer extends Renderer { if ((joiningDeadlineMs != -1 && outputBuffer.timestampUs < positionUs - 30000) || (nextOutputBuffer != null && !nextOutputBuffer.isEndOfStream() && nextOutputBuffer.timestampUs < positionUs)) { - codecCounters.droppedOutputBufferCount++; + decoderCounters.droppedOutputBufferCount++; droppedFrameCount++; consecutiveDroppedFrameCount++; - codecCounters.maxConsecutiveDroppedOutputBufferCount = Math.max(consecutiveDroppedFrameCount, - codecCounters.maxConsecutiveDroppedOutputBufferCount); + decoderCounters.maxConsecutiveDroppedOutputBufferCount = Math.max( + consecutiveDroppedFrameCount, + decoderCounters.maxConsecutiveDroppedOutputBufferCount); if (droppedFrameCount == maxDroppedFrameCountToNotify) { maybeNotifyDroppedFrameCount(); } @@ -248,7 +249,7 @@ public final class LibvpxVideoRenderer extends Renderer { } private void renderBuffer() { - codecCounters.renderedOutputBufferCount++; + decoderCounters.renderedOutputBufferCount++; consecutiveDroppedFrameCount = 0; maybeNotifyVideoSizeChanged(outputBuffer.width, outputBuffer.height); if (outputBuffer.mode == VpxDecoder.OUTPUT_MODE_RGB && surface != null) { @@ -310,7 +311,7 @@ public final class LibvpxVideoRenderer extends Renderer { } inputBuffer.flip(); decoder.queueInputBuffer(inputBuffer); - codecCounters.inputBufferCount++; + decoderCounters.inputBufferCount++; inputBuffer = null; return true; } @@ -354,8 +355,8 @@ public final class LibvpxVideoRenderer extends Renderer { @Override protected void onEnabled(boolean joining) throws ExoPlaybackException { - codecCounters = new CodecCounters(); - eventDispatcher.enabled(codecCounters); + decoderCounters = new DecoderCounters(); + eventDispatcher.enabled(decoderCounters); } @Override @@ -392,11 +393,11 @@ public final class LibvpxVideoRenderer extends Renderer { if (decoder != null) { decoder.release(); decoder = null; - codecCounters.codecReleaseCount++; + decoderCounters.codecReleaseCount++; } } finally { - codecCounters.ensureUpdated(); - eventDispatcher.disabled(codecCounters); + decoderCounters.ensureUpdated(); + eventDispatcher.disabled(decoderCounters); } } diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java index 2c3eecdca9..2e30cc6e11 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java @@ -16,8 +16,8 @@ package com.google.android.exoplayer2.ext.vp9; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; -import com.google.android.exoplayer2.extensions.SimpleDecoder; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; +import com.google.android.exoplayer2.decoder.SimpleDecoder; import java.nio.ByteBuffer; diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxOutputBuffer.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxOutputBuffer.java index 72adce8fcc..18c8261eb9 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxOutputBuffer.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxOutputBuffer.java @@ -15,7 +15,7 @@ */ package com.google.android.exoplayer2.ext.vp9; -import com.google.android.exoplayer2.extensions.OutputBuffer; +import com.google.android.exoplayer2.decoder.OutputBuffer; import java.nio.ByteBuffer; diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/extractor/mp3/XingSeekerTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/extractor/mp3/XingSeekerTest.java index 4166fe896d..592d250030 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/extractor/mp3/XingSeekerTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/extractor/mp3/XingSeekerTest.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer2.extractor.mp3; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.util.MpegAudioHeader; +import com.google.android.exoplayer2.extractor.MpegAudioHeader; import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.Util; diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/Id3ParserTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/Id3DecoderTest.java similarity index 76% rename from library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/Id3ParserTest.java rename to library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/Id3DecoderTest.java index 0fc7d48135..c0fa6abc54 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/Id3ParserTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/metadata/id3/Id3DecoderTest.java @@ -15,36 +15,37 @@ */ package com.google.android.exoplayer2.metadata.id3; -import com.google.android.exoplayer2.ParserException; +import com.google.android.exoplayer2.metadata.MetadataDecoderException; import android.test.MoreAsserts; + import junit.framework.TestCase; import java.util.List; /** - * Test for {@link Id3Parser} + * Test for {@link Id3Decoder} */ -public class Id3ParserTest extends TestCase { +public class Id3DecoderTest extends TestCase { - public void testParseTxxxFrame() throws ParserException { + public void testDecodeTxxxFrame() throws MetadataDecoderException { byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 41, 84, 88, 88, 88, 0, 0, 0, 31, 0, 0, 3, 0, 109, 100, 105, 97, 108, 111, 103, 95, 86, 73, 78, 68, 73, 67, 79, 49, 53, 50, 55, 54, 54, 52, 95, 115, 116, 97, 114, 116, 0}; - Id3Parser parser = new Id3Parser(); - List id3Frames = parser.parse(rawId3, rawId3.length); + Id3Decoder decoder = new Id3Decoder(); + List id3Frames = decoder.decode(rawId3, rawId3.length); assertEquals(1, id3Frames.size()); TxxxFrame txxxFrame = (TxxxFrame) id3Frames.get(0); assertEquals("", txxxFrame.description); assertEquals("mdialog_VINDICO1527664_start", txxxFrame.value); } - public void testParseApicFrame() throws ParserException { + public void testDecodeApicFrame() throws MetadataDecoderException { byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 45, 65, 80, 73, 67, 0, 0, 0, 35, 0, 0, 3, 105, 109, 97, 103, 101, 47, 106, 112, 101, 103, 0, 16, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; - Id3Parser parser = new Id3Parser(); - List id3Frames = parser.parse(rawId3, rawId3.length); + Id3Decoder decoder = new Id3Decoder(); + List id3Frames = decoder.decode(rawId3, rawId3.length); assertEquals(1, id3Frames.size()); ApicFrame apicFrame = (ApicFrame) id3Frames.get(0); assertEquals("image/jpeg", apicFrame.mimeType); @@ -54,11 +55,11 @@ public class Id3ParserTest extends TestCase { MoreAsserts.assertEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, apicFrame.pictureData); } - public void testParseTextInformationFrame() throws ParserException { + public void testDecodeTextInformationFrame() throws MetadataDecoderException { byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 23, 84, 73, 84, 50, 0, 0, 0, 13, 0, 0, 3, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0}; - Id3Parser parser = new Id3Parser(); - List id3Frames = parser.parse(rawId3, rawId3.length); + Id3Decoder decoder = new Id3Decoder(); + List id3Frames = decoder.decode(rawId3, rawId3.length); assertEquals(1, id3Frames.size()); TextInformationFrame textInformationFrame = (TextInformationFrame) id3Frames.get(0); assertEquals("TIT2", textInformationFrame.id); diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/text/subrip/SubripParserTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/text/subrip/SubripDecoderTest.java similarity index 78% rename from library/src/androidTest/java/com/google/android/exoplayer2/text/subrip/SubripParserTest.java rename to library/src/androidTest/java/com/google/android/exoplayer2/text/subrip/SubripDecoderTest.java index b1861c7bbe..dddf9281c3 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/text/subrip/SubripParserTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/text/subrip/SubripDecoderTest.java @@ -22,9 +22,9 @@ import android.test.InstrumentationTestCase; import java.io.IOException; /** - * Unit test for {@link SubripParser}. + * Unit test for {@link SubripDecoder}. */ -public final class SubripParserTest extends InstrumentationTestCase { +public final class SubripDecoderTest extends InstrumentationTestCase { private static final String EMPTY_FILE = "subrip/empty"; private static final String TYPICAL_FILE = "subrip/typical"; @@ -34,69 +34,69 @@ public final class SubripParserTest extends InstrumentationTestCase { private static final String TYPICAL_MISSING_SEQUENCE = "subrip/typical_missing_sequence"; private static final String NO_END_TIMECODES_FILE = "subrip/no_end_timecodes"; - public void testParseEmpty() throws IOException { - SubripParser parser = new SubripParser(); + public void testDecodeEmpty() throws IOException { + SubripDecoder decoder = new SubripDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), EMPTY_FILE); - SubripSubtitle subtitle = parser.decode(bytes, bytes.length); + SubripSubtitle subtitle = decoder.decode(bytes, bytes.length); // Assert that the subtitle is empty. assertEquals(0, subtitle.getEventTimeCount()); assertTrue(subtitle.getCues(0).isEmpty()); } - public void testParseTypical() throws IOException { - SubripParser parser = new SubripParser(); + public void testDecodeTypical() throws IOException { + SubripDecoder decoder = new SubripDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_FILE); - SubripSubtitle subtitle = parser.decode(bytes, bytes.length); + SubripSubtitle subtitle = decoder.decode(bytes, bytes.length); assertEquals(6, subtitle.getEventTimeCount()); assertTypicalCue1(subtitle, 0); assertTypicalCue2(subtitle, 2); assertTypicalCue3(subtitle, 4); } - public void testParseTypicalWithByteOrderMark() throws IOException { - SubripParser parser = new SubripParser(); + public void testDecodeTypicalWithByteOrderMark() throws IOException { + SubripDecoder decoder = new SubripDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_WITH_BYTE_ORDER_MARK); - SubripSubtitle subtitle = parser.decode(bytes, bytes.length); + SubripSubtitle subtitle = decoder.decode(bytes, bytes.length); assertEquals(6, subtitle.getEventTimeCount()); assertTypicalCue1(subtitle, 0); assertTypicalCue2(subtitle, 2); assertTypicalCue3(subtitle, 4); } - public void testParseTypicalExtraBlankLine() throws IOException { - SubripParser parser = new SubripParser(); + public void testDecodeTypicalExtraBlankLine() throws IOException { + SubripDecoder decoder = new SubripDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_EXTRA_BLANK_LINE); - SubripSubtitle subtitle = parser.decode(bytes, bytes.length); + SubripSubtitle subtitle = decoder.decode(bytes, bytes.length); assertEquals(6, subtitle.getEventTimeCount()); assertTypicalCue1(subtitle, 0); assertTypicalCue2(subtitle, 2); assertTypicalCue3(subtitle, 4); } - public void testParseTypicalMissingTimecode() throws IOException { + public void testDecodeTypicalMissingTimecode() throws IOException { // Parsing should succeed, parsing the first and third cues only. - SubripParser parser = new SubripParser(); + SubripDecoder decoder = new SubripDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_MISSING_TIMECODE); - SubripSubtitle subtitle = parser.decode(bytes, bytes.length); + SubripSubtitle subtitle = decoder.decode(bytes, bytes.length); assertEquals(4, subtitle.getEventTimeCount()); assertTypicalCue1(subtitle, 0); assertTypicalCue3(subtitle, 2); } - public void testParseTypicalMissingSequence() throws IOException { + public void testDecodeTypicalMissingSequence() throws IOException { // Parsing should succeed, parsing the first and third cues only. - SubripParser parser = new SubripParser(); + SubripDecoder decoder = new SubripDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_MISSING_SEQUENCE); - SubripSubtitle subtitle = parser.decode(bytes, bytes.length); + SubripSubtitle subtitle = decoder.decode(bytes, bytes.length); assertEquals(4, subtitle.getEventTimeCount()); assertTypicalCue1(subtitle, 0); assertTypicalCue3(subtitle, 2); } - public void testParseNoEndTimecodes() throws IOException { - SubripParser parser = new SubripParser(); + public void testDecodeNoEndTimecodes() throws IOException { + SubripDecoder decoder = new SubripDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), NO_END_TIMECODES_FILE); - SubripSubtitle subtitle = parser.decode(bytes, bytes.length); + SubripSubtitle subtitle = decoder.decode(bytes, bytes.length); // Test event count. assertEquals(3, subtitle.getEventTimeCount()); diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/text/ttml/TtmlParserTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/text/ttml/TtmlDecoderTest.java similarity index 92% rename from library/src/androidTest/java/com/google/android/exoplayer2/text/ttml/TtmlParserTest.java rename to library/src/androidTest/java/com/google/android/exoplayer2/text/ttml/TtmlDecoderTest.java index 5e9eeb7703..adf7bfab21 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/text/ttml/TtmlParserTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/text/ttml/TtmlDecoderTest.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.text.ttml; import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.text.Cue; +import com.google.android.exoplayer2.text.TextDecoderException; import com.google.android.exoplayer2.util.ColorParser; import android.test.InstrumentationTestCase; @@ -38,9 +39,9 @@ import java.util.List; import java.util.Map; /** - * Unit test for {@link TtmlParser}. + * Unit test for {@link TtmlDecoder}. */ -public final class TtmlParserTest extends InstrumentationTestCase { +public final class TtmlDecoderTest extends InstrumentationTestCase { private static final String INLINE_ATTRIBUTES_TTML_FILE = "ttml/inline_style_attributes.xml"; private static final String INHERIT_STYLE_TTML_FILE = "ttml/inherit_style.xml"; @@ -60,7 +61,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { private static final String FONT_SIZE_EMPTY_TTML_FILE = "ttml/font_size_empty.xml"; private static final String FRAME_RATE_TTML_FILE = "ttml/frame_rate.xml"; - public void testInlineAttributes() throws IOException { + public void testInlineAttributes() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE); assertEquals(4, subtitle.getEventTimeCount()); @@ -76,7 +77,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertTrue(firstPStyle.isUnderline()); } - public void testInheritInlineAttributes() throws IOException { + public void testInheritInlineAttributes() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE); assertEquals(4, subtitle.getEventTimeCount()); assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC, @@ -94,21 +95,22 @@ public final class TtmlParserTest extends InstrumentationTestCase { * Kitkat Color * @throws IOException thrown if reading subtitle file fails. */ - public void testLime() throws IOException { + public void testLime() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE); assertEquals(4, subtitle.getEventTimeCount()); assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC, 0xFF00FFFF, 0xFF00FF00, false, true, null); } - public void testInheritGlobalStyle() throws IOException { + public void testInheritGlobalStyle() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_STYLE_TTML_FILE); assertEquals(2, subtitle.getEventTimeCount()); assertSpans(subtitle, 10, "text 1", "serif", TtmlStyle.STYLE_BOLD_ITALIC, 0xFF0000FF, 0xFFFFFF00, true, false, null); } - public void testInheritGlobalStyleOverriddenByInlineAttributes() throws IOException { + public void testInheritGlobalStyleOverriddenByInlineAttributes() throws IOException, + TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_STYLE_OVERRIDE_TTML_FILE); assertEquals(4, subtitle.getEventTimeCount()); @@ -118,7 +120,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { true, false, null); } - public void testInheritGlobalAndParent() throws IOException { + public void testInheritGlobalAndParent() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_GLOBAL_AND_PARENT_TTML_FILE); assertEquals(4, subtitle.getEventTimeCount()); @@ -128,28 +130,29 @@ public final class TtmlParserTest extends InstrumentationTestCase { 0xFFFFFF00, true, true, Layout.Alignment.ALIGN_CENTER); } - public void testInheritMultipleStyles() throws IOException { + public void testInheritMultipleStyles() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE); assertEquals(12, subtitle.getEventTimeCount()); assertSpans(subtitle, 10, "text 1", "sansSerif", TtmlStyle.STYLE_BOLD_ITALIC, 0xFF0000FF, 0xFFFFFF00, false, true, null); } - public void testInheritMultipleStylesWithoutLocalAttributes() throws IOException { + public void testInheritMultipleStylesWithoutLocalAttributes() throws IOException, + TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE); assertEquals(12, subtitle.getEventTimeCount()); assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_BOLD_ITALIC, 0xFF0000FF, 0xFF000000, false, true, null); } - public void testMergeMultipleStylesWithParentStyle() throws IOException { + public void testMergeMultipleStylesWithParentStyle() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE); assertEquals(12, subtitle.getEventTimeCount()); assertSpans(subtitle, 30, "text 2.5", "sansSerifInline", TtmlStyle.STYLE_ITALIC, 0xFFFF0000, 0xFFFFFF00, true, true, null); } - public void testMultipleRegions() throws IOException { + public void testMultipleRegions() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(MULTIPLE_REGIONS_TTML_FILE); List output = subtitle.getCues(1000000); assertEquals(2, output.size()); @@ -199,7 +202,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertEquals(45.f / 100.f, ttmlCue.line); } - public void testEmptyStyleAttribute() throws IOException { + public void testEmptyStyleAttribute() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE); assertEquals(12, subtitle.getEventTimeCount()); @@ -210,7 +213,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertNull(queryChildrenForTag(fourthDiv, TtmlNode.TAG_P, 0).getStyleIds()); } - public void testNonexistingStyleId() throws IOException { + public void testNonexistingStyleId() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE); assertEquals(12, subtitle.getEventTimeCount()); @@ -221,7 +224,8 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertEquals(1, queryChildrenForTag(fifthDiv, TtmlNode.TAG_P, 0).getStyleIds().length); } - public void testNonExistingAndExistingStyleIdWithRedundantSpaces() throws IOException { + public void testNonExistingAndExistingStyleIdWithRedundantSpaces() throws IOException, + TextDecoderException { TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE); assertEquals(12, subtitle.getEventTimeCount()); @@ -233,7 +237,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertEquals(2, styleIds.length); } - public void testMultipleChaining() throws IOException { + public void testMultipleChaining() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(CHAIN_MULTIPLE_STYLES_TTML_FILE); assertEquals(2, subtitle.getEventTimeCount()); @@ -255,7 +259,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertTrue(style.isLinethrough()); } - public void testNoUnderline() throws IOException { + public void testNoUnderline() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(NO_UNDERLINE_LINETHROUGH_TTML_FILE); assertEquals(4, subtitle.getEventTimeCount()); @@ -267,7 +271,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertFalse("noUnderline from inline attribute expected", style.isUnderline()); } - public void testNoLinethrough() throws IOException { + public void testNoLinethrough() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(NO_UNDERLINE_LINETHROUGH_TTML_FILE); assertEquals(4, subtitle.getEventTimeCount()); @@ -280,7 +284,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { style.isLinethrough()); } - public void testFontSizeSpans() throws IOException { + public void testFontSizeSpans() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(FONT_SIZE_TTML_FILE); assertEquals(10, subtitle.getEventTimeCount()); @@ -315,7 +319,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertRelativeFontSize(spannable, 0.5f); } - public void testFontSizeWithMissingUnitIsIgnored() throws IOException { + public void testFontSizeWithMissingUnitIsIgnored() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(FONT_SIZE_MISSING_UNIT_TTML_FILE); assertEquals(2, subtitle.getEventTimeCount()); List cues = subtitle.getCues(10 * 1000000); @@ -326,7 +330,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertEquals(0, spannable.getSpans(0, spannable.length(), AbsoluteSizeSpan.class).length); } - public void testFontSizeWithInvalidValueIsIgnored() throws IOException { + public void testFontSizeWithInvalidValueIsIgnored() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(FONT_SIZE_INVALID_TTML_FILE); assertEquals(6, subtitle.getEventTimeCount()); @@ -354,7 +358,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertEquals(0, spannable.getSpans(0, spannable.length(), AbsoluteSizeSpan.class).length); } - public void testFontSizeWithEmptyValueIsIgnored() throws IOException { + public void testFontSizeWithEmptyValueIsIgnored() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(FONT_SIZE_EMPTY_TTML_FILE); assertEquals(2, subtitle.getEventTimeCount()); List cues = subtitle.getCues(10 * 1000000); @@ -365,7 +369,7 @@ public final class TtmlParserTest extends InstrumentationTestCase { assertEquals(0, spannable.getSpans(0, spannable.length(), AbsoluteSizeSpan.class).length); } - public void testFrameRate() throws IOException { + public void testFrameRate() throws IOException, TextDecoderException { TtmlSubtitle subtitle = getSubtitle(FRAME_RATE_TTML_FILE); assertEquals(4, subtitle.getEventTimeCount()); assertEquals(1_000_000, subtitle.getEventTime(0)); @@ -476,9 +480,10 @@ public final class TtmlParserTest extends InstrumentationTestCase { throw new IllegalStateException("tag not found"); } - private TtmlSubtitle getSubtitle(String file) throws IOException { - TtmlParser ttmlParser = new TtmlParser(); + private TtmlSubtitle getSubtitle(String file) throws IOException, TextDecoderException { + TtmlDecoder ttmlDecoder = new TtmlDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), file); - return ttmlParser.decode(bytes, bytes.length); + return ttmlDecoder.decode(bytes, bytes.length); } + } diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttParserTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttDecoderTest.java similarity index 82% rename from library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttParserTest.java rename to library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttDecoderTest.java index 3c1c8f7bf3..fa89b2a63d 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttParserTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttDecoderTest.java @@ -15,20 +15,18 @@ */ package com.google.android.exoplayer2.text.webvtt; -import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Subtitle; +import com.google.android.exoplayer2.text.TextDecoderException; import junit.framework.TestCase; -import java.io.IOException; import java.util.List; /** - * Unit test for {@link Mp4WebvttParser}. - * As a side effect, it also involves the {@link Mp4WebvttSubtitle}. + * Unit test for {@link Mp4WebvttDecoder}. */ -public final class Mp4WebvttParserTest extends TestCase { +public final class Mp4WebvttDecoderTest extends TestCase { private static final byte[] SINGLE_CUE_SAMPLE = { 0x00, 0x00, 0x00, 0x1C, // Size @@ -81,42 +79,39 @@ public final class Mp4WebvttParserTest extends TestCase { 0x76, 0x74, 0x74 }; - private Mp4WebvttParser parser; - - @Override - public void setUp() { - parser = new Mp4WebvttParser(); - } - // Positive tests. - public void testSingleCueSample() throws ParserException { - Subtitle result = parser.decode(SINGLE_CUE_SAMPLE, SINGLE_CUE_SAMPLE.length); - Cue expectedCue = new Cue("Hello World"); // Line feed must be trimmed by the parser + public void testSingleCueSample() throws TextDecoderException { + Mp4WebvttDecoder decoder = new Mp4WebvttDecoder(); + Subtitle result = decoder.decode(SINGLE_CUE_SAMPLE, SINGLE_CUE_SAMPLE.length); + Cue expectedCue = new Cue("Hello World"); // Line feed must be trimmed by the decoder assertMp4WebvttSubtitleEquals(result, expectedCue); } - public void testTwoCuesSample() throws ParserException { - Subtitle result = parser.decode(DOUBLE_CUE_SAMPLE, DOUBLE_CUE_SAMPLE.length); + public void testTwoCuesSample() throws TextDecoderException { + Mp4WebvttDecoder decoder = new Mp4WebvttDecoder(); + Subtitle result = decoder.decode(DOUBLE_CUE_SAMPLE, DOUBLE_CUE_SAMPLE.length); Cue firstExpectedCue = new Cue("Hello World"); Cue secondExpectedCue = new Cue("Bye Bye"); assertMp4WebvttSubtitleEquals(result, firstExpectedCue, secondExpectedCue); } - public void testNoCueSample() throws IOException { - Subtitle result = parser.decode(NO_CUE_SAMPLE, NO_CUE_SAMPLE.length); + public void testNoCueSample() throws TextDecoderException { + Mp4WebvttDecoder decoder = new Mp4WebvttDecoder(); + Subtitle result = decoder.decode(NO_CUE_SAMPLE, NO_CUE_SAMPLE.length); assertMp4WebvttSubtitleEquals(result, new Cue[0]); } // Negative tests. public void testSampleWithIncompleteHeader() { + Mp4WebvttDecoder decoder = new Mp4WebvttDecoder(); try { - parser.decode(INCOMPLETE_HEADER_SAMPLE, INCOMPLETE_HEADER_SAMPLE.length); - } catch (ParserException e) { + decoder.decode(INCOMPLETE_HEADER_SAMPLE, INCOMPLETE_HEADER_SAMPLE.length); + } catch (TextDecoderException e) { return; } - fail("The parser should have failed, no payload was included in the VTTCue."); + fail(); } // Util methods diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/WebvttParserTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/WebvttDecoderTest.java similarity index 89% rename from library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/WebvttParserTest.java rename to library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/WebvttDecoderTest.java index 71b8ffa42c..d3be961022 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/WebvttParserTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/text/webvtt/WebvttDecoderTest.java @@ -15,9 +15,9 @@ */ package com.google.android.exoplayer2.text.webvtt; -import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.text.Cue; +import com.google.android.exoplayer2.text.TextDecoderException; import android.graphics.Typeface; import android.test.InstrumentationTestCase; @@ -33,9 +33,9 @@ import java.io.IOException; import java.util.List; /** - * Unit test for {@link WebvttParser}. + * Unit test for {@link WebvttDecoder}. */ -public class WebvttParserTest extends InstrumentationTestCase { +public class WebvttDecoderTest extends InstrumentationTestCase { private static final String TYPICAL_FILE = "webvtt/typical"; private static final String TYPICAL_WITH_IDS_FILE = "webvtt/typical_with_identifiers"; @@ -47,18 +47,18 @@ public class WebvttParserTest extends InstrumentationTestCase { private static final String WITH_CSS_COMPLEX_SELECTORS = "webvtt/with_css_complex_selectors"; private static final String EMPTY_FILE = "webvtt/empty"; - public void testParseEmpty() throws IOException { - WebvttParser parser = new WebvttParser(); + public void testDecodeEmpty() throws IOException { + WebvttDecoder decoder = new WebvttDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), EMPTY_FILE); try { - parser.decode(bytes, bytes.length); - fail("Expected ParserException"); - } catch (ParserException expected) { + decoder.decode(bytes, bytes.length); + fail(); + } catch (TextDecoderException expected) { // Do nothing. } } - public void testParseTypical() throws IOException { + public void testDecodeTypical() throws IOException, TextDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(TYPICAL_FILE); // Test event count. @@ -69,7 +69,7 @@ public class WebvttParserTest extends InstrumentationTestCase { assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle."); } - public void testParseTypicalWithIds() throws IOException { + public void testDecodeTypicalWithIds() throws IOException, TextDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(TYPICAL_WITH_IDS_FILE); // Test event count. @@ -80,7 +80,7 @@ public class WebvttParserTest extends InstrumentationTestCase { assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle."); } - public void testParseTypicalWithComments() throws IOException { + public void testDecodeTypicalWithComments() throws IOException, TextDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(TYPICAL_WITH_COMMENTS_FILE); // test event count @@ -91,7 +91,7 @@ public class WebvttParserTest extends InstrumentationTestCase { assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle."); } - public void testParseWithTags() throws IOException { + public void testDecodeWithTags() throws IOException, TextDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_TAGS_FILE); // Test event count. @@ -104,7 +104,7 @@ public class WebvttParserTest extends InstrumentationTestCase { assertCue(subtitle, 6, 6000000, 7000000, "This is the &subtitle."); } - public void testParseWithPositioning() throws IOException { + public void testDecodeWithPositioning() throws IOException, TextDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_POSITIONING_FILE); // Test event count. assertEquals(12, subtitle.getEventTimeCount()); @@ -128,7 +128,7 @@ public class WebvttParserTest extends InstrumentationTestCase { Cue.TYPE_UNSET, 0.35f); } - public void testParseWithBadCueHeader() throws IOException { + public void testDecodeWithBadCueHeader() throws IOException, TextDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_BAD_CUE_HEADER_FILE); // Test event count. @@ -139,7 +139,7 @@ public class WebvttParserTest extends InstrumentationTestCase { assertCue(subtitle, 2, 4000000, 5000000, "This is the third subtitle."); } - public void testWebvttWithCssStyle() throws IOException { + public void testWebvttWithCssStyle() throws IOException, TextDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_CSS_STYLES); // Test event count. @@ -162,7 +162,7 @@ public class WebvttParserTest extends InstrumentationTestCase { assertEquals(Typeface.BOLD, s4.getSpans(17, s4.length(), StyleSpan.class)[0].getStyle()); } - public void testWithComplexCssSelectors() throws IOException { + public void testWithComplexCssSelectors() throws IOException, TextDecoderException { WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_CSS_COMPLEX_SELECTORS); Spanned text = getUniqueSpanTextAt(subtitle, 0); assertEquals(1, text.getSpans(30, text.length(), ForegroundColorSpan.class).length); @@ -192,10 +192,11 @@ public class WebvttParserTest extends InstrumentationTestCase { assertEquals(Typeface.ITALIC, text.getSpans(19, text.length(), StyleSpan.class)[0].getStyle()); } - private WebvttSubtitle getSubtitleForTestAsset(String asset) throws IOException { - WebvttParser parser = new WebvttParser(); + private WebvttSubtitle getSubtitleForTestAsset(String asset) throws IOException, + TextDecoderException { + WebvttDecoder decoder = new WebvttDecoder(); byte[] bytes = TestUtil.getByteArray(getInstrumentation(), asset); - return parser.decode(bytes, bytes.length); + return decoder.decode(bytes, bytes.length); } private Spanned getUniqueSpanTextAt(WebvttSubtitle sub, long timeUs) { diff --git a/library/src/main/java/com/google/android/exoplayer2/ExoPlayer.java b/library/src/main/java/com/google/android/exoplayer2/ExoPlayer.java index c2d43d8947..8c28f90715 100644 --- a/library/src/main/java/com/google/android/exoplayer2/ExoPlayer.java +++ b/library/src/main/java/com/google/android/exoplayer2/ExoPlayer.java @@ -39,15 +39,16 @@ import com.google.android.exoplayer2.source.MediaSource; * is created. Hence {@link ExoPlayer} is capable of loading and playing any media for which a * {@link Renderer} implementation can be provided. * - *

{@link MediaCodecAudioRenderer} and {@link MediaCodecVideoRenderer} can be used for - * the common cases of rendering audio and video. These components in turn require an - * upstream {@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 - * upstream dependency injection is actively encouraged, since it means that the functionality of - * the player is built up through the composition of components that can easily be exchanged for - * alternate implementations. For example a {@link MediaPeriod} implementation may require a - * further upstream data loading component to be injected through its constructor, with different - * implementations enabling the loading of data from various sources. + *

{@link com.google.android.exoplayer2.audio.MediaCodecAudioRenderer} and + * {@link com.google.android.exoplayer2.video.MediaCodecVideoRenderer} can be used for the common + * cases of rendering audio and video. These components in turn require an upstream + * {@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 upstream dependency + * injection is actively encouraged, since it means that the functionality of the player is built up + * through the composition of components that can easily be exchanged for alternate implementations. + * For example a {@link MediaPeriod} implementation may require a further upstream data loading + * component to be injected through its constructor, with different implementations enabling the + * loading of data from various sources. * * *

Threading model

diff --git a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index ac4ea78749..14265299d1 100644 --- a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -24,7 +24,9 @@ import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationListener; +import com.google.android.exoplayer2.util.MediaClock; import com.google.android.exoplayer2.util.PriorityHandlerThread; +import com.google.android.exoplayer2.util.StandaloneMediaClock; import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.Util; diff --git a/library/src/main/java/com/google/android/exoplayer2/ParserException.java b/library/src/main/java/com/google/android/exoplayer2/ParserException.java index eccd28a64e..5ee432efbf 100644 --- a/library/src/main/java/com/google/android/exoplayer2/ParserException.java +++ b/library/src/main/java/com/google/android/exoplayer2/ParserException.java @@ -18,7 +18,7 @@ package com.google.android.exoplayer2; import java.io.IOException; /** - * Thrown when an error occurs parsing media data. + * Thrown when an error occurs parsing loaded data. */ public class ParserException extends IOException { diff --git a/library/src/main/java/com/google/android/exoplayer2/Renderer.java b/library/src/main/java/com/google/android/exoplayer2/Renderer.java index c6616aa79b..a05990de8c 100644 --- a/library/src/main/java/com/google/android/exoplayer2/Renderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/Renderer.java @@ -16,8 +16,10 @@ package com.google.android.exoplayer2; import com.google.android.exoplayer2.ExoPlayer.ExoPlayerComponent; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.source.SampleStream; import com.google.android.exoplayer2.util.Assertions; +import com.google.android.exoplayer2.util.MediaClock; import com.google.android.exoplayer2.util.MimeTypes; import java.io.IOException; diff --git a/library/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java b/library/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java index 0633a12a11..3857db65f4 100644 --- a/library/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java +++ b/library/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java @@ -16,16 +16,21 @@ package com.google.android.exoplayer2; import com.google.android.exoplayer2.audio.AudioCapabilities; +import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioTrack; +import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer; +import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.drm.DrmSessionManager; +import com.google.android.exoplayer2.mediacodec.MediaCodecSelector; import com.google.android.exoplayer2.metadata.MetadataRenderer; +import com.google.android.exoplayer2.metadata.id3.Id3Decoder; import com.google.android.exoplayer2.metadata.id3.Id3Frame; -import com.google.android.exoplayer2.metadata.id3.Id3Parser; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.TextRenderer; import com.google.android.exoplayer2.trackselection.TrackSelector; - +import com.google.android.exoplayer2.video.MediaCodecVideoRenderer; +import com.google.android.exoplayer2.video.VideoRendererEventListener; import android.annotation.TargetApi; import android.content.Context; import android.media.AudioManager; @@ -60,17 +65,17 @@ public final class SimpleExoPlayer implements ExoPlayer { * A listener for debugging information. */ public interface DebugListener { - void onAudioEnabled(CodecCounters counters); + void onAudioEnabled(DecoderCounters counters); void onAudioSessionId(int audioSessionId); void onAudioDecoderInitialized(String decoderName, long elapsedRealtimeMs, long initializationDurationMs); void onAudioFormatChanged(Format format); - void onAudioDisabled(CodecCounters counters); - void onVideoEnabled(CodecCounters counters); + void onAudioDisabled(DecoderCounters counters); + void onVideoEnabled(DecoderCounters counters); void onVideoDecoderInitialized(String decoderName, long elapsedRealtimeMs, long initializationDurationMs); void onVideoFormatChanged(Format format); - void onVideoDisabled(CodecCounters counters); + void onVideoDisabled(DecoderCounters counters); void onDroppedFrames(int count, long elapsed); void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs); } @@ -106,8 +111,8 @@ public final class SimpleExoPlayer implements ExoPlayer { private Id3MetadataListener id3MetadataListener; private VideoListener videoListener; private DebugListener debugListener; - private CodecCounters videoCodecCounters; - private CodecCounters audioCodecCounters; + private DecoderCounters videoDecoderCounters; + private DecoderCounters audioDecoderCounters; private int audioSessionId; /* package */ SimpleExoPlayer(Context context, TrackSelector trackSelector, @@ -246,19 +251,19 @@ public final class SimpleExoPlayer implements ExoPlayer { } /** - * @return The {@link CodecCounters} for video, or null if there is no video component to the + * @return The {@link DecoderCounters} for video, or null if there is no video component to the * current media. */ - public CodecCounters getVideoCodecCounters() { - return videoCodecCounters; + public DecoderCounters getVideoDecoderCounters() { + return videoDecoderCounters; } /** - * @return The {@link CodecCounters} for audio, or null if there is no audio component to the + * @return The {@link DecoderCounters} for audio, or null if there is no audio component to the * current media. */ - public CodecCounters getAudioCodecCounters() { - return audioCodecCounters; + public DecoderCounters getAudioDecoderCounters() { + return audioDecoderCounters; } /** @@ -413,7 +418,7 @@ public final class SimpleExoPlayer implements ExoPlayer { renderersList.add(textRenderer); MetadataRenderer> id3Renderer = new MetadataRenderer<>(componentListener, - mainHandler.getLooper(), new Id3Parser()); + mainHandler.getLooper(), new Id3Decoder()); renderersList.add(id3Renderer); } @@ -482,8 +487,8 @@ public final class SimpleExoPlayer implements ExoPlayer { // VideoRendererEventListener implementation @Override - public void onVideoEnabled(CodecCounters counters) { - videoCodecCounters = counters; + public void onVideoEnabled(DecoderCounters counters) { + videoDecoderCounters = counters; if (debugListener != null) { debugListener.onVideoEnabled(counters); } @@ -530,19 +535,19 @@ public final class SimpleExoPlayer implements ExoPlayer { } @Override - public void onVideoDisabled(CodecCounters counters) { + public void onVideoDisabled(DecoderCounters counters) { if (debugListener != null) { debugListener.onVideoDisabled(counters); } videoFormat = null; - videoCodecCounters = null; + videoDecoderCounters = null; } // AudioRendererEventListener implementation @Override - public void onAudioEnabled(CodecCounters counters) { - audioCodecCounters = counters; + public void onAudioEnabled(DecoderCounters counters) { + audioDecoderCounters = counters; if (debugListener != null) { debugListener.onAudioEnabled(counters); } @@ -582,12 +587,12 @@ public final class SimpleExoPlayer implements ExoPlayer { } @Override - public void onAudioDisabled(CodecCounters counters) { + public void onAudioDisabled(DecoderCounters counters) { if (debugListener != null) { debugListener.onAudioDisabled(counters); } audioFormat = null; - audioCodecCounters = null; + audioDecoderCounters = null; audioSessionId = AudioTrack.SESSION_ID_NOT_SET; } diff --git a/library/src/main/java/com/google/android/exoplayer2/util/Ac3Util.java b/library/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java similarity index 97% rename from library/src/main/java/com/google/android/exoplayer2/util/Ac3Util.java rename to library/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java index 9b09423e83..3033accf72 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/Ac3Util.java +++ b/library/src/main/java/com/google/android/exoplayer2/audio/Ac3Util.java @@ -13,10 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.util; +package com.google.android.exoplayer2.audio; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.drm.DrmInitData; +import com.google.android.exoplayer2.util.MimeTypes; +import com.google.android.exoplayer2.util.ParsableBitArray; +import com.google.android.exoplayer2.util.ParsableByteArray; import java.nio.ByteBuffer; diff --git a/library/src/main/java/com/google/android/exoplayer2/extensions/AudioDecoderException.java b/library/src/main/java/com/google/android/exoplayer2/audio/AudioDecoderException.java similarity index 82% rename from library/src/main/java/com/google/android/exoplayer2/extensions/AudioDecoderException.java rename to library/src/main/java/com/google/android/exoplayer2/audio/AudioDecoderException.java index 0f15335770..e74920d1d1 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extensions/AudioDecoderException.java +++ b/library/src/main/java/com/google/android/exoplayer2/audio/AudioDecoderException.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.extensions; +package com.google.android.exoplayer2.audio; /** - * Thrown when a decoder error occurs. + * Thrown when an audio decoder error occurs. */ -public class AudioDecoderException extends Exception { +public abstract class AudioDecoderException extends Exception { public AudioDecoderException(String detailMessage) { super(detailMessage); diff --git a/library/src/main/java/com/google/android/exoplayer2/AudioRendererEventListener.java b/library/src/main/java/com/google/android/exoplayer2/audio/AudioRendererEventListener.java similarity index 87% rename from library/src/main/java/com/google/android/exoplayer2/AudioRendererEventListener.java rename to library/src/main/java/com/google/android/exoplayer2/audio/AudioRendererEventListener.java index bb5d15c9bf..f28972e708 100644 --- a/library/src/main/java/com/google/android/exoplayer2/AudioRendererEventListener.java +++ b/library/src/main/java/com/google/android/exoplayer2/audio/AudioRendererEventListener.java @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.audio; -import com.google.android.exoplayer2.audio.AudioTrack; +import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.Renderer; +import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.util.Assertions; import android.os.Handler; @@ -29,10 +31,10 @@ public interface AudioRendererEventListener { /** * Invoked when the renderer is enabled. * - * @param counters {@link CodecCounters} that will be updated by the renderer for as long as it + * @param counters {@link DecoderCounters} that will be updated by the renderer for as long as it * remains enabled. */ - void onAudioEnabled(CodecCounters counters); + void onAudioEnabled(DecoderCounters counters); /** * Invoked when the audio session is set. @@ -73,9 +75,9 @@ public interface AudioRendererEventListener { /** * Invoked when the renderer is disabled. * - * @param counters {@link CodecCounters} that were updated by the renderer. + * @param counters {@link DecoderCounters} that were updated by the renderer. */ - void onAudioDisabled(CodecCounters counters); + void onAudioDisabled(DecoderCounters counters); /** * Dispatches events to a {@link AudioRendererEventListener}. @@ -90,12 +92,12 @@ public interface AudioRendererEventListener { this.listener = listener; } - public void enabled(final CodecCounters codecCounters) { + public void enabled(final DecoderCounters decoderCounters) { if (listener != null) { handler.post(new Runnable() { @Override public void run() { - listener.onAudioEnabled(codecCounters); + listener.onAudioEnabled(decoderCounters); } }); } @@ -137,7 +139,7 @@ public interface AudioRendererEventListener { } } - public void disabled(final CodecCounters counters) { + public void disabled(final DecoderCounters counters) { if (listener != null) { handler.post(new Runnable() { @Override diff --git a/library/src/main/java/com/google/android/exoplayer2/audio/AudioTrack.java b/library/src/main/java/com/google/android/exoplayer2/audio/AudioTrack.java index 1f0bc2aa35..1e3fe65c1f 100644 --- a/library/src/main/java/com/google/android/exoplayer2/audio/AudioTrack.java +++ b/library/src/main/java/com/google/android/exoplayer2/audio/AudioTrack.java @@ -16,9 +16,7 @@ package com.google.android.exoplayer2.audio; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.util.Ac3Util; import com.google.android.exoplayer2.util.Assertions; -import com.google.android.exoplayer2.util.DtsUtil; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; diff --git a/library/src/main/java/com/google/android/exoplayer2/util/DtsUtil.java b/library/src/main/java/com/google/android/exoplayer2/audio/DtsUtil.java similarity index 96% rename from library/src/main/java/com/google/android/exoplayer2/util/DtsUtil.java rename to library/src/main/java/com/google/android/exoplayer2/audio/DtsUtil.java index ddb2a92514..e6c143ac89 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/DtsUtil.java +++ b/library/src/main/java/com/google/android/exoplayer2/audio/DtsUtil.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.util; +package com.google.android.exoplayer2.audio; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.drm.DrmInitData; +import com.google.android.exoplayer2.util.MimeTypes; +import com.google.android.exoplayer2.util.ParsableBitArray; import java.nio.ByteBuffer; diff --git a/library/src/main/java/com/google/android/exoplayer2/MediaCodecAudioRenderer.java b/library/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java similarity index 93% rename from library/src/main/java/com/google/android/exoplayer2/MediaCodecAudioRenderer.java rename to library/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java index 167a14a507..35b3086fcd 100644 --- a/library/src/main/java/com/google/android/exoplayer2/MediaCodecAudioRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java @@ -13,13 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.audio; -import com.google.android.exoplayer2.AudioRendererEventListener.EventDispatcher; -import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; -import com.google.android.exoplayer2.audio.AudioCapabilities; -import com.google.android.exoplayer2.audio.AudioTrack; +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.ExoPlaybackException; +import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.Renderer; +import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.drm.DrmSessionManager; +import com.google.android.exoplayer2.mediacodec.MediaCodecInfo; +import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer; +import com.google.android.exoplayer2.mediacodec.MediaCodecSelector; +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; +import com.google.android.exoplayer2.util.MediaClock; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; @@ -148,7 +154,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media if (allowPassthrough(mimeType) && mediaCodecSelector.getPassthroughDecoderInfo() != null) { return ADAPTIVE_NOT_SEAMLESS | FORMAT_HANDLED; } - MediaCodecDecoderInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, + MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, format.requiresSecureDecryption); if (decoderInfo == null) { return FORMAT_UNSUPPORTED_SUBTYPE; @@ -164,10 +170,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media } @Override - protected MediaCodecDecoderInfo getDecoderInfo(MediaCodecSelector mediaCodecSelector, + protected MediaCodecInfo getDecoderInfo(MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder) throws DecoderQueryException { if (allowPassthrough(format.sampleMimeType)) { - MediaCodecDecoderInfo passthroughDecoderInfo = mediaCodecSelector.getPassthroughDecoderInfo(); + MediaCodecInfo passthroughDecoderInfo = mediaCodecSelector.getPassthroughDecoderInfo(); if (passthroughDecoderInfo != null) { passthroughEnabled = true; return passthroughDecoderInfo; @@ -255,7 +261,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media @Override protected void onEnabled(boolean joining) throws ExoPlaybackException { super.onEnabled(joining); - eventDispatcher.enabled(codecCounters); + eventDispatcher.enabled(decoderCounters); } @Override @@ -287,8 +293,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media try { super.onDisabled(); } finally { - codecCounters.ensureUpdated(); - eventDispatcher.disabled(codecCounters); + decoderCounters.ensureUpdated(); + eventDispatcher.disabled(decoderCounters); } } } @@ -326,7 +332,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media if (shouldSkip) { codec.releaseOutputBuffer(bufferIndex, false); - codecCounters.skippedOutputBufferCount++; + decoderCounters.skippedOutputBufferCount++; audioTrack.handleDiscontinuity(); return true; } @@ -378,7 +384,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media // Release the buffer if it was consumed. if ((handleBufferResult & AudioTrack.RESULT_BUFFER_CONSUMED) != 0) { codec.releaseOutputBuffer(bufferIndex, false); - codecCounters.renderedOutputBufferCount++; + decoderCounters.renderedOutputBufferCount++; return true; } diff --git a/library/src/main/java/com/google/android/exoplayer2/extensions/AudioDecoderRenderer.java b/library/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java similarity index 90% rename from library/src/main/java/com/google/android/exoplayer2/extensions/AudioDecoderRenderer.java rename to library/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java index d430edf2e9..0f871cd1c3 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extensions/AudioDecoderRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java @@ -13,20 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.extensions; +package com.google.android.exoplayer2.audio; -import com.google.android.exoplayer2.AudioRendererEventListener; -import com.google.android.exoplayer2.AudioRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.CodecCounters; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; -import com.google.android.exoplayer2.MediaClock; import com.google.android.exoplayer2.Renderer; -import com.google.android.exoplayer2.audio.AudioCapabilities; -import com.google.android.exoplayer2.audio.AudioTrack; +import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher; +import com.google.android.exoplayer2.decoder.DecoderCounters; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; +import com.google.android.exoplayer2.decoder.SimpleDecoder; +import com.google.android.exoplayer2.decoder.SimpleOutputBuffer; +import com.google.android.exoplayer2.util.MediaClock; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.TraceUtil; @@ -38,12 +37,12 @@ import android.os.SystemClock; /** * Decodes and renders audio using a {@link SimpleDecoder}. */ -public abstract class AudioDecoderRenderer extends Renderer implements MediaClock { +public abstract class SimpleDecoderAudioRenderer extends Renderer implements MediaClock { private final EventDispatcher eventDispatcher; private final FormatHolder formatHolder; - private CodecCounters codecCounters; + private DecoderCounters decoderCounters; private Format inputFormat; private SimpleDecoder decoder; @@ -61,7 +60,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc private boolean audioTrackHasData; private long lastFeedElapsedRealtimeMs; - public AudioDecoderRenderer() { + public SimpleDecoderAudioRenderer() { this(null, null); } @@ -70,7 +69,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc * 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 AudioDecoderRenderer(Handler eventHandler, + public SimpleDecoderAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener) { this (eventHandler, eventListener, null, AudioManager.STREAM_MUSIC); } @@ -83,7 +82,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc * default capabilities (no encoded audio passthrough support) should be assumed. * @param streamType The type of audio stream for the {@link AudioTrack}. */ - public AudioDecoderRenderer(Handler eventHandler, + public SimpleDecoderAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener, AudioCapabilities audioCapabilities, int streamType) { eventDispatcher = new EventDispatcher(eventHandler, eventListener); @@ -119,7 +118,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc long codecInitializedTimestamp = SystemClock.elapsedRealtime(); eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp, codecInitializedTimestamp - codecInitializingTimestamp); - codecCounters.codecInitCount++; + decoderCounters.codecInitCount++; } catch (AudioDecoderException e) { throw ExoPlaybackException.createForRenderer(e, getIndex()); } @@ -135,7 +134,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc | AudioDecoderException e) { throw ExoPlaybackException.createForRenderer(e, getIndex()); } - codecCounters.ensureUpdated(); + decoderCounters.ensureUpdated(); } @Override @@ -170,7 +169,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc if (outputBuffer == null) { return false; } - codecCounters.skippedOutputBufferCount += outputBuffer.skippedOutputBufferCount; + decoderCounters.skippedOutputBufferCount += outputBuffer.skippedOutputBufferCount; } if (outputBuffer.isEndOfStream()) { @@ -219,7 +218,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc // Release the buffer if it was consumed. if ((handleBufferResult & AudioTrack.RESULT_BUFFER_CONSUMED) != 0) { - codecCounters.renderedOutputBufferCount++; + decoderCounters.renderedOutputBufferCount++; outputBuffer.release(); outputBuffer = null; return true; @@ -256,7 +255,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc } inputBuffer.flip(); decoder.queueInputBuffer(inputBuffer); - codecCounters.inputBufferCount++; + decoderCounters.inputBufferCount++; inputBuffer = null; return true; } @@ -307,8 +306,8 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc @Override protected void onEnabled(boolean joining) throws ExoPlaybackException { - codecCounters = new CodecCounters(); - eventDispatcher.enabled(codecCounters); + decoderCounters = new DecoderCounters(); + eventDispatcher.enabled(decoderCounters); } @Override @@ -343,12 +342,12 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc if (decoder != null) { decoder.release(); decoder = null; - codecCounters.codecReleaseCount++; + decoderCounters.codecReleaseCount++; } audioTrack.release(); } finally { - codecCounters.ensureUpdated(); - eventDispatcher.disabled(codecCounters); + decoderCounters.ensureUpdated(); + eventDispatcher.disabled(decoderCounters); } } diff --git a/library/src/main/java/com/google/android/exoplayer2/util/Buffer.java b/library/src/main/java/com/google/android/exoplayer2/decoder/Buffer.java similarity index 98% rename from library/src/main/java/com/google/android/exoplayer2/util/Buffer.java rename to library/src/main/java/com/google/android/exoplayer2/decoder/Buffer.java index b0b938c67d..cb408714f4 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/Buffer.java +++ b/library/src/main/java/com/google/android/exoplayer2/decoder/Buffer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.util; +package com.google.android.exoplayer2.decoder; import com.google.android.exoplayer2.C; diff --git a/library/src/main/java/com/google/android/exoplayer2/CryptoInfo.java b/library/src/main/java/com/google/android/exoplayer2/decoder/CryptoInfo.java similarity index 98% rename from library/src/main/java/com/google/android/exoplayer2/CryptoInfo.java rename to library/src/main/java/com/google/android/exoplayer2/decoder/CryptoInfo.java index 56cb7d3bdd..a85d2ac7cc 100644 --- a/library/src/main/java/com/google/android/exoplayer2/CryptoInfo.java +++ b/library/src/main/java/com/google/android/exoplayer2/decoder/CryptoInfo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.decoder; import com.google.android.exoplayer2.util.Util; diff --git a/library/src/main/java/com/google/android/exoplayer2/extensions/Decoder.java b/library/src/main/java/com/google/android/exoplayer2/decoder/Decoder.java similarity index 97% rename from library/src/main/java/com/google/android/exoplayer2/extensions/Decoder.java rename to library/src/main/java/com/google/android/exoplayer2/decoder/Decoder.java index 79e0e5849e..4616154f76 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extensions/Decoder.java +++ b/library/src/main/java/com/google/android/exoplayer2/decoder/Decoder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.extensions; +package com.google.android.exoplayer2.decoder; /** * A media decoder. diff --git a/library/src/main/java/com/google/android/exoplayer2/CodecCounters.java b/library/src/main/java/com/google/android/exoplayer2/decoder/DecoderCounters.java similarity index 93% rename from library/src/main/java/com/google/android/exoplayer2/CodecCounters.java rename to library/src/main/java/com/google/android/exoplayer2/decoder/DecoderCounters.java index 73147a8001..397ef6ecac 100644 --- a/library/src/main/java/com/google/android/exoplayer2/CodecCounters.java +++ b/library/src/main/java/com/google/android/exoplayer2/decoder/DecoderCounters.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.decoder; /** * Maintains codec event counts, for debugging purposes only. @@ -22,7 +22,7 @@ package com.google.android.exoplayer2; * To ensure that the counter values are correctly reflected between threads, users of this class * should invoke {@link #ensureUpdated()} prior to reading and after writing. */ -public final class CodecCounters { +public final class DecoderCounters { /** * The number of times the codec has been initialized. @@ -73,9 +73,9 @@ public final class CodecCounters { /** * Merges the counts from {@code other} into this instance. * - * @param other The {@link CodecCounters} to merge into this instance. + * @param other The {@link DecoderCounters} to merge into this instance. */ - public void merge(CodecCounters other) { + public void merge(DecoderCounters other) { codecInitCount += other.codecInitCount; codecReleaseCount += other.codecReleaseCount; inputBufferCount += other.inputBufferCount; diff --git a/library/src/main/java/com/google/android/exoplayer2/DecoderInputBuffer.java b/library/src/main/java/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java similarity index 98% rename from library/src/main/java/com/google/android/exoplayer2/DecoderInputBuffer.java rename to library/src/main/java/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java index c00e22e8d7..3e59bedee6 100644 --- a/library/src/main/java/com/google/android/exoplayer2/DecoderInputBuffer.java +++ b/library/src/main/java/com/google/android/exoplayer2/decoder/DecoderInputBuffer.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.decoder; -import com.google.android.exoplayer2.util.Buffer; +import com.google.android.exoplayer2.C; import java.nio.ByteBuffer; diff --git a/library/src/main/java/com/google/android/exoplayer2/extensions/OutputBuffer.java b/library/src/main/java/com/google/android/exoplayer2/decoder/OutputBuffer.java similarity index 91% rename from library/src/main/java/com/google/android/exoplayer2/extensions/OutputBuffer.java rename to library/src/main/java/com/google/android/exoplayer2/decoder/OutputBuffer.java index 22aaf4fc73..31a9660086 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extensions/OutputBuffer.java +++ b/library/src/main/java/com/google/android/exoplayer2/decoder/OutputBuffer.java @@ -13,9 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.extensions; - -import com.google.android.exoplayer2.util.Buffer; +package com.google.android.exoplayer2.decoder; /** * Output buffer decoded by a {@link Decoder}. diff --git a/library/src/main/java/com/google/android/exoplayer2/extensions/SimpleDecoder.java b/library/src/main/java/com/google/android/exoplayer2/decoder/SimpleDecoder.java similarity index 95% rename from library/src/main/java/com/google/android/exoplayer2/extensions/SimpleDecoder.java rename to library/src/main/java/com/google/android/exoplayer2/decoder/SimpleDecoder.java index f782e30737..45a08f3dd5 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extensions/SimpleDecoder.java +++ b/library/src/main/java/com/google/android/exoplayer2/decoder/SimpleDecoder.java @@ -13,10 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.extensions; +package com.google.android.exoplayer2.decoder; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.util.Assertions; import java.util.LinkedList; @@ -27,20 +26,6 @@ import java.util.LinkedList; public abstract class SimpleDecoder implements Decoder { - /** - * Listener for {@link SimpleDecoder} events. - */ - public interface EventListener { - - /** - * Invoked when the decoder encounters an error. - * - * @param e The corresponding exception. - */ - void onDecoderError(E e); - - } - private final Thread decodeThread; private final Object lock; diff --git a/library/src/main/java/com/google/android/exoplayer2/extensions/SimpleOutputBuffer.java b/library/src/main/java/com/google/android/exoplayer2/decoder/SimpleOutputBuffer.java similarity index 97% rename from library/src/main/java/com/google/android/exoplayer2/extensions/SimpleOutputBuffer.java rename to library/src/main/java/com/google/android/exoplayer2/decoder/SimpleOutputBuffer.java index 706af6d060..314d5cfab7 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extensions/SimpleOutputBuffer.java +++ b/library/src/main/java/com/google/android/exoplayer2/decoder/SimpleOutputBuffer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.extensions; +package com.google.android.exoplayer2.decoder; import java.nio.ByteBuffer; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java b/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java index dbc912a358..8033b83af5 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java @@ -16,9 +16,9 @@ package com.google.android.exoplayer2.extractor; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.upstream.Allocation; import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.util.Assertions; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/GaplessInfoHolder.java b/library/src/main/java/com/google/android/exoplayer2/extractor/GaplessInfoHolder.java index c804075b98..72d2e1abdf 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/GaplessInfoHolder.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/GaplessInfoHolder.java @@ -52,7 +52,7 @@ public final class GaplessInfoHolder { /** * Populates the holder with data from an MP3 Xing header, if valid and non-zero. * - * @param value The 24-bit value to parse. + * @param value The 24-bit value to decode. * @return Whether the holder was populated. */ public boolean setFromXingHeaderValue(int value) { diff --git a/library/src/main/java/com/google/android/exoplayer2/util/MpegAudioHeader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/MpegAudioHeader.java similarity index 98% rename from library/src/main/java/com/google/android/exoplayer2/util/MpegAudioHeader.java rename to library/src/main/java/com/google/android/exoplayer2/extractor/MpegAudioHeader.java index 8d6cad76e6..d9bf8c5ae9 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/MpegAudioHeader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/MpegAudioHeader.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.util; +package com.google.android.exoplayer2.extractor; + +import com.google.android.exoplayer2.util.MimeTypes; /** - * Representation of an MPEG audio frame header. + * An MPEG audio frame header. */ public final class MpegAudioHeader { diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/flv/VideoTagPayloadReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/flv/VideoTagPayloadReader.java index 49bf2ba574..ef6fd78cc3 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/flv/VideoTagPayloadReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/flv/VideoTagPayloadReader.java @@ -101,7 +101,7 @@ import java.util.List; hasOutputFormat = true; } else if (packetType == AVC_PACKET_TYPE_AVC_NALU) { // TODO: Deduplicate with Mp4Extractor. - // Zero the top three bytes of the array that we'll use to parse nal unit lengths, in case + // Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case // they're only 1 or 2 bytes long. byte[] nalLengthData = nalLength.data; nalLengthData[0] = 0; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java index 72aa5fcc95..f620069b6f 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java @@ -920,7 +920,7 @@ public final class MatroskaExtractor implements Extractor { if (CODEC_ID_H264.equals(track.codecId) || CODEC_ID_H265.equals(track.codecId)) { // TODO: Deduplicate with Mp4Extractor. - // Zero the top three bytes of the array that we'll use to parse nal unit lengths, in case + // Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case // they're only 1 or 2 bytes long. byte[] nalLengthData = nalLength.data; nalLengthData[0] = 0; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java index 0aa6f7798c..930764c42a 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java @@ -26,7 +26,7 @@ import com.google.android.exoplayer2.extractor.GaplessInfoHolder; import com.google.android.exoplayer2.extractor.PositionHolder; import com.google.android.exoplayer2.extractor.SeekMap; import com.google.android.exoplayer2.extractor.TrackOutput; -import com.google.android.exoplayer2.util.MpegAudioHeader; +import com.google.android.exoplayer2.extractor.MpegAudioHeader; import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.Util; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/VbriSeeker.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/VbriSeeker.java index a6fe4fe897..78c2238c6f 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/VbriSeeker.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/VbriSeeker.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer2.extractor.mp3; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.util.MpegAudioHeader; +import com.google.android.exoplayer2.extractor.MpegAudioHeader; import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.Util; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/XingSeeker.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/XingSeeker.java index 123abe9450..1094caba8f 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/XingSeeker.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp3/XingSeeker.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer2.extractor.mp3; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.util.MpegAudioHeader; +import com.google.android.exoplayer2.extractor.MpegAudioHeader; import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.Util; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java index 08ea8f5b86..3d7bc52287 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java @@ -18,9 +18,9 @@ package com.google.android.exoplayer2.extractor.mp4; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.ParserException; +import com.google.android.exoplayer2.audio.Ac3Util; import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.extractor.GaplessInfoHolder; -import com.google.android.exoplayer2.util.Ac3Util; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.CodecSpecificDataUtil; import com.google.android.exoplayer2.util.MimeTypes; @@ -49,7 +49,7 @@ import java.util.List; /** * Parses a trak atom (defined in 14496-12). * - * @param trak Atom to parse. + * @param trak Atom to decode. * @param mvhd Movie header atom, used to get the timescale. * @param duration The duration in units of the timescale declared in the mvhd atom, or -1 if the * duration should be parsed from the tkhd atom. @@ -93,7 +93,7 @@ import java.util.List; * Parses an stbl atom (defined in 14496-12). * * @param track Track to which this sample table corresponds. - * @param stblAtom stbl (sample table) atom to parse. + * @param stblAtom stbl (sample table) atom to decode. * @param gaplessInfoHolder Holder to populate with gapless playback information. * @return Sample table described by the stbl atom. * @throws ParserException If the resulting sample sequence does not contain a sync sample. @@ -191,7 +191,7 @@ import java.util.List; remainingSamplesAtTimestampOffset = ctts.readUnsignedIntToInt(); // The BMFF spec (ISO 14496-12) states that sample offsets should be unsigned integers // in version 0 ctts boxes, however some streams violate the spec and use signed - // integers instead. It's safe to always parse sample offsets as signed integers here, + // integers instead. It's safe to always decode sample offsets as signed integers here, // because unsigned integers will still be parsed correctly (unless their top bit is // set, which is never true in practice because sample offsets are always small). timestampOffset = ctts.readInt(); @@ -378,14 +378,14 @@ import java.util.List; /** * Parses a udta atom. * - * @param udtaAtom The udta (user data) atom to parse. + * @param udtaAtom The udta (user data) atom to decode. * @param isQuickTime True for QuickTime media. False otherwise. * @param out {@link GaplessInfoHolder} to populate with gapless playback information. */ public static void parseUdta(Atom.LeafAtom udtaAtom, boolean isQuickTime, GaplessInfoHolder out) { if (isQuickTime) { // Meta boxes are regular boxes rather than full boxes in QuickTime. For now, don't try and - // parse one. + // decode one. return; } ParsableByteArray udtaData = udtaAtom.data; @@ -535,7 +535,7 @@ import java.util.List; /** * Parses an hdlr atom. * - * @param hdlr The hdlr atom to parse. + * @param hdlr The hdlr atom to decode. * @return The track type. */ private static int parseHdlr(ParsableByteArray hdlr) { @@ -556,7 +556,7 @@ import java.util.List; /** * Parses an mdhd atom (defined in 14496-12). * - * @param mdhd The mdhd atom to parse. + * @param mdhd The mdhd atom to decode. * @return A pair consisting of the media timescale defined as the number of time units that pass * in one second, and the language code. */ @@ -577,7 +577,7 @@ import java.util.List; /** * Parses a stsd atom (defined in 14496-12). * - * @param stsd The stsd atom to parse. + * @param stsd The stsd atom to decode. * @param trackId The track's identifier in its container. * @param rotationDegrees The rotation of the track in degrees. * @param language The language of the track. @@ -780,7 +780,7 @@ import java.util.List; /** * Parses the edts atom (defined in 14496-12 subsection 8.6.5). * - * @param edtsAtom edts (edit box) atom to parse. + * @param edtsAtom edts (edit box) atom to decode. * @return Pair of edit list durations and edit list media times, or a pair of nulls if they are * not present. */ diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java index 9a1125b57d..0a4c0d2649 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/FragmentedMp4Extractor.java @@ -538,7 +538,7 @@ public final class FragmentedMp4Extractor implements Extractor { /** * Parses a saio atom (defined in 14496-12). * - * @param saio The saio atom to parse. + * @param saio The saio atom to decode. * @param out The {@link TrackFragment} to populate with data from the saio atom. */ private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws ParserException { @@ -565,7 +565,7 @@ public final class FragmentedMp4Extractor implements Extractor { * returns the {@link TrackBundle} of the corresponding {@link Track}. If the tfhd does not refer * to any {@link TrackBundle}, {@code null} is returned and no changes are made. * - * @param tfhd The tfhd atom to parse. + * @param tfhd The tfhd atom to decode. * @param trackBundles The track bundles, one of which corresponds to the tfhd atom being parsed. * @return The {@link TrackBundle} to which the {@link TrackFragment} belongs, or null if the tfhd * does not refer to any {@link TrackBundle}. @@ -621,7 +621,7 @@ public final class FragmentedMp4Extractor implements Extractor { * which parsed data should be placed. * @param decodeTime The decode time of the first sample in the fragment run. * @param flags Flags to allow any required workaround to be executed. - * @param trun The trun atom to parse. + * @param trun The trun atom to decode. */ private static void parseTrun(TrackBundle trackBundle, long decodeTime, int flags, ParsableByteArray trun) { @@ -681,7 +681,7 @@ public final class FragmentedMp4Extractor implements Extractor { if (sampleCompositionTimeOffsetsPresent) { // The BMFF spec (ISO 14496-12) states that sample offsets should be unsigned integers in // version 0 trun boxes, however a significant number of streams violate the spec and use - // signed integers instead. It's safe to always parse sample offsets as signed integers + // signed integers instead. It's safe to always decode sample offsets as signed integers // here, because unsigned integers will still be parsed correctly (unless their top bit is // set, which is never true in practice because sample offsets are always small). int sampleOffset = trun.readInt(); @@ -926,7 +926,7 @@ public final class FragmentedMp4Extractor implements Extractor { TrackOutput output = currentTrackBundle.output; int sampleIndex = currentTrackBundle.currentSampleIndex; if (track.nalUnitLengthFieldLength != -1) { - // Zero the top three bytes of the array that we'll use to parse nal unit lengths, in case + // Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case // they're only 1 or 2 bytes long. byte[] nalLengthData = nalLength.data; nalLengthData[0] = 0; @@ -1044,7 +1044,7 @@ public final class FragmentedMp4Extractor implements Extractor { return 1 + vectorSize + subsampleDataLength; } - /** Returns whether the extractor should parse a leaf atom with type {@code atom}. */ + /** Returns whether the extractor should decode a leaf atom with type {@code atom}. */ private static boolean shouldParseLeafAtom(int atom) { return atom == Atom.TYPE_hdlr || atom == Atom.TYPE_mdhd || atom == Atom.TYPE_mvhd || atom == Atom.TYPE_sidx || atom == Atom.TYPE_stsd || atom == Atom.TYPE_tfdt @@ -1055,7 +1055,7 @@ public final class FragmentedMp4Extractor implements Extractor { || atom == Atom.TYPE_mehd; } - /** Returns whether the extractor should parse a container atom with type {@code atom}. */ + /** Returns whether the extractor should decode a container atom with type {@code atom}. */ private static boolean shouldParseContainerAtom(int atom) { return atom == Atom.TYPE_moov || atom == Atom.TYPE_trak || atom == Atom.TYPE_mdia || atom == Atom.TYPE_minf || atom == Atom.TYPE_stbl || atom == Atom.TYPE_moof diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java index 1386d16639..5635e76399 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java @@ -401,7 +401,7 @@ public final class Mp4Extractor implements Extractor, SeekMap { } input.skipFully((int) skipAmount); if (track.track.nalUnitLengthFieldLength != -1) { - // Zero the top three bytes of the array that we'll use to parse nal unit lengths, in case + // Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case // they're only 1 or 2 bytes long. byte[] nalLengthData = nalLength.data; nalLengthData[0] = 0; @@ -470,7 +470,7 @@ public final class Mp4Extractor implements Extractor, SeekMap { } /** - * Returns whether the extractor should parse a leaf atom with type {@code atom}. + * Returns whether the extractor should decode a leaf atom with type {@code atom}. */ private static boolean shouldParseLeafAtom(int atom) { return atom == Atom.TYPE_mdhd || atom == Atom.TYPE_mvhd || atom == Atom.TYPE_hdlr @@ -481,7 +481,7 @@ public final class Mp4Extractor implements Extractor, SeekMap { } /** - * Returns whether the extractor should parse a container atom with type {@code atom}. + * Returns whether the extractor should decode a container atom with type {@code atom}. */ private static boolean shouldParseContainerAtom(int atom) { return atom == Atom.TYPE_moov || atom == Atom.TYPE_trak || atom == Atom.TYPE_mdia diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Reader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Reader.java index 5efed42a3d..c151a35853 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Reader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/Ac3Reader.java @@ -17,8 +17,8 @@ package com.google.android.exoplayer2.extractor.ts; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.audio.Ac3Util; import com.google.android.exoplayer2.extractor.TrackOutput; -import com.google.android.exoplayer2.util.Ac3Util; import com.google.android.exoplayer2.util.ParsableBitArray; import com.google.android.exoplayer2.util.ParsableByteArray; @@ -56,7 +56,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray; * * @param output Track output for extracted samples. * @param isEac3 Whether the stream is E-AC-3 (ETSI TS 102 366 Annex E). Specify {@code false} to - * parse sample headers as AC-3. + * decode sample headers as AC-3. */ public Ac3Reader(TrackOutput output, boolean isEac3) { super(output); diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/DtsReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/DtsReader.java index 251aa12fdc..24bc0aed8d 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/DtsReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/DtsReader.java @@ -17,8 +17,8 @@ package com.google.android.exoplayer2.extractor.ts; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.audio.DtsUtil; import com.google.android.exoplayer2.extractor.TrackOutput; -import com.google.android.exoplayer2.util.DtsUtil; import com.google.android.exoplayer2.util.ParsableByteArray; /** diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H262Reader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H262Reader.java index 66c7c80a3f..09d71efdf0 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H262Reader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H262Reader.java @@ -119,7 +119,7 @@ import java.util.Collections; // passed to csdDataTargetBuffer. int bytesAlreadyPassed = lengthToStartCode < 0 ? -lengthToStartCode : 0; if (csdBuffer.onStartCode(startCodeValue, bytesAlreadyPassed)) { - // The csd data is complete, so we can parse and output the media format. + // The csd data is complete, so we can decode and output the media format. Pair result = parseCsdBuffer(csdBuffer); output.format(result.first); frameDurationUs = result.second; diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H264Reader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H264Reader.java index fc6b5e3e79..4c5997ddb7 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H264Reader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/H264Reader.java @@ -330,7 +330,7 @@ import java.util.List; } int picParameterSetId = bitArray.readUnsignedExpGolombCodedInt(); if (pps.indexOfKey(picParameterSetId) < 0) { - // We have not seen the PPS yet, so don't try to parse the slice header. + // We have not seen the PPS yet, so don't try to decode the slice header. isFilling = false; return; } diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/MpegAudioReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/MpegAudioReader.java index b023506292..ab27839b88 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/MpegAudioReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/MpegAudioReader.java @@ -18,7 +18,7 @@ package com.google.android.exoplayer2.extractor.ts; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.extractor.TrackOutput; -import com.google.android.exoplayer2.util.MpegAudioHeader; +import com.google.android.exoplayer2.extractor.MpegAudioHeader; import com.google.android.exoplayer2.util.ParsableByteArray; /** diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SeiReader.java b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SeiReader.java index 0df83d4f43..a921e4c38f 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SeiReader.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/ts/SeiReader.java @@ -18,7 +18,7 @@ package com.google.android.exoplayer2.extractor.ts; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.extractor.TrackOutput; -import com.google.android.exoplayer2.text.eia608.Eia608Parser; +import com.google.android.exoplayer2.text.eia608.Eia608Decoder; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.ParsableByteArray; @@ -51,7 +51,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray; payloadSize += b; } while (b == 0xFF); // Process the payload. - if (Eia608Parser.isSeiMessageEia608(payloadType, payloadSize, seiBuffer)) { + if (Eia608Decoder.isSeiMessageEia608(payloadType, payloadSize, seiBuffer)) { // Ignore country_code (1) + provider_code (2) + user_identifier (4) // + user_data_type_code (1). seiBuffer.skipBytes(8); diff --git a/library/src/main/java/com/google/android/exoplayer2/MediaCodecDecoderInfo.java b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java similarity index 80% rename from library/src/main/java/com/google/android/exoplayer2/MediaCodecDecoderInfo.java rename to library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java index 1e4eeb7235..f99b7fba36 100644 --- a/library/src/main/java/com/google/android/exoplayer2/MediaCodecDecoderInfo.java +++ b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java @@ -13,57 +13,59 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.mediacodec; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; import android.annotation.TargetApi; -import android.media.MediaCodecInfo; +import android.media.MediaCodec; +import android.media.MediaCodecInfo.AudioCapabilities; import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecInfo.CodecProfileLevel; +import android.media.MediaCodecInfo.VideoCapabilities; import android.util.Pair; /** - * Contains information about a media decoder. + * Contains information about a {@link MediaCodec} decoder. */ @TargetApi(16) -public final class MediaCodecDecoderInfo { +public final class MediaCodecInfo { /** * The name of the decoder. *

- * May be passed to {@link android.media.MediaCodec#createByCodecName(String)} to create an - * instance of the decoder. + * May be passed to {@link MediaCodec#createByCodecName(String)} to create an instance of the + * decoder. */ public final String name; /** * Whether the decoder supports seamless resolution switches. * - * @see MediaCodecInfo.CodecCapabilities#isFeatureSupported(String) - * @see MediaCodecInfo.CodecCapabilities#FEATURE_AdaptivePlayback + * @see CodecCapabilities#isFeatureSupported(String) + * @see CodecCapabilities#FEATURE_AdaptivePlayback */ public final boolean adaptive; private final String mimeType; private final CodecCapabilities capabilities; - public static MediaCodecDecoderInfo newPassthroughInstance(String name) { - return new MediaCodecDecoderInfo(name, null, null); + public static MediaCodecInfo newPassthroughInstance(String name) { + return new MediaCodecInfo(name, null, null); } - public static MediaCodecDecoderInfo newInstance(String name, String mimeType, + public static MediaCodecInfo newInstance(String name, String mimeType, CodecCapabilities capabilities) { - return new MediaCodecDecoderInfo(name, mimeType, capabilities); + return new MediaCodecInfo(name, mimeType, capabilities); } /** * @param name The name of the decoder. * @param capabilities The capabilities of the decoder. */ - private MediaCodecDecoderInfo(String name, String mimeType, CodecCapabilities capabilities) { + private MediaCodecInfo(String name, String mimeType, CodecCapabilities capabilities) { this.name = Assertions.checkNotNull(name); this.mimeType = mimeType; this.capabilities = capabilities; @@ -101,13 +103,12 @@ public final class MediaCodecDecoderInfo { if (!codecMimeType.equals(MimeTypes.VIDEO_H265)) { return true; } - Pair codecProfileAndLevel = - MediaCodecUtil.getHevcProfileAndLevel(codec); + Pair codecProfileAndLevel = MediaCodecUtil.getHevcProfileAndLevel(codec); if (codecProfileAndLevel == null) { // If we don't know any better, we assume that the profile and level are supported. return true; } - for (MediaCodecInfo.CodecProfileLevel capabilities : getProfileLevels()) { + for (CodecProfileLevel capabilities : getProfileLevels()) { if (capabilities.profile == codecProfileAndLevel.first && capabilities.level >= codecProfileAndLevel.second) { return true; @@ -130,7 +131,7 @@ public final class MediaCodecDecoderInfo { if (capabilities == null) { return false; } - MediaCodecInfo.VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); + VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); return videoCapabilities != null && videoCapabilities.isSizeSupported(width, height); } @@ -149,7 +150,7 @@ public final class MediaCodecDecoderInfo { if (capabilities == null) { return false; } - MediaCodecInfo.VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); + VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); return videoCapabilities != null && videoCapabilities.areSizeAndRateSupported(width, height, frameRate); } @@ -167,7 +168,7 @@ public final class MediaCodecDecoderInfo { if (capabilities == null) { return false; } - MediaCodecInfo.AudioCapabilities audioCapabilities = capabilities.getAudioCapabilities(); + AudioCapabilities audioCapabilities = capabilities.getAudioCapabilities(); return audioCapabilities != null && audioCapabilities.isSampleRateSupported(sampleRate); } @@ -184,7 +185,7 @@ public final class MediaCodecDecoderInfo { if (capabilities == null) { return false; } - MediaCodecInfo.AudioCapabilities audioCapabilities = capabilities.getAudioCapabilities(); + AudioCapabilities audioCapabilities = capabilities.getAudioCapabilities(); return audioCapabilities != null && audioCapabilities.getMaxInputChannelCount() >= channelCount; } diff --git a/library/src/main/java/com/google/android/exoplayer2/MediaCodecRenderer.java b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java similarity index 97% rename from library/src/main/java/com/google/android/exoplayer2/MediaCodecRenderer.java rename to library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java index 5e9bfe67c8..44a6cfa2c0 100644 --- a/library/src/main/java/com/google/android/exoplayer2/MediaCodecRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java @@ -13,11 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.mediacodec; -import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; +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.Renderer; +import com.google.android.exoplayer2.decoder.DecoderCounters; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSessionManager; +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.NalUnitUtil; @@ -195,7 +202,7 @@ public abstract class MediaCodecRenderer extends Renderer { private boolean outputStreamEnded; private boolean waitingForKeys; - protected CodecCounters codecCounters; + protected DecoderCounters decoderCounters; /** * @param mediaCodecSelector A decoder selector. @@ -248,16 +255,16 @@ public abstract class MediaCodecRenderer extends Renderer { throws DecoderQueryException; /** - * Returns a {@link MediaCodecDecoderInfo} for a given format. + * Returns a {@link MediaCodecInfo} for a given format. * * @param mediaCodecSelector The decoder selector. * @param format The format for which a decoder is required. * @param requiresSecureDecoder Whether a secure decoder is required. - * @return A {@link MediaCodecDecoderInfo} describing the decoder to instantiate, or null if no + * @return A {@link MediaCodecInfo} describing the decoder to instantiate, or null if no * suitable decoder exists. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ - protected MediaCodecDecoderInfo getDecoderInfo(MediaCodecSelector mediaCodecSelector, + protected MediaCodecInfo getDecoderInfo(MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder) throws DecoderQueryException { return mediaCodecSelector.getDecoderInfo(format.sampleMimeType, requiresSecureDecoder); } @@ -301,7 +308,7 @@ public abstract class MediaCodecRenderer extends Renderer { } } - MediaCodecDecoderInfo decoderInfo = null; + MediaCodecInfo decoderInfo = null; try { decoderInfo = getDecoderInfo(mediaCodecSelector, format, drmSessionRequiresSecureDecoder); if (decoderInfo == null && drmSessionRequiresSecureDecoder) { @@ -358,7 +365,7 @@ public abstract class MediaCodecRenderer extends Renderer { ? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS) : -1; inputIndex = -1; outputIndex = -1; - codecCounters.codecInitCount++; + decoderCounters.codecInitCount++; } private void throwDecoderInitError(DecoderInitializationException e) @@ -372,7 +379,7 @@ public abstract class MediaCodecRenderer extends Renderer { @Override protected void onEnabled(boolean joining) throws ExoPlaybackException { - codecCounters = new CodecCounters(); + decoderCounters = new DecoderCounters(); } @Override @@ -421,7 +428,7 @@ public abstract class MediaCodecRenderer extends Renderer { codecReceivedEos = false; codecReconfigurationState = RECONFIGURATION_STATE_NONE; codecReinitializationState = REINITIALIZATION_STATE_NONE; - codecCounters.codecReleaseCount++; + decoderCounters.codecReleaseCount++; try { codec.stop(); } finally { @@ -456,7 +463,7 @@ public abstract class MediaCodecRenderer extends Renderer { while (feedInputBuffer()) {} TraceUtil.endSection(); } - codecCounters.ensureUpdated(); + decoderCounters.ensureUpdated(); } private void readFormat() throws ExoPlaybackException { @@ -631,7 +638,7 @@ public abstract class MediaCodecRenderer extends Renderer { inputIndex = -1; codecReceivedBuffers = true; codecReconfigurationState = RECONFIGURATION_STATE_NONE; - codecCounters.inputBufferCount++; + decoderCounters.inputBufferCount++; } catch (CryptoException e) { throw ExoPlaybackException.createForRenderer(e, getIndex()); } diff --git a/library/src/main/java/com/google/android/exoplayer2/MediaCodecSelector.java b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecSelector.java similarity index 71% rename from library/src/main/java/com/google/android/exoplayer2/MediaCodecSelector.java rename to library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecSelector.java index 47f8686f34..7430147000 100644 --- a/library/src/main/java/com/google/android/exoplayer2/MediaCodecSelector.java +++ b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecSelector.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.mediacodec; -import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import android.media.MediaCodec; @@ -30,13 +30,13 @@ public interface MediaCodecSelector { MediaCodecSelector DEFAULT = new MediaCodecSelector() { @Override - public MediaCodecDecoderInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder) + public MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder) throws DecoderQueryException { return MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder); } @Override - public MediaCodecDecoderInfo getPassthroughDecoderInfo() throws DecoderQueryException { + public MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException { return MediaCodecUtil.getPassthroughDecoderInfo(); } @@ -47,20 +47,20 @@ public interface MediaCodecSelector { * * @param mimeType The mime type for which a decoder is required. * @param requiresSecureDecoder Whether a secure decoder is required. - * @return A {@link MediaCodecDecoderInfo} describing the decoder, or null if no suitable decoder + * @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder * exists. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ - MediaCodecDecoderInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder) + MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder) throws DecoderQueryException; /** * Selects a decoder to instantiate for audio passthrough. * - * @return A {@link MediaCodecDecoderInfo} describing the decoder, or null if no suitable decoder + * @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder * exists. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ - MediaCodecDecoderInfo getPassthroughDecoderInfo() throws DecoderQueryException; + MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException; } diff --git a/library/src/main/java/com/google/android/exoplayer2/MediaCodecUtil.java b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java similarity index 89% rename from library/src/main/java/com/google/android/exoplayer2/MediaCodecUtil.java rename to library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java index ef20fcb251..ddecb03df7 100644 --- a/library/src/main/java/com/google/android/exoplayer2/MediaCodecUtil.java +++ b/library/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.mediacodec; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; import android.annotation.SuppressLint; import android.annotation.TargetApi; -import android.media.MediaCodecInfo; import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecInfo.CodecProfileLevel; import android.media.MediaCodecList; @@ -58,15 +57,14 @@ public final class MediaCodecUtil { } private static final String TAG = "MediaCodecUtil"; - private static final MediaCodecDecoderInfo PASSTHROUGH_DECODER_INFO = - MediaCodecDecoderInfo.newPassthroughInstance("OMX.google.raw.decoder"); + private static final MediaCodecInfo PASSTHROUGH_DECODER_INFO = + MediaCodecInfo.newPassthroughInstance("OMX.google.raw.decoder"); private static final Map HEVC_CODEC_STRING_TO_PROFILE_LEVEL; private static final String CODEC_ID_HEV1 = "hev1"; private static final String CODEC_ID_HVC1 = "hvc1"; private static final Pattern PROFILE_PATTERN = Pattern.compile("^\\D?(\\d+)$"); - private static final HashMap> decoderInfosCache = - new HashMap<>(); + private static final HashMap> decoderInfosCache = new HashMap<>(); // Lazily initialized. private static int maxH264DecodableFrameSize = -1; @@ -94,10 +92,10 @@ public final class MediaCodecUtil { /** * Returns information about a decoder suitable for audio passthrough. ** - * @return A {@link MediaCodecDecoderInfo} describing the decoder, or null if no suitable decoder + * @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder * exists. */ - public static MediaCodecDecoderInfo getPassthroughDecoderInfo() { + public static MediaCodecInfo getPassthroughDecoderInfo() { // TODO: Return null if the raw decoder doesn't exist. return PASSTHROUGH_DECODER_INFO; } @@ -108,29 +106,29 @@ public final class MediaCodecUtil { * @param mimeType The mime type. * @param secure Whether the decoder is required to support secure decryption. Always pass false * unless secure decryption really is required. - * @return A {@link MediaCodecDecoderInfo} describing the decoder, or null if no suitable decoder + * @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder * exists. */ - public static MediaCodecDecoderInfo getDecoderInfo(String mimeType, boolean secure) + public static MediaCodecInfo getDecoderInfo(String mimeType, boolean secure) throws DecoderQueryException { - List decoderInfos = getDecoderInfos(mimeType, secure); + List decoderInfos = getDecoderInfos(mimeType, secure); return decoderInfos.isEmpty() ? null : decoderInfos.get(0); } /** - * Returns all {@link MediaCodecDecoderInfo}s for the given mime type, in the order given by + * Returns all {@link MediaCodecInfo}s for the given mime type, in the order given by * {@link MediaCodecList}. * * @param mimeType The mime type. * @param secure Whether the decoder is required to support secure decryption. Always pass false * unless secure decryption really is required. - * @return A list of all @{link MediaCodecDecoderInfo}s for the given mime type, in the order + * @return A list of all @{link MediaCodecInfo}s for the given mime type, in the order * given by {@link MediaCodecList}. */ - public static synchronized List getDecoderInfos(String mimeType, + public static synchronized List getDecoderInfos(String mimeType, boolean secure) throws DecoderQueryException { CodecKey key = new CodecKey(mimeType, secure); - List decoderInfos = decoderInfosCache.get(key); + List decoderInfos = decoderInfosCache.get(key); if (decoderInfos != null) { return decoderInfos; } @@ -152,16 +150,16 @@ public final class MediaCodecUtil { return decoderInfos; } - private static List getDecoderInfosInternal( + private static List getDecoderInfosInternal( CodecKey key, MediaCodecListCompat mediaCodecList) throws DecoderQueryException { try { - List decoderInfos = new ArrayList<>(); + List decoderInfos = new ArrayList<>(); String mimeType = key.mimeType; int numberOfCodecs = mediaCodecList.getCodecCount(); boolean secureDecodersExplicit = mediaCodecList.secureDecodersExplicit(); // Note: MediaCodecList is sorted by the framework such that the best decoders come first. for (int i = 0; i < numberOfCodecs; i++) { - MediaCodecInfo codecInfo = mediaCodecList.getCodecInfoAt(i); + android.media.MediaCodecInfo codecInfo = mediaCodecList.getCodecInfoAt(i); String codecName = codecInfo.getName(); if (isCodecUsableDecoder(codecInfo, codecName, secureDecodersExplicit)) { for (String supportedType : codecInfo.getSupportedTypes()) { @@ -172,9 +170,9 @@ public final class MediaCodecUtil { if ((secureDecodersExplicit && key.secure == secure) || (!secureDecodersExplicit && !key.secure)) { decoderInfos.add( - MediaCodecDecoderInfo.newInstance(codecName, mimeType, capabilities)); + MediaCodecInfo.newInstance(codecName, mimeType, capabilities)); } else if (!secureDecodersExplicit && secure) { - decoderInfos.add(MediaCodecDecoderInfo.newInstance(codecName + ".secure", + decoderInfos.add(MediaCodecInfo.newInstance(codecName + ".secure", mimeType, capabilities)); // It only makes sense to have one synthesized secure decoder, return immediately. return decoderInfos; @@ -205,7 +203,7 @@ public final class MediaCodecUtil { /** * Returns whether the specified codec is usable for decoding on the current device. */ - private static boolean isCodecUsableDecoder(MediaCodecInfo info, String name, + private static boolean isCodecUsableDecoder(android.media.MediaCodecInfo info, String name, boolean secureDecodersExplicit) { if (info.isEncoder() || (!secureDecodersExplicit && name.endsWith(".secure"))) { return false; @@ -277,7 +275,7 @@ public final class MediaCodecUtil { public static int maxH264DecodableFrameSize() throws DecoderQueryException { if (maxH264DecodableFrameSize == -1) { int result = 0; - MediaCodecDecoderInfo decoderInfo = getDecoderInfo(MimeTypes.VIDEO_H264, false); + MediaCodecInfo decoderInfo = getDecoderInfo(MimeTypes.VIDEO_H264, false); if (decoderInfo != null) { for (CodecProfileLevel profileLevel : decoderInfo.getProfileLevels()) { result = Math.max(avcLevelToMaxFrameSize(profileLevel.level), result); @@ -291,8 +289,8 @@ public final class MediaCodecUtil { } /** - * Returns the HEVC profile and level (as defined by {@link MediaCodecInfo.CodecProfileLevel}) - * corresponding to the given codec description string (as defined by RFC 6381). + * Returns the HEVC profile and level (as defined by {@link CodecProfileLevel}) corresponding to + * the given codec description string (as defined by RFC 6381). * * @param codec An HEVC codec description string, as defined by RFC 6381. * @return A pair (profile constant, level constant) if {@code codec} is well-formed and @@ -375,7 +373,7 @@ public final class MediaCodecUtil { * * @param index The index. */ - MediaCodecInfo getCodecInfoAt(int index); + android.media.MediaCodecInfo getCodecInfoAt(int index); /** * @return Returns whether secure decoders are explicitly listed, if present. @@ -384,7 +382,7 @@ public final class MediaCodecUtil { /** * Whether secure playback is supported for the given {@link CodecCapabilities}, which should - * have been obtained from a {@link MediaCodecInfo} obtained from this list. + * have been obtained from a {@link android.media.MediaCodecInfo} obtained from this list. */ boolean isSecurePlaybackSupported(String mimeType, CodecCapabilities capabilities); @@ -395,7 +393,7 @@ public final class MediaCodecUtil { private final int codecKind; - private MediaCodecInfo[] mediaCodecInfos; + private android.media.MediaCodecInfo[] mediaCodecInfos; public MediaCodecListCompatV21(boolean includeSecure) { codecKind = includeSecure ? MediaCodecList.ALL_CODECS : MediaCodecList.REGULAR_CODECS; @@ -408,7 +406,7 @@ public final class MediaCodecUtil { } @Override - public MediaCodecInfo getCodecInfoAt(int index) { + public android.media.MediaCodecInfo getCodecInfoAt(int index) { ensureMediaCodecInfosInitialized(); return mediaCodecInfos[index]; } @@ -440,7 +438,7 @@ public final class MediaCodecUtil { } @Override - public MediaCodecInfo getCodecInfoAt(int index) { + public android.media.MediaCodecInfo getCodecInfoAt(int index) { return MediaCodecList.getCodecInfoAt(index); } diff --git a/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataParser.java b/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataDecoder.java similarity index 63% rename from library/src/main/java/com/google/android/exoplayer2/metadata/MetadataParser.java rename to library/src/main/java/com/google/android/exoplayer2/metadata/MetadataDecoder.java index 3da41db360..d9765cf3af 100644 --- a/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataDecoder.java @@ -15,31 +15,30 @@ */ package com.google.android.exoplayer2.metadata; -import com.google.android.exoplayer2.ParserException; - +// TODO: This class should implement SimpleDecoder. /** * Parses objects of type from binary data. * * @param The type of the metadata. */ -public interface MetadataParser { +public interface MetadataDecoder { /** - * Checks whether the parser supports a given mime type. + * Checks whether the decoder supports a given mime type. * * @param mimeType A metadata mime type. * @return Whether the mime type is supported. */ - boolean canParse(String mimeType); + boolean canDecode(String mimeType); /** - * Parses metadata objects of type from the provided binary data. + * Decodes metadata objects of type from the provided binary data. * - * @param data The raw binary data from which to parse the metadata. + * @param data The raw binary data from which to decode the metadata. * @param size The size of the input data. - * @return @return A parsed metadata object of type . - * @throws ParserException If a problem occurred parsing the data. + * @return @return A decoded metadata object of type . + * @throws MetadataDecoderException If a problem occurred decoding the data. */ - T parse(byte[] data, int size) throws ParserException; + T decode(byte[] data, int size) throws MetadataDecoderException; } diff --git a/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataDecoderException.java b/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataDecoderException.java new file mode 100644 index 0000000000..496dc18da4 --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataDecoderException.java @@ -0,0 +1,31 @@ +/* + * 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.metadata; + +/** + * Thrown when an error occurs decoding metadata. + */ +public class MetadataDecoderException extends Exception { + + public MetadataDecoderException(String message) { + super(message); + } + + public MetadataDecoderException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java b/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java index 1707705a60..a35e9931a5 100644 --- a/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java @@ -16,11 +16,11 @@ package com.google.android.exoplayer2.metadata; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.Renderer; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.util.Assertions; import android.os.Handler; @@ -28,7 +28,6 @@ import android.os.Handler.Callback; import android.os.Looper; import android.os.Message; -import java.io.IOException; import java.nio.ByteBuffer; /** @@ -56,7 +55,7 @@ public final class MetadataRenderer extends Renderer implements Callback { private static final int MSG_INVOKE_RENDERER = 0; - private final MetadataParser metadataParser; + private final MetadataDecoder metadataDecoder; private final Output output; private final Handler outputHandler; private final FormatHolder formatHolder; @@ -73,12 +72,13 @@ public final class MetadataRenderer extends Renderer implements Callback { * 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 metadataDecoder A decoder for the metadata. */ - public MetadataRenderer(Output output, Looper outputLooper, MetadataParser metadataParser) { + public MetadataRenderer(Output output, Looper outputLooper, + MetadataDecoder metadataDecoder) { this.output = Assertions.checkNotNull(output); this.outputHandler = outputLooper == null ? null : new Handler(outputLooper, this); - this.metadataParser = Assertions.checkNotNull(metadataParser); + this.metadataDecoder = Assertions.checkNotNull(metadataDecoder); formatHolder = new FormatHolder(); buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL); } @@ -90,7 +90,7 @@ public final class MetadataRenderer extends Renderer implements Callback { @Override public int supportsFormat(Format format) { - return metadataParser.canParse(format.sampleMimeType) ? Renderer.FORMAT_HANDLED + return metadataDecoder.canDecode(format.sampleMimeType) ? Renderer.FORMAT_HANDLED : Renderer.FORMAT_UNSUPPORTED_TYPE; } @@ -113,8 +113,8 @@ public final class MetadataRenderer extends Renderer implements Callback { try { buffer.flip(); ByteBuffer bufferData = buffer.data; - pendingMetadata = metadataParser.parse(bufferData.array(), bufferData.limit()); - } catch (IOException e) { + pendingMetadata = metadataDecoder.decode(bufferData.array(), bufferData.limit()); + } catch (MetadataDecoderException e) { throw ExoPlaybackException.createForRenderer(e, getIndex()); } } diff --git a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Parser.java b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Decoder.java similarity index 85% rename from library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Parser.java rename to library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Decoder.java index fae9dd117d..5858f2bd89 100644 --- a/library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Parser.java +++ b/library/src/main/java/com/google/android/exoplayer2/metadata/id3/Id3Decoder.java @@ -16,7 +16,8 @@ package com.google.android.exoplayer2.metadata.id3; import com.google.android.exoplayer2.ParserException; -import com.google.android.exoplayer2.metadata.MetadataParser; +import com.google.android.exoplayer2.metadata.MetadataDecoder; +import com.google.android.exoplayer2.metadata.MetadataDecoderException; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.ParsableByteArray; @@ -28,9 +29,9 @@ import java.util.List; import java.util.Locale; /** - * Extracts individual TXXX text frames from raw ID3 data. + * Decodes individual TXXX text frames from raw ID3 data. */ -public final class Id3Parser implements MetadataParser> { +public final class Id3Decoder implements MetadataDecoder> { private static final int ID3_TEXT_ENCODING_ISO_8859_1 = 0; private static final int ID3_TEXT_ENCODING_UTF_16 = 1; @@ -38,15 +39,15 @@ public final class Id3Parser implements MetadataParser> { private static final int ID3_TEXT_ENCODING_UTF_8 = 3; @Override - public boolean canParse(String mimeType) { + public boolean canDecode(String mimeType) { return mimeType.equals(MimeTypes.APPLICATION_ID3); } @Override - public List parse(byte[] data, int size) throws ParserException { + public List decode(byte[] data, int size) throws MetadataDecoderException { List id3Frames = new ArrayList<>(); ParsableByteArray id3Data = new ParsableByteArray(data, size); - int id3Size = parseId3Header(id3Data); + int id3Size = decodeId3Header(id3Data); while (id3Size > 0) { int frameId0 = id3Data.readUnsignedByte(); @@ -64,24 +65,24 @@ public final class Id3Parser implements MetadataParser> { try { Id3Frame frame; if (frameId0 == 'T' && frameId1 == 'X' && frameId2 == 'X' && frameId3 == 'X') { - frame = parseTxxxFrame(id3Data, frameSize); + frame = decodeTxxxFrame(id3Data, frameSize); } else if (frameId0 == 'P' && frameId1 == 'R' && frameId2 == 'I' && frameId3 == 'V') { - frame = parsePrivFrame(id3Data, frameSize); + frame = decodePrivFrame(id3Data, frameSize); } else if (frameId0 == 'G' && frameId1 == 'E' && frameId2 == 'O' && frameId3 == 'B') { - frame = parseGeobFrame(id3Data, frameSize); + frame = decodeGeobFrame(id3Data, frameSize); } else if (frameId0 == 'A' && frameId1 == 'P' && frameId2 == 'I' && frameId3 == 'C') { - frame = parseApicFrame(id3Data, frameSize); + frame = decodeApicFrame(id3Data, frameSize); } else if (frameId0 == 'T') { String id = String.format(Locale.US, "%c%c%c%c", frameId0, frameId1, frameId2, frameId3); - frame = parseTextInformationFrame(id3Data, frameSize, id); + frame = decodeTextInformationFrame(id3Data, frameSize, id); } else { String id = String.format(Locale.US, "%c%c%c%c", frameId0, frameId1, frameId2, frameId3); - frame = parseBinaryFrame(id3Data, frameSize, id); + frame = decodeBinaryFrame(id3Data, frameSize, id); } id3Frames.add(frame); id3Size -= frameSize + 10 /* header size */; } catch (UnsupportedEncodingException e) { - throw new ParserException(e); + throw new MetadataDecoderException("Unsupported encoding", e); } } @@ -122,18 +123,16 @@ public final class Id3Parser implements MetadataParser> { } /** - * Parses an ID3 header. - * * @param id3Buffer A {@link ParsableByteArray} from which data should be read. * @return The size of ID3 frames in bytes, excluding the header and footer. * @throws ParserException If ID3 file identifier != "ID3". */ - private static int parseId3Header(ParsableByteArray id3Buffer) throws ParserException { + private static int decodeId3Header(ParsableByteArray id3Buffer) throws MetadataDecoderException { int id1 = id3Buffer.readUnsignedByte(); int id2 = id3Buffer.readUnsignedByte(); int id3 = id3Buffer.readUnsignedByte(); if (id1 != 'I' || id2 != 'D' || id3 != '3') { - throw new ParserException(String.format(Locale.US, + throw new MetadataDecoderException(String.format(Locale.US, "Unexpected ID3 file identifier, expected \"ID3\", actual \"%c%c%c\".", id1, id2, id3)); } id3Buffer.skipBytes(2); // Skip version. @@ -158,7 +157,7 @@ public final class Id3Parser implements MetadataParser> { return id3Size; } - private static TxxxFrame parseTxxxFrame(ParsableByteArray id3Data, int frameSize) + private static TxxxFrame decodeTxxxFrame(ParsableByteArray id3Data, int frameSize) throws UnsupportedEncodingException { int encoding = id3Data.readUnsignedByte(); String charset = getCharsetName(encoding); @@ -176,7 +175,7 @@ public final class Id3Parser implements MetadataParser> { return new TxxxFrame(description, value); } - private static PrivFrame parsePrivFrame(ParsableByteArray id3Data, int frameSize) + private static PrivFrame decodePrivFrame(ParsableByteArray id3Data, int frameSize) throws UnsupportedEncodingException { byte[] data = new byte[frameSize]; id3Data.readBytes(data, 0, frameSize); @@ -190,7 +189,7 @@ public final class Id3Parser implements MetadataParser> { return new PrivFrame(owner, privateData); } - private static GeobFrame parseGeobFrame(ParsableByteArray id3Data, int frameSize) + private static GeobFrame decodeGeobFrame(ParsableByteArray id3Data, int frameSize) throws UnsupportedEncodingException { int encoding = id3Data.readUnsignedByte(); String charset = getCharsetName(encoding); @@ -217,7 +216,7 @@ public final class Id3Parser implements MetadataParser> { return new GeobFrame(mimeType, filename, description, objectData); } - private static ApicFrame parseApicFrame(ParsableByteArray id3Data, int frameSize) + private static ApicFrame decodeApicFrame(ParsableByteArray id3Data, int frameSize) throws UnsupportedEncodingException { int encoding = id3Data.readUnsignedByte(); String charset = getCharsetName(encoding); @@ -241,7 +240,7 @@ public final class Id3Parser implements MetadataParser> { return new ApicFrame(mimeType, description, pictureType, pictureData); } - private static TextInformationFrame parseTextInformationFrame(ParsableByteArray id3Data, + private static TextInformationFrame decodeTextInformationFrame(ParsableByteArray id3Data, int frameSize, String id) throws UnsupportedEncodingException { int encoding = id3Data.readUnsignedByte(); String charset = getCharsetName(encoding); @@ -255,7 +254,8 @@ public final class Id3Parser implements MetadataParser> { return new TextInformationFrame(id, description); } - private static BinaryFrame parseBinaryFrame(ParsableByteArray id3Data, int frameSize, String id) { + private static BinaryFrame decodeBinaryFrame(ParsableByteArray id3Data, int frameSize, + String id) { byte[] frame = new byte[frameSize]; id3Data.readBytes(frame, 0, frameSize); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java b/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java index 239d6783f9..8941a62def 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java @@ -16,10 +16,10 @@ package com.google.android.exoplayer2.source; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.ParserException; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.extractor.DefaultExtractorInput; import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; import com.google.android.exoplayer2.extractor.DefaultTrackOutput; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/SampleStream.java b/library/src/main/java/com/google/android/exoplayer2/source/SampleStream.java index 24b85f7c53..f539b44942 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/SampleStream.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/SampleStream.java @@ -16,8 +16,8 @@ package com.google.android.exoplayer2.source; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.FormatHolder; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import java.io.IOException; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java b/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java index 61b9c64aac..db88ddec7b 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java @@ -16,9 +16,9 @@ package com.google.android.exoplayer2.source; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.DataSource; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java index b3744fc879..ead6888424 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java @@ -16,9 +16,9 @@ package com.google.android.exoplayer2.source.chunk; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.extractor.DefaultTrackOutput; import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.SampleStream; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ContainerMediaChunk.java b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ContainerMediaChunk.java index 00da17337b..2c8f454e8c 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ContainerMediaChunk.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ContainerMediaChunk.java @@ -29,7 +29,7 @@ import com.google.android.exoplayer2.util.Util; import java.io.IOException; /** - * A {@link BaseMediaChunk} that uses an {@link Extractor} to parse sample data. + * A {@link BaseMediaChunk} that uses an {@link Extractor} to decode sample data. */ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackMetadataOutput { @@ -109,7 +109,7 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackMe trackOutput.formatWithOffset(sampleFormat, sampleOffsetUs); extractorWrapper.init(this, trackOutput); } - // Load and parse the sample data. + // Load and decode the sample data. try { int result = Extractor.RESULT_CONTINUE; while (result == Extractor.RESULT_CONTINUE && !loadCanceled) { diff --git a/library/src/main/java/com/google/android/exoplayer2/source/chunk/InitializationChunk.java b/library/src/main/java/com/google/android/exoplayer2/source/chunk/InitializationChunk.java index 3bc2921f87..3d145cf2b9 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/chunk/InitializationChunk.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/chunk/InitializationChunk.java @@ -31,7 +31,7 @@ import com.google.android.exoplayer2.util.Util; import java.io.IOException; /** - * A {@link Chunk} that uses an {@link Extractor} to parse initialization data for single track. + * A {@link Chunk} that uses an {@link Extractor} to decode initialization data for single track. */ public final class InitializationChunk extends Chunk implements SingleTrackMetadataOutput, TrackOutput { @@ -140,7 +140,7 @@ public final class InitializationChunk extends Chunk implements SingleTrackMetad // Set the target to ourselves. extractorWrapper.init(this, this); } - // Load and parse the initialization data. + // Load and decode the initialization data. try { int result = Extractor.RESULT_CONTINUE; while (result == Extractor.RESULT_CONTINUE && !loadCanceled) { diff --git a/library/src/main/java/com/google/android/exoplayer2/source/dash/mpd/MediaPresentationDescriptionParser.java b/library/src/main/java/com/google/android/exoplayer2/source/dash/mpd/MediaPresentationDescriptionParser.java index ff870d5aa6..77a55b0285 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/dash/mpd/MediaPresentationDescriptionParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/dash/mpd/MediaPresentationDescriptionParser.java @@ -28,9 +28,9 @@ import com.google.android.exoplayer2.source.dash.mpd.SegmentBase.SingleSegmentBa import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MimeTypes; -import com.google.android.exoplayer2.util.ParserUtil; import com.google.android.exoplayer2.util.UriUtil; import com.google.android.exoplayer2.util.Util; +import com.google.android.exoplayer2.util.XmlPullParserUtil; import android.net.Uri; import android.text.TextUtils; @@ -120,16 +120,16 @@ public class MediaPresentationDescriptionParser extends DefaultHandler boolean seenFirstBaseUrl = false; do { xpp.next(); - if (ParserUtil.isStartTag(xpp, "BaseURL")) { + if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } - } else if (ParserUtil.isStartTag(xpp, "UTCTiming")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "UTCTiming")) { utcTiming = parseUtcTiming(xpp); - } else if (ParserUtil.isStartTag(xpp, "Location")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "Location")) { location = Uri.parse(xpp.nextText()); - } else if (ParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) { + } else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) { Pair periodWithDurationMs = parsePeriod(xpp, baseUrl, nextPeriodStartMs); Period period = periodWithDurationMs.first; if (period.startMs == -1) { @@ -146,7 +146,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler periods.add(period); } } - } while (!ParserUtil.isEndTag(xpp, "MPD")); + } while (!XmlPullParserUtil.isEndTag(xpp, "MPD")); if (durationMs == -1) { if (nextPeriodStartMs != -1) { @@ -193,21 +193,21 @@ public class MediaPresentationDescriptionParser extends DefaultHandler boolean seenFirstBaseUrl = false; do { xpp.next(); - if (ParserUtil.isStartTag(xpp, "BaseURL")) { + if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } - } else if (ParserUtil.isStartTag(xpp, "AdaptationSet")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "AdaptationSet")) { adaptationSets.add(parseAdaptationSet(xpp, baseUrl, segmentBase)); - } else if (ParserUtil.isStartTag(xpp, "SegmentBase")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, baseUrl, null); - } else if (ParserUtil.isStartTag(xpp, "SegmentList")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, baseUrl, null); - } else if (ParserUtil.isStartTag(xpp, "SegmentTemplate")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, baseUrl, null); } - } while (!ParserUtil.isEndTag(xpp, "Period")); + } while (!XmlPullParserUtil.isEndTag(xpp, "Period")); return Pair.create(buildPeriod(id, startMs, adaptationSets), durationMs); } @@ -237,37 +237,37 @@ public class MediaPresentationDescriptionParser extends DefaultHandler boolean seenFirstBaseUrl = false; do { xpp.next(); - if (ParserUtil.isStartTag(xpp, "BaseURL")) { + if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } - } else if (ParserUtil.isStartTag(xpp, "ContentProtection")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) { SchemeData contentProtection = parseContentProtection(xpp); if (contentProtection != null) { drmSchemeDatas.add(contentProtection); } - } else if (ParserUtil.isStartTag(xpp, "ContentComponent")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "ContentComponent")) { language = checkLanguageConsistency(language, xpp.getAttributeValue(null, "lang")); contentType = checkContentTypeConsistency(contentType, parseContentType(xpp)); - } else if (ParserUtil.isStartTag(xpp, "Representation")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) { RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs, width, height, frameRate, audioChannels, audioSamplingRate, language, segmentBase); contentType = checkContentTypeConsistency(contentType, getContentType(representationInfo.format)); representationInfos.add(representationInfo); - } else if (ParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); - } else if (ParserUtil.isStartTag(xpp, "SegmentBase")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, baseUrl, (SingleSegmentBase) segmentBase); - } else if (ParserUtil.isStartTag(xpp, "SegmentList")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, baseUrl, (SegmentList) segmentBase); - } else if (ParserUtil.isStartTag(xpp, "SegmentTemplate")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, baseUrl, (SegmentTemplate) segmentBase); - } else if (ParserUtil.isStartTag(xpp)) { + } else if (XmlPullParserUtil.isStartTag(xpp)) { parseAdaptationSetChild(xpp); } - } while (!ParserUtil.isEndTag(xpp, "AdaptationSet")); + } while (!XmlPullParserUtil.isEndTag(xpp, "AdaptationSet")); List representations = new ArrayList<>(representationInfos.size()); for (int i = 0; i < representationInfos.size(); i++) { @@ -321,7 +321,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler do { xpp.next(); // The cenc:pssh element is defined in 23001-7:2015. - if (ParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) { + if (XmlPullParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) { seenPsshElement = true; byte[] data = Base64.decode(xpp.getText(), Base64.DEFAULT); UUID uuid = PsshAtomUtil.parseUuid(data); @@ -329,7 +329,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler schemeData = new SchemeData(uuid, MimeTypes.VIDEO_MP4, data); } } - } while (!ParserUtil.isEndTag(xpp, "ContentProtection")); + } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection")); if (seenPsshElement && schemeData == null) { Log.w(TAG, "Skipped unsupported ContentProtection element"); return null; @@ -371,26 +371,26 @@ public class MediaPresentationDescriptionParser extends DefaultHandler boolean seenFirstBaseUrl = false; do { xpp.next(); - if (ParserUtil.isStartTag(xpp, "BaseURL")) { + if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) { if (!seenFirstBaseUrl) { baseUrl = parseBaseUrl(xpp, baseUrl); seenFirstBaseUrl = true; } - } else if (ParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) { audioChannels = parseAudioChannelConfiguration(xpp); - } else if (ParserUtil.isStartTag(xpp, "SegmentBase")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) { segmentBase = parseSegmentBase(xpp, baseUrl, (SingleSegmentBase) segmentBase); - } else if (ParserUtil.isStartTag(xpp, "SegmentList")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) { segmentBase = parseSegmentList(xpp, baseUrl, (SegmentList) segmentBase); - } else if (ParserUtil.isStartTag(xpp, "SegmentTemplate")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, baseUrl, (SegmentTemplate) segmentBase); - } else if (ParserUtil.isStartTag(xpp, "ContentProtection")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) { SchemeData contentProtection = parseContentProtection(xpp); if (contentProtection != null) { drmSchemeDatas.add(contentProtection); } } - } while (!ParserUtil.isEndTag(xpp, "Representation")); + } while (!XmlPullParserUtil.isEndTag(xpp, "Representation")); Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, audioSamplingRate, bandwidth, adaptationSetLanguage, codecs); @@ -453,10 +453,10 @@ public class MediaPresentationDescriptionParser extends DefaultHandler RangedUri initialization = parent != null ? parent.initialization : null; do { xpp.next(); - if (ParserUtil.isStartTag(xpp, "Initialization")) { + if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp, baseUrl); } - } while (!ParserUtil.isEndTag(xpp, "SegmentBase")); + } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentBase")); return buildSingleSegmentBase(initialization, timescale, presentationTimeOffset, baseUrl, indexStart, indexLength); @@ -483,17 +483,17 @@ public class MediaPresentationDescriptionParser extends DefaultHandler do { xpp.next(); - if (ParserUtil.isStartTag(xpp, "Initialization")) { + if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp, baseUrl); - } else if (ParserUtil.isStartTag(xpp, "SegmentTimeline")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTimeline")) { timeline = parseSegmentTimeline(xpp); - } else if (ParserUtil.isStartTag(xpp, "SegmentURL")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentURL")) { if (segments == null) { segments = new ArrayList<>(); } segments.add(parseSegmentUrl(xpp, baseUrl)); } - } while (!ParserUtil.isEndTag(xpp, "SegmentList")); + } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentList")); if (parent != null) { initialization = initialization != null ? initialization : parent.initialization; @@ -530,12 +530,12 @@ public class MediaPresentationDescriptionParser extends DefaultHandler do { xpp.next(); - if (ParserUtil.isStartTag(xpp, "Initialization")) { + if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { initialization = parseInitialization(xpp, baseUrl); - } else if (ParserUtil.isStartTag(xpp, "SegmentTimeline")) { + } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTimeline")) { timeline = parseSegmentTimeline(xpp); } - } while (!ParserUtil.isEndTag(xpp, "SegmentTemplate")); + } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentTemplate")); if (parent != null) { initialization = initialization != null ? initialization : parent.initialization; @@ -560,7 +560,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler long elapsedTime = 0; do { xpp.next(); - if (ParserUtil.isStartTag(xpp, "S")) { + if (XmlPullParserUtil.isStartTag(xpp, "S")) { elapsedTime = parseLong(xpp, "t", elapsedTime); long duration = parseLong(xpp, "d"); int count = 1 + parseInt(xpp, "r", 0); @@ -569,7 +569,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler elapsedTime += duration; } } - } while (!ParserUtil.isEndTag(xpp, "SegmentTimeline")); + } while (!XmlPullParserUtil.isEndTag(xpp, "SegmentTimeline")); return segmentTimeline; } @@ -628,7 +628,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler } do { xpp.next(); - } while (!ParserUtil.isEndTag(xpp, "AudioChannelConfiguration")); + } while (!XmlPullParserUtil.isEndTag(xpp, "AudioChannelConfiguration")); return audioChannels; } diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java index 96d11bf9f6..094104d76a 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java @@ -67,7 +67,7 @@ import java.util.concurrent.atomic.AtomicInteger; * @param endTimeUs The end time of the media contained by the chunk, in microseconds. * @param chunkIndex The index of the chunk. * @param discontinuitySequenceNumber The discontinuity sequence number of the chunk. - * @param extractor The extractor to parse samples from the data. + * @param extractor The extractor to decode samples from the data. * @param extractorNeedsInit Whether the extractor needs initializing with the target * {@link HlsSampleStreamWrapper}. * @param shouldSpliceIn Whether the samples parsed from this chunk should be spliced into any diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index a864265afe..6fe27c6fbc 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -16,9 +16,9 @@ package com.google.android.exoplayer2.source.hls; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.DecoderInputBuffer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.extractor.DefaultTrackOutput; import com.google.android.exoplayer2.extractor.DefaultTrackOutput.UpstreamFormatChangedListener; import com.google.android.exoplayer2.extractor.ExtractorOutput; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java index 742c4273ee..045500b95a 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java @@ -25,6 +25,7 @@ import com.google.android.exoplayer2.extractor.PositionHolder; import com.google.android.exoplayer2.extractor.SeekMap; import com.google.android.exoplayer2.extractor.TrackOutput; import com.google.android.exoplayer2.extractor.ts.PtsTimestampAdjuster; +import com.google.android.exoplayer2.text.TextDecoderException; import com.google.android.exoplayer2.text.webvtt.WebvttParserUtil; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.ParsableByteArray; @@ -119,7 +120,11 @@ import java.util.regex.Pattern; ParsableByteArray webvttData = new ParsableByteArray(sampleData); // Validate the first line of the header. - WebvttParserUtil.validateWebvttHeaderLine(webvttData); + try { + WebvttParserUtil.validateWebvttHeaderLine(webvttData); + } catch (TextDecoderException e) { + throw new ParserException(e); + } // Defaults to use if the header doesn't contain an X-TIMESTAMP-MAP header. long vttTimestampUs = 0; diff --git a/library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleParser.java b/library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleDecoder.java similarity index 80% rename from library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleParser.java rename to library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleDecoder.java index 5f00c45f9b..df5b6fd227 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleDecoder.java @@ -15,21 +15,20 @@ */ package com.google.android.exoplayer2.text; -import com.google.android.exoplayer2.ParserException; -import com.google.android.exoplayer2.extensions.SimpleDecoder; +import com.google.android.exoplayer2.decoder.SimpleDecoder; import java.nio.ByteBuffer; /** * Base class for subtitle parsers that use their own decode thread. */ -public abstract class SimpleSubtitleParser extends - SimpleDecoder implements - SubtitleParser { +public abstract class SimpleSubtitleDecoder extends + SimpleDecoder implements + SubtitleDecoder { private final String name; - protected SimpleSubtitleParser(String name) { + protected SimpleSubtitleDecoder(String name) { super(new SubtitleInputBuffer[2], new SubtitleOutputBuffer[2]); this.name = name; setInitialInputBufferSize(1024); @@ -61,14 +60,14 @@ public abstract class SimpleSubtitleParser extends } @Override - protected final ParserException decode(SubtitleInputBuffer inputBuffer, + protected final TextDecoderException decode(SubtitleInputBuffer inputBuffer, SubtitleOutputBuffer outputBuffer, boolean reset) { try { ByteBuffer inputData = inputBuffer.data; Subtitle subtitle = decode(inputData.array(), inputData.limit()); outputBuffer.setOutput(inputBuffer.timeUs, subtitle, inputBuffer.subsampleOffsetUs); return null; - } catch (ParserException e) { + } catch (TextDecoderException e) { return e; } } @@ -79,8 +78,8 @@ public abstract class SimpleSubtitleParser extends * @param data The data to be decoded. * @param size The size of the data. * @return A {@link Subtitle} to rendered. - * @throws ParserException A parsing exception. + * @throws TextDecoderException If a decoding error occurs. */ - protected abstract Subtitle decode(byte[] data, int size) throws ParserException; + protected abstract Subtitle decode(byte[] data, int size) throws TextDecoderException; } diff --git a/library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleOutputBuffer.java b/library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleOutputBuffer.java index 8f37b47e55..d7608e60ca 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleOutputBuffer.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/SimpleSubtitleOutputBuffer.java @@ -16,13 +16,13 @@ package com.google.android.exoplayer2.text; /** - * A {@link Subtitle} output from a subtitle parser that extends {@link SimpleSubtitleParser}. + * A {@link Subtitle} output from a subtitle parser that extends {@link SimpleSubtitleDecoder}. */ public final class SimpleSubtitleOutputBuffer extends SubtitleOutputBuffer { - private SimpleSubtitleParser owner; + private SimpleSubtitleDecoder owner; - public SimpleSubtitleOutputBuffer(SimpleSubtitleParser owner) { + public SimpleSubtitleOutputBuffer(SimpleSubtitleDecoder owner) { super(); this.owner = owner; } diff --git a/library/src/main/java/com/google/android/exoplayer2/text/SubtitleParser.java b/library/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoder.java similarity index 81% rename from library/src/main/java/com/google/android/exoplayer2/text/SubtitleParser.java rename to library/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoder.java index 223967964f..d912bbfbb2 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/SubtitleParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoder.java @@ -15,14 +15,13 @@ */ package com.google.android.exoplayer2.text; -import com.google.android.exoplayer2.ParserException; -import com.google.android.exoplayer2.extensions.Decoder; +import com.google.android.exoplayer2.decoder.Decoder; /** * Parses {@link Subtitle}s from {@link SubtitleInputBuffer}s. */ -public interface SubtitleParser extends - Decoder { +public interface SubtitleDecoder extends + Decoder { /** * Informs the parser of the current playback position. diff --git a/library/src/main/java/com/google/android/exoplayer2/text/SubtitleParserFactory.java b/library/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java similarity index 62% rename from library/src/main/java/com/google/android/exoplayer2/text/SubtitleParserFactory.java rename to library/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java index 2345917cd6..38ed29c846 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/SubtitleParserFactory.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/SubtitleDecoderFactory.java @@ -16,13 +16,19 @@ package com.google.android.exoplayer2.text; import com.google.android.exoplayer2.Format; -import com.google.android.exoplayer2.extensions.Decoder; +import com.google.android.exoplayer2.decoder.Decoder; +import com.google.android.exoplayer2.text.eia608.Eia608Decoder; +import com.google.android.exoplayer2.text.subrip.SubripDecoder; +import com.google.android.exoplayer2.text.ttml.TtmlDecoder; +import com.google.android.exoplayer2.text.tx3g.Tx3gDecoder; +import com.google.android.exoplayer2.text.webvtt.Mp4WebvttDecoder; +import com.google.android.exoplayer2.text.webvtt.WebvttDecoder; import com.google.android.exoplayer2.util.MimeTypes; /** - * A factory for {@link Decoder} instances that will parse subtitles. + * A factory for {@link Decoder} instances that will decode subtitles. */ -public interface SubtitleParserFactory { +public interface SubtitleDecoderFactory { /** * Returns whether the factory is able to instantiate a {@link Decoder} for the given @@ -40,56 +46,56 @@ public interface SubtitleParserFactory { * @return A new {@link Decoder}. * @throws IllegalArgumentException If the {@link Format} is not supported. */ - SubtitleParser createParser(Format format); + SubtitleDecoder createDecoder(Format format); /** - * Default {@link SubtitleParserFactory} implementation. + * Default {@link SubtitleDecoderFactory} implementation. *

* The formats supported by this factory are: *

    - *
  • WebVTT ({@link com.google.android.exoplayer2.text.webvtt.WebvttParser})
  • - *
  • WebVTT (MP4) ({@link com.google.android.exoplayer2.text.webvtt.Mp4WebvttParser})
  • - *
  • TTML ({@link com.google.android.exoplayer2.text.ttml.TtmlParser})
  • - *
  • SubRip ({@link com.google.android.exoplayer2.text.subrip.SubripParser})
  • - *
  • TX3G ({@link com.google.android.exoplayer2.text.tx3g.Tx3gParser})
  • - *
  • Eia608 ({@link com.google.android.exoplayer2.text.eia608.Eia608Parser})
  • + *
  • WebVTT ({@link WebvttDecoder})
  • + *
  • WebVTT (MP4) ({@link Mp4WebvttDecoder})
  • + *
  • TTML ({@link TtmlDecoder})
  • + *
  • SubRip ({@link SubripDecoder})
  • + *
  • TX3G ({@link Tx3gDecoder})
  • + *
  • Eia608 ({@link Eia608Decoder})
  • *
*/ - SubtitleParserFactory DEFAULT = new SubtitleParserFactory() { + SubtitleDecoderFactory DEFAULT = new SubtitleDecoderFactory() { @Override public boolean supportsFormat(Format format) { - return getParserClass(format.sampleMimeType) != null; + return getDecoderClass(format.sampleMimeType) != null; } @Override - public SubtitleParser createParser(Format format) { + public SubtitleDecoder createDecoder(Format format) { try { - Class clazz = getParserClass(format.sampleMimeType); + Class clazz = getDecoderClass(format.sampleMimeType); if (clazz == null) { - throw new IllegalArgumentException("Attempted to create parser for unsupported format"); + throw new IllegalArgumentException("Attempted to create decoder for unsupported format"); } - return clazz.asSubclass(SubtitleParser.class).newInstance(); + return clazz.asSubclass(SubtitleDecoder.class).getConstructor().newInstance(); } catch (Exception e) { - throw new IllegalStateException("Unexpected error instantiating parser", e); + throw new IllegalStateException("Unexpected error instantiating decoder", e); } } - private Class getParserClass(String mimeType) { + private Class getDecoderClass(String mimeType) { try { switch (mimeType) { case MimeTypes.TEXT_VTT: - return Class.forName("com.google.android.exoplayer2.text.webvtt.WebvttParser"); + return Class.forName("com.google.android.exoplayer2.text.webvtt.WebvttDecoder"); case MimeTypes.APPLICATION_TTML: - return Class.forName("com.google.android.exoplayer2.text.ttml.TtmlParser"); + return Class.forName("com.google.android.exoplayer2.text.ttml.TtmlDecoder"); case MimeTypes.APPLICATION_MP4VTT: - return Class.forName("com.google.android.exoplayer2.text.webvtt.Mp4WebvttParser"); + return Class.forName("com.google.android.exoplayer2.text.webvtt.Mp4WebvttDecoder"); case MimeTypes.APPLICATION_SUBRIP: - return Class.forName("com.google.android.exoplayer2.text.subrip.SubripParser"); + return Class.forName("com.google.android.exoplayer2.text.subrip.SubripDecoder"); case MimeTypes.APPLICATION_TX3G: - return Class.forName("com.google.android.exoplayer2.text.tx3g.Tx3gParser"); + return Class.forName("com.google.android.exoplayer2.text.tx3g.Tx3gDecoder"); case MimeTypes.APPLICATION_EIA608: - return Class.forName("com.google.android.exoplayer2.text.eia608.Eia608Parser"); + return Class.forName("com.google.android.exoplayer2.text.eia608.Eia608Decoder"); default: return null; } diff --git a/library/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java b/library/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java index bea9b63572..e0d1ee15d3 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java @@ -15,7 +15,7 @@ */ package com.google.android.exoplayer2.text; -import com.google.android.exoplayer2.DecoderInputBuffer; +import com.google.android.exoplayer2.decoder.DecoderInputBuffer; /** * An input buffer for a subtitle parser. diff --git a/library/src/main/java/com/google/android/exoplayer2/text/SubtitleOutputBuffer.java b/library/src/main/java/com/google/android/exoplayer2/text/SubtitleOutputBuffer.java index a7550e2ab9..b3470a4bb8 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/SubtitleOutputBuffer.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/SubtitleOutputBuffer.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer2.text; import com.google.android.exoplayer2.Format; -import com.google.android.exoplayer2.extensions.OutputBuffer; +import com.google.android.exoplayer2.decoder.OutputBuffer; import java.util.List; diff --git a/library/src/main/java/com/google/android/exoplayer2/text/TextDecoderException.java b/library/src/main/java/com/google/android/exoplayer2/text/TextDecoderException.java new file mode 100644 index 0000000000..9d42affd51 --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer2/text/TextDecoderException.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** + * Thrown when an error occurs decoding text data. + */ +public class TextDecoderException extends Exception { + + public TextDecoderException(String message) { + super(message); + } + + public TextDecoderException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/library/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java b/library/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java index 56eab2e8cd..04a7190adc 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java @@ -19,9 +19,7 @@ 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.extensions.Decoder; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MimeTypes; @@ -31,15 +29,14 @@ 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 Renderer} for subtitles. *

- * 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 + * Text is parsed from sample data using {@link SubtitleDecoder} instances obtained from a + * {@link SubtitleDecoderFactory}. The actual rendering of each line of text is delegated to a * {@link Output}. */ @TargetApi(16) @@ -63,12 +60,12 @@ public final class TextRenderer extends Renderer implements Callback { private final Handler outputHandler; private final Output output; - private final SubtitleParserFactory parserFactory; + private final SubtitleDecoderFactory decoderFactory; private final FormatHolder formatHolder; private boolean inputStreamEnded; private boolean outputStreamEnded; - private SubtitleParser parser; + private SubtitleDecoder decoder; private SubtitleInputBuffer nextInputBuffer; private SubtitleOutputBuffer subtitle; private SubtitleOutputBuffer nextSubtitle; @@ -83,7 +80,7 @@ public final class TextRenderer extends Renderer implements Callback { * should be invoked directly on the player's internal rendering thread. */ public TextRenderer(Output output, Looper outputLooper) { - this(output, outputLooper, SubtitleParserFactory.DEFAULT); + this(output, outputLooper, SubtitleDecoderFactory.DEFAULT); } /** @@ -93,12 +90,12 @@ public final class TextRenderer extends Renderer implements Callback { * 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. + * @param decoderFactory A factory from which to obtain {@link SubtitleDecoder} instances. */ - public TextRenderer(Output output, Looper outputLooper, SubtitleParserFactory parserFactory) { + public TextRenderer(Output output, Looper outputLooper, SubtitleDecoderFactory decoderFactory) { this.output = Assertions.checkNotNull(output); this.outputHandler = outputLooper == null ? null : new Handler(outputLooper, this); - this.parserFactory = parserFactory; + this.decoderFactory = decoderFactory; formatHolder = new FormatHolder(); } @@ -109,17 +106,17 @@ public final class TextRenderer extends Renderer implements Callback { @Override public int supportsFormat(Format format) { - return parserFactory.supportsFormat(format) ? Renderer.FORMAT_HANDLED + return decoderFactory.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(); + if (decoder != null) { + decoder.release(); } - parser = parserFactory.createParser(formats[0]); + decoder = decoderFactory.createDecoder(formats[0]); } @Override @@ -136,7 +133,7 @@ public final class TextRenderer extends Renderer implements Callback { } nextInputBuffer = null; clearOutput(); - parser.flush(); + decoder.flush(); } @Override @@ -146,10 +143,10 @@ public final class TextRenderer extends Renderer implements Callback { } if (nextSubtitle == null) { - parser.setPositionUs(positionUs); + decoder.setPositionUs(positionUs); try { - nextSubtitle = parser.dequeueOutputBuffer(); - } catch (IOException e) { + nextSubtitle = decoder.dequeueOutputBuffer(); + } catch (TextDecoderException e) { throw ExoPlaybackException.createForRenderer(e, getIndex()); } } @@ -195,7 +192,7 @@ public final class TextRenderer extends Renderer implements Callback { try { while (!inputStreamEnded) { if (nextInputBuffer == null) { - nextInputBuffer = parser.dequeueInputBuffer(); + nextInputBuffer = decoder.dequeueInputBuffer(); if (nextInputBuffer == null) { return; } @@ -211,13 +208,13 @@ public final class TextRenderer extends Renderer implements Callback { nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs; nextInputBuffer.flip(); } - parser.queueInputBuffer(nextInputBuffer); + decoder.queueInputBuffer(nextInputBuffer); nextInputBuffer = null; } else if (result == C.RESULT_NOTHING_READ) { break; } } - } catch (ParserException e) { + } catch (TextDecoderException e) { throw ExoPlaybackException.createForRenderer(e, getIndex()); } } @@ -232,8 +229,8 @@ public final class TextRenderer extends Renderer implements Callback { nextSubtitle.release(); nextSubtitle = null; } - parser.release(); - parser = null; + decoder.release(); + decoder = null; nextInputBuffer = null; clearOutput(); super.onDisabled(); diff --git a/library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608Parser.java b/library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608Decoder.java similarity index 97% rename from library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608Parser.java rename to library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608Decoder.java index 0d77b9c233..5db576caed 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608Parser.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608Decoder.java @@ -16,10 +16,10 @@ package com.google.android.exoplayer2.text.eia608; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ParserException; +import com.google.android.exoplayer2.text.SubtitleDecoder; import com.google.android.exoplayer2.text.SubtitleInputBuffer; import com.google.android.exoplayer2.text.SubtitleOutputBuffer; -import com.google.android.exoplayer2.text.SubtitleParser; +import com.google.android.exoplayer2.text.TextDecoderException; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.ParsableByteArray; @@ -29,10 +29,9 @@ import java.util.LinkedList; import java.util.TreeSet; /** - * Facilitates the extraction and parsing of EIA-608 (a.k.a. "line 21 captions" and "CEA-608") - * Closed Captions from the SEI data block from H.264. + * A {@link SubtitleDecoder} for EIA-608 (also known as "line 21 captions" and "CEA-608"). */ -public final class Eia608Parser implements SubtitleParser { +public final class Eia608Decoder implements SubtitleDecoder { private static final int NUM_INPUT_BUFFERS = 10; private static final int NUM_OUTPUT_BUFFERS = 2; @@ -184,7 +183,7 @@ public final class Eia608Parser implements SubtitleParser { private byte repeatableControlCc1; private byte repeatableControlCc2; - public Eia608Parser() { + public Eia608Decoder() { availableInputBuffers = new LinkedList<>(); for (int i = 0; i < NUM_INPUT_BUFFERS; i++) { availableInputBuffers.add(new SubtitleInputBuffer()); @@ -205,7 +204,7 @@ public final class Eia608Parser implements SubtitleParser { @Override public String getName() { - return "Eia608Parser"; + return "Eia608Decoder"; } @Override @@ -214,7 +213,7 @@ public final class Eia608Parser implements SubtitleParser { } @Override - public SubtitleInputBuffer dequeueInputBuffer() throws ParserException { + public SubtitleInputBuffer dequeueInputBuffer() throws TextDecoderException { Assertions.checkState(dequeuedInputBuffer == null); if (availableInputBuffers.isEmpty()) { return null; @@ -224,7 +223,7 @@ public final class Eia608Parser implements SubtitleParser { } @Override - public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws ParserException { + public void queueInputBuffer(SubtitleInputBuffer inputBuffer) throws TextDecoderException { Assertions.checkArgument(inputBuffer != null); Assertions.checkArgument(inputBuffer == dequeuedInputBuffer); queuedInputBuffers.add(inputBuffer); @@ -232,7 +231,7 @@ public final class Eia608Parser implements SubtitleParser { } @Override - public SubtitleOutputBuffer dequeueOutputBuffer() throws ParserException { + public SubtitleOutputBuffer dequeueOutputBuffer() throws TextDecoderException { if (availableOutputBuffers.isEmpty()) { return null; } diff --git a/library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608SubtitleOutputBuffer.java b/library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608SubtitleOutputBuffer.java index 1f025a9268..5a5796e77a 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608SubtitleOutputBuffer.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/eia608/Eia608SubtitleOutputBuffer.java @@ -19,13 +19,13 @@ import com.google.android.exoplayer2.text.Subtitle; import com.google.android.exoplayer2.text.SubtitleOutputBuffer; /** - * A {@link Subtitle} output from an {@link Eia608Parser}. + * A {@link Subtitle} output from an {@link Eia608Decoder}. */ public final class Eia608SubtitleOutputBuffer extends SubtitleOutputBuffer { - private Eia608Parser owner; + private Eia608Decoder owner; - public Eia608SubtitleOutputBuffer(Eia608Parser owner) { + public Eia608SubtitleOutputBuffer(Eia608Decoder owner) { super(); this.owner = owner; } diff --git a/library/src/main/java/com/google/android/exoplayer2/text/subrip/SubripParser.java b/library/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java similarity index 92% rename from library/src/main/java/com/google/android/exoplayer2/text/subrip/SubripParser.java rename to library/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java index df0c333ff3..72acdb90c7 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/subrip/SubripParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer2.text.subrip; import com.google.android.exoplayer2.text.Cue; -import com.google.android.exoplayer2.text.SimpleSubtitleParser; +import com.google.android.exoplayer2.text.SimpleSubtitleDecoder; import com.google.android.exoplayer2.util.LongArray; import com.google.android.exoplayer2.util.ParsableByteArray; @@ -30,11 +30,11 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * A simple SubRip parser. + * A {@link SimpleSubtitleDecoder} for SubRip. */ -public final class SubripParser extends SimpleSubtitleParser { +public final class SubripDecoder extends SimpleSubtitleDecoder { - private static final String TAG = "SubripParser"; + private static final String TAG = "SubripDecoder"; private static final Pattern SUBRIP_TIMING_LINE = Pattern.compile("(\\S*)\\s*-->\\s*(\\S*)"); private static final Pattern SUBRIP_TIMESTAMP = @@ -42,8 +42,8 @@ public final class SubripParser extends SimpleSubtitleParser { private final StringBuilder textBuilder; - public SubripParser() { - super("SubripParser"); + public SubripDecoder() { + super("SubripDecoder"); textBuilder = new StringBuilder(); } diff --git a/library/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlParser.java b/library/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlDecoder.java similarity index 90% rename from library/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlParser.java rename to library/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlDecoder.java index 3ad7a9687f..f55d8504ab 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlDecoder.java @@ -16,12 +16,12 @@ package com.google.android.exoplayer2.text.ttml; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.text.Cue; -import com.google.android.exoplayer2.text.SimpleSubtitleParser; +import com.google.android.exoplayer2.text.SimpleSubtitleDecoder; +import com.google.android.exoplayer2.text.TextDecoderException; import com.google.android.exoplayer2.util.ColorParser; -import com.google.android.exoplayer2.util.ParserUtil; import com.google.android.exoplayer2.util.Util; +import com.google.android.exoplayer2.util.XmlPullParserUtil; import android.text.Layout; import android.util.Log; @@ -40,7 +40,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * A simple TTML parser that supports DFXP presentation profile. + * A {@link SimpleSubtitleDecoder} for TTML supporting the DFXP presentation profile. *

* Supported features in this parser are: *

    @@ -60,9 +60,9 @@ import java.util.regex.Pattern; *

    * @see TTML specification */ -public final class TtmlParser extends SimpleSubtitleParser { +public final class TtmlDecoder extends SimpleSubtitleDecoder { - private static final String TAG = "TtmlParser"; + private static final String TAG = "TtmlDecoder"; private static final String TTP = "http://www.w3.org/ns/ttml#parameter"; @@ -88,8 +88,8 @@ public final class TtmlParser extends SimpleSubtitleParser { private final XmlPullParserFactory xmlParserFactory; - public TtmlParser() { - super("TtmlParser"); + public TtmlDecoder() { + super("TtmlDecoder"); try { xmlParserFactory = XmlPullParserFactory.newInstance(); xmlParserFactory.setNamespaceAware(true); @@ -99,7 +99,7 @@ public final class TtmlParser extends SimpleSubtitleParser { } @Override - protected TtmlSubtitle decode(byte[] bytes, int length) throws ParserException { + protected TtmlSubtitle decode(byte[] bytes, int length) throws TextDecoderException { try { XmlPullParser xmlParser = xmlParserFactory.newPullParser(); Map globalStyles = new HashMap<>(); @@ -132,7 +132,7 @@ public final class TtmlParser extends SimpleSubtitleParser { if (parent != null) { parent.addChild(node); } - } catch (ParserException e) { + } catch (TextDecoderException e) { Log.w(TAG, "Suppressing parser error", e); // Treat the node (and by extension, all of its children) as unsupported. unsupportedNodeDepth++; @@ -158,13 +158,14 @@ public final class TtmlParser extends SimpleSubtitleParser { } return ttmlSubtitle; } catch (XmlPullParserException xppe) { - throw new ParserException("Unable to parse source", xppe); + throw new TextDecoderException("Unable to decode source", xppe); } catch (IOException e) { throw new IllegalStateException("Unexpected error when reading input.", e); } } - private FrameAndTickRate parseFrameAndTickRates(XmlPullParser xmlParser) throws ParserException { + private FrameAndTickRate parseFrameAndTickRates(XmlPullParser xmlParser) + throws TextDecoderException { int frameRate = DEFAULT_FRAME_RATE; String frameRateString = xmlParser.getAttributeValue(TTP, "frameRate"); if (frameRateString != null) { @@ -176,7 +177,7 @@ public final class TtmlParser extends SimpleSubtitleParser { if (frameRateMultiplierString != null) { String[] parts = frameRateMultiplierString.split(" "); if (parts.length != 2) { - throw new ParserException("frameRateMultiplier doesn't have 2 parts"); + throw new TextDecoderException("frameRateMultiplier doesn't have 2 parts"); } float numerator = Integer.parseInt(parts[0]); float denominator = Integer.parseInt(parts[1]); @@ -202,8 +203,8 @@ public final class TtmlParser extends SimpleSubtitleParser { throws IOException, XmlPullParserException { do { xmlParser.next(); - if (ParserUtil.isStartTag(xmlParser, TtmlNode.TAG_STYLE)) { - String parentStyleId = ParserUtil.getAttributeValue(xmlParser, ATTR_STYLE); + if (XmlPullParserUtil.isStartTag(xmlParser, TtmlNode.TAG_STYLE)) { + String parentStyleId = XmlPullParserUtil.getAttributeValue(xmlParser, ATTR_STYLE); TtmlStyle style = parseStyleAttributes(xmlParser, new TtmlStyle()); if (parentStyleId != null) { for (String id : parseStyleIds(parentStyleId)) { @@ -213,13 +214,13 @@ public final class TtmlParser extends SimpleSubtitleParser { if (style.getId() != null) { globalStyles.put(style.getId(), style); } - } else if (ParserUtil.isStartTag(xmlParser, TtmlNode.TAG_REGION)) { + } else if (XmlPullParserUtil.isStartTag(xmlParser, TtmlNode.TAG_REGION)) { Pair ttmlRegionInfo = parseRegionAttributes(xmlParser); if (ttmlRegionInfo != null) { globalRegions.put(ttmlRegionInfo.first, ttmlRegionInfo.second); } } - } while (!ParserUtil.isEndTag(xmlParser, TtmlNode.TAG_HEAD)); + } while (!XmlPullParserUtil.isEndTag(xmlParser, TtmlNode.TAG_HEAD)); return globalStyles; } @@ -228,9 +229,9 @@ public final class TtmlParser extends SimpleSubtitleParser { * terms of percentage of the viewport. Regions that do not correctly declare origin are ignored. */ private Pair parseRegionAttributes(XmlPullParser xmlParser) { - String regionId = ParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_ID); - String regionOrigin = ParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_TTS_ORIGIN); - String regionExtent = ParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_TTS_EXTENT); + String regionId = XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_ID); + String regionOrigin = XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_TTS_ORIGIN); + String regionExtent = XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_TTS_EXTENT); if (regionOrigin == null || regionId == null) { return null; } @@ -298,7 +299,7 @@ public final class TtmlParser extends SimpleSubtitleParser { try { style = createIfNull(style); parseFontSize(attributeValue, style); - } catch (ParserException e) { + } catch (TextDecoderException e) { Log.w(TAG, "failed parsing fontSize value: '" + attributeValue + "'"); } break; @@ -358,7 +359,8 @@ public final class TtmlParser extends SimpleSubtitleParser { } private TtmlNode parseNode(XmlPullParser parser, TtmlNode parent, - Map regionMap, FrameAndTickRate frameAndTickRate) throws ParserException { + Map regionMap, FrameAndTickRate frameAndTickRate) + throws TextDecoderException { long duration = 0; long startTime = TtmlNode.UNDEFINED_TIME; long endTime = TtmlNode.UNDEFINED_TIME; @@ -436,7 +438,7 @@ public final class TtmlParser extends SimpleSubtitleParser { || tag.equals(TtmlNode.TAG_SMPTE_INFORMATION); } - private static void parseFontSize(String expression, TtmlStyle out) throws ParserException { + private static void parseFontSize(String expression, TtmlStyle out) throws TextDecoderException { String[] expressions = expression.split("\\s+"); Matcher matcher; if (expressions.length == 1) { @@ -446,7 +448,7 @@ public final class TtmlParser extends SimpleSubtitleParser { Log.w(TAG, "Multiple values in fontSize attribute. Picking the second value for vertical font" + " size and ignoring the first."); } else { - throw new ParserException("Invalid number of entries for fontSize: " + expressions.length + throw new TextDecoderException("Invalid number of entries for fontSize: " + expressions.length + "."); } @@ -463,11 +465,11 @@ public final class TtmlParser extends SimpleSubtitleParser { out.setFontSizeUnit(TtmlStyle.FONT_SIZE_UNIT_PERCENT); break; default: - throw new ParserException("Invalid unit for fontSize: '" + unit + "'."); + throw new TextDecoderException("Invalid unit for fontSize: '" + unit + "'."); } out.setFontSize(Float.valueOf(matcher.group(1))); } else { - throw new ParserException("Invalid expression for fontSize: '" + expression + "'."); + throw new TextDecoderException("Invalid expression for fontSize: '" + expression + "'."); } } @@ -480,10 +482,10 @@ public final class TtmlParser extends SimpleSubtitleParser { * @param time A string that includes the time expression. * @param frameAndTickRate The effective frame and tick rates of the stream. * @return The parsed timestamp in microseconds. - * @throws ParserException If the given string does not contain a valid time expression. + * @throws TextDecoderException If the given string does not contain a valid time expression. */ private static long parseTimeExpression(String time, FrameAndTickRate frameAndTickRate) - throws ParserException { + throws TextDecoderException { Matcher matcher = CLOCK_TIME.matcher(time); if (matcher.matches()) { String hours = matcher.group(1); @@ -531,7 +533,7 @@ public final class TtmlParser extends SimpleSubtitleParser { } return (long) (offsetSeconds * C.MICROS_PER_SECOND); } - throw new ParserException("Malformed time expression: " + time); + throw new TextDecoderException("Malformed time expression: " + time); } private static final class FrameAndTickRate { diff --git a/library/src/main/java/com/google/android/exoplayer2/text/tx3g/Tx3gParser.java b/library/src/main/java/com/google/android/exoplayer2/text/tx3g/Tx3gDecoder.java similarity index 82% rename from library/src/main/java/com/google/android/exoplayer2/text/tx3g/Tx3gParser.java rename to library/src/main/java/com/google/android/exoplayer2/text/tx3g/Tx3gDecoder.java index 211cbd3368..f3385245dc 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/tx3g/Tx3gParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/tx3g/Tx3gDecoder.java @@ -16,18 +16,18 @@ package com.google.android.exoplayer2.text.tx3g; import com.google.android.exoplayer2.text.Cue; -import com.google.android.exoplayer2.text.SimpleSubtitleParser; +import com.google.android.exoplayer2.text.SimpleSubtitleDecoder; import com.google.android.exoplayer2.text.Subtitle; /** - * A subtitle parser for tx3g. + * A {@link SimpleSubtitleDecoder} for tx3g. *

    * Currently only supports parsing of a single text track. */ -public final class Tx3gParser extends SimpleSubtitleParser { +public final class Tx3gDecoder extends SimpleSubtitleDecoder { - public Tx3gParser() { - super("Tx3gParser"); + public Tx3gDecoder() { + super("Tx3gDecoder"); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttParser.java b/library/src/main/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttDecoder.java similarity index 84% rename from library/src/main/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttParser.java rename to library/src/main/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttDecoder.java index 7655a8d973..8b1927dd0c 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/webvtt/Mp4WebvttDecoder.java @@ -15,9 +15,9 @@ */ package com.google.android.exoplayer2.text.webvtt; -import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.text.Cue; -import com.google.android.exoplayer2.text.SimpleSubtitleParser; +import com.google.android.exoplayer2.text.SimpleSubtitleDecoder; +import com.google.android.exoplayer2.text.TextDecoderException; import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.Util; @@ -26,9 +26,9 @@ import java.util.Collections; import java.util.List; /** - * A subtitle parser for Webvtt embedded in a Mp4 container file. + * A {@link SimpleSubtitleDecoder} for Webvtt embedded in a Mp4 container file. */ -public final class Mp4WebvttParser extends SimpleSubtitleParser { +public final class Mp4WebvttDecoder extends SimpleSubtitleDecoder { private static final int BOX_HEADER_SIZE = 8; @@ -39,21 +39,21 @@ public final class Mp4WebvttParser extends SimpleSubtitleParser { private final ParsableByteArray sampleData; private final WebvttCue.Builder builder; - public Mp4WebvttParser() { - super("Mp4WebvttParser"); + public Mp4WebvttDecoder() { + super("Mp4WebvttDecoder"); sampleData = new ParsableByteArray(); builder = new WebvttCue.Builder(); } @Override - protected Mp4WebvttSubtitle decode(byte[] bytes, int length) throws ParserException { + protected Mp4WebvttSubtitle decode(byte[] bytes, int length) throws TextDecoderException { // Webvtt in Mp4 samples have boxes inside of them, so we have to do a traditional box parsing: // first 4 bytes size and then 4 bytes type. sampleData.reset(bytes, length); List resultingCueList = new ArrayList<>(); while (sampleData.bytesLeft() > 0) { if (sampleData.bytesLeft() < BOX_HEADER_SIZE) { - throw new ParserException("Incomplete Mp4Webvtt Top Level box header found."); + throw new TextDecoderException("Incomplete Mp4Webvtt Top Level box header found."); } int boxSize = sampleData.readInt(); int boxType = sampleData.readInt(); @@ -68,11 +68,11 @@ public final class Mp4WebvttParser extends SimpleSubtitleParser { } private static Cue parseVttCueBox(ParsableByteArray sampleData, WebvttCue.Builder builder, - int remainingCueBoxBytes) throws ParserException { + int remainingCueBoxBytes) throws TextDecoderException { builder.reset(); while (remainingCueBoxBytes > 0) { if (remainingCueBoxBytes < BOX_HEADER_SIZE) { - throw new ParserException("Incomplete vtt cue box header found."); + throw new TextDecoderException("Incomplete vtt cue box header found."); } int boxSize = sampleData.readInt(); int boxType = sampleData.readInt(); diff --git a/library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttParser.java b/library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttDecoder.java similarity index 90% rename from library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttParser.java rename to library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttDecoder.java index 481320f8b6..f041dfc69a 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttDecoder.java @@ -15,8 +15,8 @@ */ package com.google.android.exoplayer2.text.webvtt; -import com.google.android.exoplayer2.ParserException; -import com.google.android.exoplayer2.text.SimpleSubtitleParser; +import com.google.android.exoplayer2.text.SimpleSubtitleDecoder; +import com.google.android.exoplayer2.text.TextDecoderException; import com.google.android.exoplayer2.util.ParsableByteArray; import android.text.TextUtils; @@ -25,11 +25,11 @@ import java.util.ArrayList; import java.util.List; /** - * A simple WebVTT parser. + * A {@link SimpleSubtitleDecoder} for WebVTT. *

    * @see WebVTT specification */ -public final class WebvttParser extends SimpleSubtitleParser { +public final class WebvttDecoder extends SimpleSubtitleDecoder { private static final int NO_EVENT_FOUND = -1; private static final int END_OF_FILE_FOUND = 0; @@ -45,8 +45,8 @@ public final class WebvttParser extends SimpleSubtitleParser { private final CssParser cssParser; private final List definedStyles; - public WebvttParser() { - super("WebvttParser"); + public WebvttDecoder() { + super("WebvttDecoder"); cueParser = new WebvttCueParser(); parsableWebvttData = new ParsableByteArray(); webvttCueBuilder = new WebvttCue.Builder(); @@ -55,7 +55,7 @@ public final class WebvttParser extends SimpleSubtitleParser { } @Override - protected WebvttSubtitle decode(byte[] bytes, int length) throws ParserException { + protected WebvttSubtitle decode(byte[] bytes, int length) throws TextDecoderException { parsableWebvttData.reset(bytes, length); // Initialization for consistent starting state. webvttCueBuilder.reset(); @@ -72,7 +72,7 @@ public final class WebvttParser extends SimpleSubtitleParser { skipComment(parsableWebvttData); } else if (eventFound == STYLE_BLOCK_FOUND) { if (!subtitles.isEmpty()) { - throw new ParserException("A style block was found after the first cue."); + throw new TextDecoderException("A style block was found after the first cue."); } parsableWebvttData.readLine(); // Consume the "STYLE" header. WebvttCssStyle styleBlock = cssParser.parseBlock(parsableWebvttData); diff --git a/library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttParserUtil.java b/library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttParserUtil.java index 9990177404..a7d8a5822d 100644 --- a/library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttParserUtil.java +++ b/library/src/main/java/com/google/android/exoplayer2/text/webvtt/WebvttParserUtil.java @@ -15,7 +15,7 @@ */ package com.google.android.exoplayer2.text.webvtt; -import com.google.android.exoplayer2.ParserException; +import com.google.android.exoplayer2.text.TextDecoderException; import com.google.android.exoplayer2.util.ParsableByteArray; import java.util.regex.Matcher; @@ -35,12 +35,12 @@ public final class WebvttParserUtil { * Reads and validates the first line of a WebVTT file. * * @param input The input from which the line should be read. - * @throws ParserException If the line isn't the start of a valid WebVTT file. + * @throws TextDecoderException If the line isn't the start of a valid WebVTT file. */ - public static void validateWebvttHeaderLine(ParsableByteArray input) throws ParserException { + public static void validateWebvttHeaderLine(ParsableByteArray input) throws TextDecoderException { String line = input.readLine(); if (line == null || !HEADER.matcher(line).matches()) { - throw new ParserException("Expected WEBVTT. Got " + line); + throw new TextDecoderException("Expected WEBVTT. Got " + line); } } @@ -62,10 +62,11 @@ public final class WebvttParserUtil { } /** - * Parses a percentage and returns a scaled float. - * @param s contains the number to parse. - * @return a float scaled number. 1.0 represents 100%. - * @throws NumberFormatException if the number format is invalid or does not end with '%'. + * Parses a percentage string. + * + * @param s The percentage string. + * @return The parsed value, where 1.0 represents 100%. + * @throws NumberFormatException If the percentage could not be parsed. */ public static float parsePercentage(String s) throws NumberFormatException { if (!s.endsWith("%")) { diff --git a/library/src/main/java/com/google/android/exoplayer2/util/DebugTextViewHelper.java b/library/src/main/java/com/google/android/exoplayer2/ui/DebugTextViewHelper.java similarity index 91% rename from library/src/main/java/com/google/android/exoplayer2/util/DebugTextViewHelper.java rename to library/src/main/java/com/google/android/exoplayer2/ui/DebugTextViewHelper.java index c8940364f2..3875037efb 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/DebugTextViewHelper.java +++ b/library/src/main/java/com/google/android/exoplayer2/ui/DebugTextViewHelper.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.util; +package com.google.android.exoplayer2.ui; -import com.google.android.exoplayer2.CodecCounters; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.decoder.DecoderCounters; import android.widget.TextView; @@ -116,7 +116,8 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe return ""; } return "\n" + format.sampleMimeType + "(id:" + format.id + " r:" + format.width + "x" - + format.height + getCodecCounterBufferCountString(player.getVideoCodecCounters()) + ")"; + + format.height + getDecoderCountersBufferCountString(player.getVideoDecoderCounters()) + + ")"; } private String getAudioString() { @@ -125,11 +126,11 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe return ""; } return "\n" + format.sampleMimeType + "(id:" + format.id + " hz:" + format.sampleRate + " ch:" - + format.channelCount + getCodecCounterBufferCountString(player.getAudioCodecCounters()) - + ")"; + + format.channelCount + + getDecoderCountersBufferCountString(player.getAudioDecoderCounters()) + ")"; } - private static String getCodecCounterBufferCountString(CodecCounters counters) { + private static String getDecoderCountersBufferCountString(DecoderCounters counters) { if (counters == null) { return ""; } diff --git a/library/src/main/java/com/google/android/exoplayer2/ui/PlayerControl.java b/library/src/main/java/com/google/android/exoplayer2/ui/PlayerControl.java index e0ee5dd9ae..7ffb707c8e 100644 --- a/library/src/main/java/com/google/android/exoplayer2/ui/PlayerControl.java +++ b/library/src/main/java/com/google/android/exoplayer2/ui/PlayerControl.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer2.ui; import com.google.android.exoplayer2.ExoPlayer; -import com.google.android.exoplayer2.MediaCodecAudioRenderer; +import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer; import com.google.android.exoplayer2.util.Util; import android.widget.MediaController.MediaPlayerControl; diff --git a/library/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java b/library/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java index 830b9d1600..8bffd16749 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java +++ b/library/src/main/java/com/google/android/exoplayer2/util/CodecSpecificDataUtil.java @@ -128,10 +128,10 @@ public final class CodecSpecificDataUtil { */ public static byte[] buildAacAudioSpecificConfig(int audioObjectType, int sampleRateIndex, int channelConfig) { - byte[] audioSpecificConfig = new byte[2]; - audioSpecificConfig[0] = (byte) ((audioObjectType << 3) & 0xF8 | (sampleRateIndex >> 1) & 0x07); - audioSpecificConfig[1] = (byte) ((sampleRateIndex << 7) & 0x80 | (channelConfig << 3) & 0x78); - return audioSpecificConfig; + byte[] specificConfig = new byte[2]; + specificConfig[0] = (byte) (((audioObjectType << 3) & 0xF8) | ((sampleRateIndex >> 1) & 0x07)); + specificConfig[1] = (byte) (((sampleRateIndex << 7) & 0x80) | ((channelConfig << 3) & 0x78)); + return specificConfig; } /** diff --git a/library/src/main/java/com/google/android/exoplayer2/MediaClock.java b/library/src/main/java/com/google/android/exoplayer2/util/MediaClock.java similarity index 94% rename from library/src/main/java/com/google/android/exoplayer2/MediaClock.java rename to library/src/main/java/com/google/android/exoplayer2/util/MediaClock.java index 8d1b6a627b..c6da3a50a6 100644 --- a/library/src/main/java/com/google/android/exoplayer2/MediaClock.java +++ b/library/src/main/java/com/google/android/exoplayer2/util/MediaClock.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.util; /** * Tracks the progression of media time. diff --git a/library/src/main/java/com/google/android/exoplayer2/StandaloneMediaClock.java b/library/src/main/java/com/google/android/exoplayer2/util/StandaloneMediaClock.java similarity index 94% rename from library/src/main/java/com/google/android/exoplayer2/StandaloneMediaClock.java rename to library/src/main/java/com/google/android/exoplayer2/util/StandaloneMediaClock.java index a078add858..0ae9b40869 100644 --- a/library/src/main/java/com/google/android/exoplayer2/StandaloneMediaClock.java +++ b/library/src/main/java/com/google/android/exoplayer2/util/StandaloneMediaClock.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.util; import android.os.SystemClock; @@ -21,7 +21,7 @@ import android.os.SystemClock; * A standalone {@link MediaClock}. The clock can be started, stopped and its time can be set and * retrieved. When started, this clock is based on {@link SystemClock#elapsedRealtime()}. */ -/* package */ final class StandaloneMediaClock implements MediaClock { +public final class StandaloneMediaClock implements MediaClock { private boolean started; diff --git a/library/src/main/java/com/google/android/exoplayer2/util/Util.java b/library/src/main/java/com/google/android/exoplayer2/util/Util.java index 91723ccc07..8c29d0c934 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/Util.java +++ b/library/src/main/java/com/google/android/exoplayer2/util/Util.java @@ -49,7 +49,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * Miscellaneous utility functions. + * Miscellaneous utility methods. */ public final class Util { @@ -346,7 +346,7 @@ public final class Util { /** * Parses an xs:duration attribute value, returning the parsed duration in milliseconds. * - * @param value The attribute value to parse. + * @param value The attribute value to decode. * @return The parsed duration in milliseconds. */ public static long parseXsDuration(String value) { @@ -378,7 +378,7 @@ public final class Util { * Parses an xs:dateTime attribute value, returning the parsed timestamp in milliseconds since * the epoch. * - * @param value The attribute value to parse. + * @param value The attribute value to decode. * @return The parsed timestamp in milliseconds since the epoch. */ public static long parseXsDateTime(String value) throws ParseException { diff --git a/library/src/main/java/com/google/android/exoplayer2/util/ParserUtil.java b/library/src/main/java/com/google/android/exoplayer2/util/XmlPullParserUtil.java similarity index 93% rename from library/src/main/java/com/google/android/exoplayer2/util/ParserUtil.java rename to library/src/main/java/com/google/android/exoplayer2/util/XmlPullParserUtil.java index 8e6e1251ac..e49f9d8038 100644 --- a/library/src/main/java/com/google/android/exoplayer2/util/ParserUtil.java +++ b/library/src/main/java/com/google/android/exoplayer2/util/XmlPullParserUtil.java @@ -19,11 +19,11 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; /** - * Parser utility functions. + * {@link XmlPullParser} utility methods. */ -public final class ParserUtil { +public final class XmlPullParserUtil { - private ParserUtil() {} + private XmlPullParserUtil() {} public static boolean isEndTag(XmlPullParser xpp, String name) throws XmlPullParserException { return isEndTag(xpp) && xpp.getName().equals(name); diff --git a/library/src/main/java/com/google/android/exoplayer2/MediaCodecVideoRenderer.java b/library/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java similarity index 94% rename from library/src/main/java/com/google/android/exoplayer2/MediaCodecVideoRenderer.java rename to library/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java index 26d98e2c38..70cbf8ef86 100644 --- a/library/src/main/java/com/google/android/exoplayer2/MediaCodecVideoRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java @@ -13,14 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.video; -import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; -import com.google.android.exoplayer2.VideoRendererEventListener.EventDispatcher; +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.ExoPlaybackException; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.drm.DrmSessionManager; +import com.google.android.exoplayer2.mediacodec.MediaCodecInfo; +import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer; +import com.google.android.exoplayer2.mediacodec.MediaCodecSelector; +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil; +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.Util; +import com.google.android.exoplayer2.video.VideoRendererEventListener.EventDispatcher; import android.annotation.SuppressLint; import android.annotation.TargetApi; @@ -173,7 +180,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { if (!MimeTypes.isVideo(mimeType)) { return FORMAT_UNSUPPORTED_TYPE; } - MediaCodecDecoderInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, + MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, format.requiresSecureDecryption); if (decoderInfo == null) { return FORMAT_UNSUPPORTED_SUBTYPE; @@ -205,7 +212,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { @Override protected void onEnabled(boolean joining) throws ExoPlaybackException { super.onEnabled(joining); - eventDispatcher.enabled(codecCounters); + eventDispatcher.enabled(decoderCounters); frameReleaseTimeHelper.enable(); } @@ -282,8 +289,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { try { super.onDisabled(); } finally { - codecCounters.ensureUpdated(); - eventDispatcher.disabled(codecCounters); + decoderCounters.ensureUpdated(); + eventDispatcher.disabled(decoderCounters); } } @@ -307,7 +314,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { this.surface = surface; this.reportedDrawnToSurface = false; int state = getState(); - if (state == Renderer.STATE_ENABLED || state == Renderer.STATE_STARTED) { + if (state == STATE_ENABLED || state == STATE_STARTED) { releaseCodec(); maybeInitCodec(); } @@ -403,7 +410,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { return true; } - if (getState() != Renderer.STATE_STARTED) { + if (getState() != STATE_STARTED) { return false; } @@ -458,18 +465,18 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { TraceUtil.beginSection("skipVideoBuffer"); codec.releaseOutputBuffer(bufferIndex, false); TraceUtil.endSection(); - codecCounters.skippedOutputBufferCount++; + decoderCounters.skippedOutputBufferCount++; } protected void dropOutputBuffer(MediaCodec codec, int bufferIndex) { TraceUtil.beginSection("dropVideoBuffer"); codec.releaseOutputBuffer(bufferIndex, false); TraceUtil.endSection(); - codecCounters.droppedOutputBufferCount++; + decoderCounters.droppedOutputBufferCount++; droppedFrameCount++; consecutiveDroppedFrameCount++; - codecCounters.maxConsecutiveDroppedOutputBufferCount = Math.max(consecutiveDroppedFrameCount, - codecCounters.maxConsecutiveDroppedOutputBufferCount); + decoderCounters.maxConsecutiveDroppedOutputBufferCount = Math.max(consecutiveDroppedFrameCount, + decoderCounters.maxConsecutiveDroppedOutputBufferCount); if (droppedFrameCount == maxDroppedFrameCountToNotify) { maybeNotifyDroppedFrameCount(); } @@ -480,7 +487,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { TraceUtil.beginSection("releaseOutputBuffer"); codec.releaseOutputBuffer(bufferIndex, true); TraceUtil.endSection(); - codecCounters.renderedOutputBufferCount++; + decoderCounters.renderedOutputBufferCount++; consecutiveDroppedFrameCount = 0; renderedFirstFrame = true; maybeNotifyDrawnToSurface(); @@ -492,7 +499,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { TraceUtil.beginSection("releaseOutputBuffer"); codec.releaseOutputBuffer(bufferIndex, releaseTimeNs); TraceUtil.endSection(); - codecCounters.renderedOutputBufferCount++; + decoderCounters.renderedOutputBufferCount++; consecutiveDroppedFrameCount = 0; renderedFirstFrame = true; maybeNotifyDrawnToSurface(); diff --git a/library/src/main/java/com/google/android/exoplayer2/VideoFrameReleaseTimeHelper.java b/library/src/main/java/com/google/android/exoplayer2/video/VideoFrameReleaseTimeHelper.java similarity index 99% rename from library/src/main/java/com/google/android/exoplayer2/VideoFrameReleaseTimeHelper.java rename to library/src/main/java/com/google/android/exoplayer2/video/VideoFrameReleaseTimeHelper.java index bf98117dc2..21a14269b0 100644 --- a/library/src/main/java/com/google/android/exoplayer2/VideoFrameReleaseTimeHelper.java +++ b/library/src/main/java/com/google/android/exoplayer2/video/VideoFrameReleaseTimeHelper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.video; import android.annotation.TargetApi; import android.content.Context; diff --git a/library/src/main/java/com/google/android/exoplayer2/VideoRendererEventListener.java b/library/src/main/java/com/google/android/exoplayer2/video/VideoRendererEventListener.java similarity index 90% rename from library/src/main/java/com/google/android/exoplayer2/VideoRendererEventListener.java rename to library/src/main/java/com/google/android/exoplayer2/video/VideoRendererEventListener.java index da55b24e27..d782fa56d3 100644 --- a/library/src/main/java/com/google/android/exoplayer2/VideoRendererEventListener.java +++ b/library/src/main/java/com/google/android/exoplayer2/video/VideoRendererEventListener.java @@ -13,8 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2; +package com.google.android.exoplayer2.video; +import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.Renderer; +import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.util.Assertions; import android.os.Handler; @@ -30,10 +33,10 @@ public interface VideoRendererEventListener { /** * Invoked when the renderer is enabled. * - * @param counters {@link CodecCounters} that will be updated by the renderer for as long as it + * @param counters {@link DecoderCounters} that will be updated by the renderer for as long as it * remains enabled. */ - void onVideoEnabled(CodecCounters counters); + void onVideoEnabled(DecoderCounters counters); /** * Invoked when a decoder is created. @@ -96,9 +99,9 @@ public interface VideoRendererEventListener { /** * Invoked when the renderer is disabled. * - * @param counters {@link CodecCounters} that were updated by the renderer. + * @param counters {@link DecoderCounters} that were updated by the renderer. */ - void onVideoDisabled(CodecCounters counters); + void onVideoDisabled(DecoderCounters counters); /** * Dispatches events to a {@link VideoRendererEventListener}. @@ -113,12 +116,12 @@ public interface VideoRendererEventListener { this.listener = listener; } - public void enabled(final CodecCounters codecCounters) { + public void enabled(final DecoderCounters decoderCounters) { if (listener != null) { handler.post(new Runnable() { @Override public void run() { - listener.onVideoEnabled(codecCounters); + listener.onVideoEnabled(decoderCounters); } }); } @@ -183,7 +186,7 @@ public interface VideoRendererEventListener { } } - public void disabled(final CodecCounters counters) { + public void disabled(final DecoderCounters counters) { if (listener != null) { handler.post(new Runnable() { @Override diff --git a/playbacktests/src/main/java/com/google/android/exoplayer2/playbacktests/gts/DashTest.java b/playbacktests/src/main/java/com/google/android/exoplayer2/playbacktests/gts/DashTest.java index a171d9a49c..43e09f0b34 100644 --- a/playbacktests/src/main/java/com/google/android/exoplayer2/playbacktests/gts/DashTest.java +++ b/playbacktests/src/main/java/com/google/android/exoplayer2/playbacktests/gts/DashTest.java @@ -16,15 +16,15 @@ package com.google.android.exoplayer2.playbacktests.gts; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.CodecCounters; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; -import com.google.android.exoplayer2.MediaCodecDecoderInfo; -import com.google.android.exoplayer2.MediaCodecUtil; -import com.google.android.exoplayer2.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.Renderer; +import com.google.android.exoplayer2.decoder.DecoderCounters; +import com.google.android.exoplayer2.mediacodec.MediaCodecInfo; +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil; +import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.playbacktests.util.ActionSchedule; -import com.google.android.exoplayer2.playbacktests.util.CodecCountersUtil; +import com.google.android.exoplayer2.playbacktests.util.DecoderCountersUtil; import com.google.android.exoplayer2.playbacktests.util.ExoHostedTest; import com.google.android.exoplayer2.playbacktests.util.HostActivity; import com.google.android.exoplayer2.playbacktests.util.MetricsLogger; @@ -365,7 +365,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2