Commit 71186ef1 by cblay Committed by Oliver Woodman

Improving handling of atoms with size less than header in FragmentedMp4Extractor.

These currently lead to cryptic ArrayIndexOutOfBoundsExceptions being thrown from System.arraycopy() so my proposal is to throw a more useful ParserException instead.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=142087132
parent da9c10a1
Showing with 86 additions and 314 deletions
# Release notes # # Release notes #
### r2.1.1 ###
Bugfix release only. Users of r2.1.0 and r2.0.x should proactively update to
this version.
* Fix some subtitle types (e.g. WebVTT) being displayed out of sync
([#2208](https://github.com/google/ExoPlayer/issues/2208)).
* Fix incorrect position reporting for on-demand HLS media that includes
EXT-X-PROGRAM-DATE-TIME tags
([#2224](https://github.com/google/ExoPlayer/issues/2224)).
* Fix issue where playbacks could get stuck in the initial buffering state if
over 1MB of data needs to be read to initialize the playback.
### r2.1.0 ### ### r2.1.0 ###
This release contains important bug fixes. Users of r2.0.x should proactively
update to this version.
* HLS: Support for seeking in live streams * HLS: Support for seeking in live streams
([#87](https://github.com/google/ExoPlayer/issues/87)). ([#87](https://github.com/google/ExoPlayer/issues/87)).
* HLS: Improved support: * HLS: Improved support:
......
...@@ -35,7 +35,7 @@ allprojects { ...@@ -35,7 +35,7 @@ allprojects {
releaseRepoName = 'exoplayer' releaseRepoName = 'exoplayer'
releaseUserOrg = 'google' releaseUserOrg = 'google'
releaseGroupId = 'com.google.android.exoplayer' releaseGroupId = 'com.google.android.exoplayer'
releaseVersion = 'r2.1.1' releaseVersion = 'r2.1.0'
releaseWebsite = 'https://github.com/google/ExoPlayer' releaseWebsite = 'https://github.com/google/ExoPlayer'
} }
} }
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.exoplayer2.demo" package="com.google.android.exoplayer2.demo"
android:versionCode="2101" android:versionCode="2100"
android:versionName="2.1.1"> android:versionName="2.1.0">
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
......
...@@ -183,54 +183,30 @@ ...@@ -183,54 +183,30 @@
"uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears_uhd.mpd" "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears_uhd.mpd"
}, },
{ {
"name": "WV: Secure Fullsample SD & HD (WebM,VP9)", "name": "WV: Secure SD & HD (WebM,VP9)",
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears.mpd", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
}, },
{ {
"name": "WV: Secure Fullsample SD (WebM,VP9)", "name": "WV: Secure SD (WebM,VP9)",
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_sd.mpd", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_sd.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
}, },
{ {
"name": "WV: Secure Fullsample HD (WebM,VP9)", "name": "WV: Secure HD (WebM,VP9)",
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_hd.mpd", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_hd.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
}, },
{ {
"name": "WV: Secure Fullsample UHD (WebM,VP9)", "name": "WV: Secure UHD (WebM,VP9)",
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_uhd.mpd", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_uhd.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test" "drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
}, },
{ {
"name": "WV: Secure Subsample SD & HD (WebM,VP9)",
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/subsample/24fps/tears/tears.mpd",
"drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
},
{
"name": "WV: Secure Subsample SD (WebM,VP9)",
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/subsample/24fps/tears/tears_sd.mpd",
"drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
},
{
"name": "WV: Secure Subsample HD (WebM,VP9)",
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/subsample/24fps/tears/tears_hd.mpd",
"drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
},
{
"name": "WV: Secure Subsample UHD (WebM,VP9)",
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/subsample/24fps/tears/tears_uhd.mpd",
"drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
},
{
"name": "WV: Secure Subsample (WebM, VP9 with altref)", "name": "WV: Secure Subsample (WebM, VP9 with altref)",
"uri": "https://storage.googleapis.com/widevine_test/vp9/sintel_1080p_vp9_altref_subsample/sintel_1080p_vp9_altref_subsample.mpd", "uri": "https://storage.googleapis.com/widevine_test/vp9/sintel_1080p_vp9_altref_subsample/sintel_1080p_vp9_altref_subsample.mpd",
"drm_scheme": "widevine", "drm_scheme": "widevine",
......
...@@ -31,7 +31,6 @@ import com.google.android.exoplayer2.upstream.Allocator; ...@@ -31,7 +31,6 @@ import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
...@@ -49,25 +48,12 @@ public final class ExoPlayerTest extends TestCase { ...@@ -49,25 +48,12 @@ public final class ExoPlayerTest extends TestCase {
*/ */
private static final int TIMEOUT_MS = 10000; private static final int TIMEOUT_MS = 10000;
/**
* Tests playback of a source that exposes a single period.
*/
public void testPlayToEnd() throws Exception { public void testPlayToEnd() throws Exception {
PlayerWrapper playerWrapper = new PlayerWrapper(); PlayerWrapper playerWrapper = new PlayerWrapper();
Format format = Format.createVideoSampleFormat(null, MimeTypes.VIDEO_H264, null, Format format = Format.createVideoSampleFormat(null, MimeTypes.VIDEO_H264, null,
Format.NO_VALUE, Format.NO_VALUE, 1280, 720, Format.NO_VALUE, null, null); Format.NO_VALUE, Format.NO_VALUE, 1280, 720, Format.NO_VALUE, null, null);
playerWrapper.setup(new SinglePeriodTimeline(0, false), null, format); playerWrapper.setup(new SinglePeriodTimeline(0, false), new Object(), format);
playerWrapper.blockUntilEnded(TIMEOUT_MS); playerWrapper.blockUntilEndedOrError(TIMEOUT_MS);
}
/**
* Tests playback of a source that exposes an empty timeline. Playback is expected to end without
* error.
*/
public void testPlayEmptyTimeline() throws Exception {
PlayerWrapper playerWrapper = new PlayerWrapper();
playerWrapper.setup(Timeline.EMPTY, null, null);
playerWrapper.blockUntilEnded(TIMEOUT_MS);
} }
/** /**
...@@ -84,6 +70,7 @@ public final class ExoPlayerTest extends TestCase { ...@@ -84,6 +70,7 @@ public final class ExoPlayerTest extends TestCase {
private Format expectedFormat; private Format expectedFormat;
private ExoPlayer player; private ExoPlayer player;
private Exception exception; private Exception exception;
private boolean seenPositionDiscontinuity;
public PlayerWrapper() { public PlayerWrapper() {
endedCountDownLatch = new CountDownLatch(1); endedCountDownLatch = new CountDownLatch(1);
...@@ -94,11 +81,12 @@ public final class ExoPlayerTest extends TestCase { ...@@ -94,11 +81,12 @@ public final class ExoPlayerTest extends TestCase {
// Called on the test thread. // Called on the test thread.
public void blockUntilEnded(long timeoutMs) throws Exception { public void blockUntilEndedOrError(long timeoutMs) throws Exception {
if (!endedCountDownLatch.await(timeoutMs, TimeUnit.MILLISECONDS)) { if (!endedCountDownLatch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
exception = new TimeoutException("Test playback timed out."); exception = new TimeoutException("Test playback timed out.");
} }
release(); release();
// Throw any pending exception (from playback, timing out or releasing). // Throw any pending exception (from playback, timing out or releasing).
if (exception != null) { if (exception != null) {
throw exception; throw exception;
...@@ -120,7 +108,7 @@ public final class ExoPlayerTest extends TestCase { ...@@ -120,7 +108,7 @@ public final class ExoPlayerTest extends TestCase {
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
player.prepare(new FakeMediaSource(timeline, manifest, format)); player.prepare(new FakeMediaSource(timeline, manifest, format));
} catch (Exception e) { } catch (Exception e) {
handleError(e); handlePlayerException(e);
} }
} }
}); });
...@@ -135,7 +123,7 @@ public final class ExoPlayerTest extends TestCase { ...@@ -135,7 +123,7 @@ public final class ExoPlayerTest extends TestCase {
player.release(); player.release();
} }
} catch (Exception e) { } catch (Exception e) {
handleError(e); handlePlayerException(e);
} finally { } finally {
playerThread.quit(); playerThread.quit();
} }
...@@ -144,7 +132,7 @@ public final class ExoPlayerTest extends TestCase { ...@@ -144,7 +132,7 @@ public final class ExoPlayerTest extends TestCase {
playerThread.join(); playerThread.join();
} }
private void handleError(Exception exception) { private void handlePlayerException(Exception exception) {
if (this.exception == null) { if (this.exception == null) {
this.exception = exception; this.exception = exception;
} }
...@@ -179,13 +167,20 @@ public final class ExoPlayerTest extends TestCase { ...@@ -179,13 +167,20 @@ public final class ExoPlayerTest extends TestCase {
@Override @Override
public void onPlayerError(ExoPlaybackException exception) { public void onPlayerError(ExoPlaybackException exception) {
handleError(exception); this.exception = exception;
endedCountDownLatch.countDown();
} }
@Override @Override
public void onPositionDiscontinuity() { public void onPositionDiscontinuity() {
// Should never happen. assertFalse(seenPositionDiscontinuity);
handleError(new IllegalStateException("Received position discontinuity")); assertEquals(0, player.getCurrentWindowIndex());
assertEquals(0, player.getCurrentPeriodIndex());
assertEquals(0, player.getCurrentPosition());
assertEquals(0, player.getBufferedPosition());
assertEquals(expectedTimeline, player.getCurrentTimeline());
assertEquals(expectedManifest, player.getCurrentManifest());
seenPositionDiscontinuity = true;
} }
} }
...@@ -199,16 +194,17 @@ public final class ExoPlayerTest extends TestCase { ...@@ -199,16 +194,17 @@ public final class ExoPlayerTest extends TestCase {
private final Timeline timeline; private final Timeline timeline;
private final Object manifest; private final Object manifest;
private final Format format; private final Format format;
private final ArrayList<FakeMediaPeriod> activeMediaPeriods;
private FakeMediaPeriod mediaPeriod;
private boolean preparedSource; private boolean preparedSource;
private boolean releasedPeriod;
private boolean releasedSource; private boolean releasedSource;
public FakeMediaSource(Timeline timeline, Object manifest, Format format) { public FakeMediaSource(Timeline timeline, Object manifest, Format format) {
Assertions.checkArgument(timeline.getPeriodCount() == 1);
this.timeline = timeline; this.timeline = timeline;
this.manifest = manifest; this.manifest = manifest;
this.format = format; this.format = format;
activeMediaPeriods = new ArrayList<>();
} }
@Override @Override
...@@ -225,29 +221,33 @@ public final class ExoPlayerTest extends TestCase { ...@@ -225,29 +221,33 @@ public final class ExoPlayerTest extends TestCase {
@Override @Override
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) { public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
Assertions.checkIndex(index, 0, timeline.getPeriodCount());
assertTrue(preparedSource); assertTrue(preparedSource);
assertNull(mediaPeriod);
assertFalse(releasedPeriod);
assertFalse(releasedSource); assertFalse(releasedSource);
assertEquals(0, index); assertEquals(0, index);
assertEquals(0, positionUs); assertEquals(0, positionUs);
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(format); mediaPeriod = new FakeMediaPeriod(format);
activeMediaPeriods.add(mediaPeriod);
return mediaPeriod; return mediaPeriod;
} }
@Override @Override
public void releasePeriod(MediaPeriod mediaPeriod) { public void releasePeriod(MediaPeriod mediaPeriod) {
assertTrue(preparedSource); assertTrue(preparedSource);
assertNotNull(this.mediaPeriod);
assertFalse(releasedPeriod);
assertFalse(releasedSource); assertFalse(releasedSource);
assertTrue(activeMediaPeriods.remove(mediaPeriod)); assertEquals(this.mediaPeriod, mediaPeriod);
((FakeMediaPeriod) mediaPeriod).release(); this.mediaPeriod.release();
releasedPeriod = true;
} }
@Override @Override
public void releaseSource() { public void releaseSource() {
assertTrue(preparedSource); assertTrue(preparedSource);
assertNotNull(this.mediaPeriod);
assertTrue(releasedPeriod);
assertFalse(releasedSource); assertFalse(releasedSource);
assertTrue(activeMediaPeriods.isEmpty());
releasedSource = true; releasedSource = true;
} }
...@@ -400,6 +400,7 @@ public final class ExoPlayerTest extends TestCase { ...@@ -400,6 +400,7 @@ public final class ExoPlayerTest extends TestCase {
public FakeVideoRenderer(Format expectedFormat) { public FakeVideoRenderer(Format expectedFormat) {
super(C.TRACK_TYPE_VIDEO); super(C.TRACK_TYPE_VIDEO);
Assertions.checkArgument(MimeTypes.isVideo(expectedFormat.sampleMimeType));
this.expectedFormat = expectedFormat; this.expectedFormat = expectedFormat;
} }
......
...@@ -267,12 +267,6 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { ...@@ -267,12 +267,6 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
return streamIsFinal ? C.RESULT_BUFFER_READ : C.RESULT_NOTHING_READ; return streamIsFinal ? C.RESULT_BUFFER_READ : C.RESULT_NOTHING_READ;
} }
buffer.timeUs += streamOffsetUs; buffer.timeUs += streamOffsetUs;
} else if (result == C.RESULT_FORMAT_READ) {
Format format = formatHolder.format;
if (format.subsampleOffsetUs != Format.OFFSET_SAMPLE_RELATIVE) {
format = format.copyWithSubsampleOffsetUs(format.subsampleOffsetUs + streamOffsetUs);
formatHolder.format = format;
}
} }
return result; return result;
} }
......
...@@ -97,13 +97,6 @@ public final class C { ...@@ -97,13 +97,6 @@ public final class C {
public static final int CRYPTO_MODE_AES_CBC = MediaCodec.CRYPTO_MODE_AES_CBC; public static final int CRYPTO_MODE_AES_CBC = MediaCodec.CRYPTO_MODE_AES_CBC;
/** /**
* Represents an unset {@link android.media.AudioTrack} session identifier. Equal to
* {@link AudioManager#AUDIO_SESSION_ID_GENERATE}.
*/
@SuppressWarnings("InlinedApi")
public static final int AUDIO_SESSION_ID_UNSET = AudioManager.AUDIO_SESSION_ID_GENERATE;
/**
* Represents an audio encoding, or an invalid or unset value. * Represents an audio encoding, or an invalid or unset value.
*/ */
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
......
...@@ -332,10 +332,8 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -332,10 +332,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
case ExoPlayerImplInternal.MSG_SEEK_ACK: { case ExoPlayerImplInternal.MSG_SEEK_ACK: {
if (--pendingSeekAcks == 0) { if (--pendingSeekAcks == 0) {
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj; playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
if (msg.arg1 != 0) { for (EventListener listener : listeners) {
for (EventListener listener : listeners) { listener.onPositionDiscontinuity();
listener.onPositionDiscontinuity();
}
} }
} }
break; break;
......
...@@ -559,7 +559,7 @@ import java.io.IOException; ...@@ -559,7 +559,7 @@ import java.io.IOException;
// The seek position was valid for the timeline that it was performed into, but the // The seek position was valid for the timeline that it was performed into, but the
// timeline has changed and a suitable seek position could not be resolved in the new one. // timeline has changed and a suitable seek position could not be resolved in the new one.
playbackInfo = new PlaybackInfo(0, 0); playbackInfo = new PlaybackInfo(0, 0);
eventHandler.obtainMessage(MSG_SEEK_ACK, 1, 0, playbackInfo).sendToTarget(); eventHandler.obtainMessage(MSG_SEEK_ACK, playbackInfo).sendToTarget();
// Set the internal position to (0,TIME_UNSET) so that a subsequent seek to (0,0) isn't // Set the internal position to (0,TIME_UNSET) so that a subsequent seek to (0,0) isn't
// ignored. // ignored.
playbackInfo = new PlaybackInfo(0, C.TIME_UNSET); playbackInfo = new PlaybackInfo(0, C.TIME_UNSET);
...@@ -569,7 +569,6 @@ import java.io.IOException; ...@@ -569,7 +569,6 @@ import java.io.IOException;
return; return;
} }
boolean seekPositionAdjusted = seekPosition.windowPositionUs == C.TIME_UNSET;
int periodIndex = periodPosition.first; int periodIndex = periodPosition.first;
long periodPositionUs = periodPosition.second; long periodPositionUs = periodPosition.second;
...@@ -579,13 +578,10 @@ import java.io.IOException; ...@@ -579,13 +578,10 @@ import java.io.IOException;
// Seek position equals the current position. Do nothing. // Seek position equals the current position. Do nothing.
return; return;
} }
long newPeriodPositionUs = seekToPeriodPosition(periodIndex, periodPositionUs); periodPositionUs = seekToPeriodPosition(periodIndex, periodPositionUs);
seekPositionAdjusted |= periodPositionUs != newPeriodPositionUs;
periodPositionUs = newPeriodPositionUs;
} finally { } finally {
playbackInfo = new PlaybackInfo(periodIndex, periodPositionUs); playbackInfo = new PlaybackInfo(periodIndex, periodPositionUs);
eventHandler.obtainMessage(MSG_SEEK_ACK, seekPositionAdjusted ? 1 : 0, 0, playbackInfo) eventHandler.obtainMessage(MSG_SEEK_ACK, playbackInfo).sendToTarget();
.sendToTarget();
} }
} }
...@@ -680,7 +676,6 @@ import java.io.IOException; ...@@ -680,7 +676,6 @@ import java.io.IOException;
standaloneMediaClock.stop(); standaloneMediaClock.stop();
rendererMediaClock = null; rendererMediaClock = null;
rendererMediaClockSource = null; rendererMediaClockSource = null;
rendererPositionUs = RENDERER_TIMESTAMP_OFFSET_US;
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
try { try {
ensureStopped(renderer); ensureStopped(renderer);
...@@ -828,6 +823,9 @@ import java.io.IOException; ...@@ -828,6 +823,9 @@ import java.io.IOException;
} }
private boolean haveSufficientBuffer(boolean rebuffering) { private boolean haveSufficientBuffer(boolean rebuffering) {
if (loadingPeriodHolder == null) {
return false;
}
long loadingPeriodBufferedPositionUs = !loadingPeriodHolder.prepared long loadingPeriodBufferedPositionUs = !loadingPeriodHolder.prepared
? loadingPeriodHolder.startPositionUs ? loadingPeriodHolder.startPositionUs
: loadingPeriodHolder.mediaPeriod.getBufferedPositionUs(); : loadingPeriodHolder.mediaPeriod.getBufferedPositionUs();
...@@ -1289,8 +1287,7 @@ import java.io.IOException; ...@@ -1289,8 +1287,7 @@ import java.io.IOException;
} }
private void maybeContinueLoading() { private void maybeContinueLoading() {
long nextLoadPositionUs = !loadingPeriodHolder.prepared ? 0 long nextLoadPositionUs = loadingPeriodHolder.mediaPeriod.getNextLoadPositionUs();
: loadingPeriodHolder.mediaPeriod.getNextLoadPositionUs();
if (nextLoadPositionUs == C.TIME_END_OF_SOURCE) { if (nextLoadPositionUs == C.TIME_END_OF_SOURCE) {
setIsLoading(false); setIsLoading(false);
} else { } else {
......
...@@ -23,7 +23,7 @@ public interface ExoPlayerLibraryInfo { ...@@ -23,7 +23,7 @@ public interface ExoPlayerLibraryInfo {
/** /**
* The version of the library, expressed as a string. * The version of the library, expressed as a string.
*/ */
String VERSION = "2.1.1"; String VERSION = "2.1.0";
/** /**
* The version of the library, expressed as an integer. * The version of the library, expressed as an integer.
...@@ -32,7 +32,7 @@ public interface ExoPlayerLibraryInfo { ...@@ -32,7 +32,7 @@ public interface ExoPlayerLibraryInfo {
* corresponding integer version 1002003 (001-002-003), and "123.45.6" has the corresponding * corresponding integer version 1002003 (001-002-003), and "123.45.6" has the corresponding
* integer version 123045006 (123-045-006). * integer version 123045006 (123-045-006).
*/ */
int VERSION_INT = 2001001; int VERSION_INT = 2001000;
/** /**
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions} * Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}
......
...@@ -29,6 +29,7 @@ import android.view.SurfaceView; ...@@ -29,6 +29,7 @@ import android.view.SurfaceView;
import android.view.TextureView; import android.view.TextureView;
import com.google.android.exoplayer2.audio.AudioCapabilities; import com.google.android.exoplayer2.audio.AudioCapabilities;
import com.google.android.exoplayer2.audio.AudioRendererEventListener; 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.audio.MediaCodecAudioRenderer;
import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
...@@ -177,7 +178,7 @@ public class SimpleExoPlayer implements ExoPlayer { ...@@ -177,7 +178,7 @@ public class SimpleExoPlayer implements ExoPlayer {
// Set initial values. // Set initial values.
audioVolume = 1; audioVolume = 1;
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
audioStreamType = C.STREAM_TYPE_DEFAULT; audioStreamType = C.STREAM_TYPE_DEFAULT;
videoScalingMode = C.VIDEO_SCALING_MODE_DEFAULT; videoScalingMode = C.VIDEO_SCALING_MODE_DEFAULT;
...@@ -392,7 +393,7 @@ public class SimpleExoPlayer implements ExoPlayer { ...@@ -392,7 +393,7 @@ public class SimpleExoPlayer implements ExoPlayer {
} }
/** /**
* Returns the audio session identifier, or {@link C#AUDIO_SESSION_ID_UNSET} if not set. * Returns the audio session identifier, or {@code AudioTrack.SESSION_ID_NOT_SET} if not set.
*/ */
public int getAudioSessionId() { public int getAudioSessionId() {
return audioSessionId; return audioSessionId;
...@@ -948,7 +949,7 @@ public class SimpleExoPlayer implements ExoPlayer { ...@@ -948,7 +949,7 @@ public class SimpleExoPlayer implements ExoPlayer {
} }
audioFormat = null; audioFormat = null;
audioDecoderCounters = null; audioDecoderCounters = null;
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
} }
// TextRenderer.Output implementation // TextRenderer.Output implementation
......
...@@ -129,7 +129,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -129,7 +129,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
boolean playClearSamplesWithoutKeys, Handler eventHandler, boolean playClearSamplesWithoutKeys, Handler eventHandler,
AudioRendererEventListener eventListener, AudioCapabilities audioCapabilities) { AudioRendererEventListener eventListener, AudioCapabilities audioCapabilities) {
super(C.TRACK_TYPE_AUDIO, mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys); super(C.TRACK_TYPE_AUDIO, mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys);
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
audioTrack = new AudioTrack(audioCapabilities, this); audioTrack = new AudioTrack(audioCapabilities, this);
eventDispatcher = new EventDispatcher(eventHandler, eventListener); eventDispatcher = new EventDispatcher(eventHandler, eventListener);
} }
...@@ -274,7 +274,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -274,7 +274,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override @Override
protected void onDisabled() { protected void onDisabled() {
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
try { try {
audioTrack.release(); audioTrack.release();
} finally { } finally {
...@@ -328,8 +328,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -328,8 +328,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
if (!audioTrack.isInitialized()) { if (!audioTrack.isInitialized()) {
// Initialize the AudioTrack now. // Initialize the AudioTrack now.
try { try {
if (audioSessionId == C.AUDIO_SESSION_ID_UNSET) { if (audioSessionId == AudioTrack.SESSION_ID_NOT_SET) {
audioSessionId = audioTrack.initialize(C.AUDIO_SESSION_ID_UNSET); audioSessionId = audioTrack.initialize(AudioTrack.SESSION_ID_NOT_SET);
eventDispatcher.audioSessionId(audioSessionId); eventDispatcher.audioSessionId(audioSessionId);
onAudioSessionId(audioSessionId); onAudioSessionId(audioSessionId);
} else { } else {
...@@ -387,7 +387,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -387,7 +387,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
case C.MSG_SET_STREAM_TYPE: case C.MSG_SET_STREAM_TYPE:
@C.StreamType int streamType = (Integer) message; @C.StreamType int streamType = (Integer) message;
if (audioTrack.setStreamType(streamType)) { if (audioTrack.setStreamType(streamType)) {
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
} }
break; break;
default: default:
......
...@@ -145,7 +145,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements ...@@ -145,7 +145,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
this.drmSessionManager = drmSessionManager; this.drmSessionManager = drmSessionManager;
formatHolder = new FormatHolder(); formatHolder = new FormatHolder();
this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys; this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys;
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
decoderReinitializationState = REINITIALIZATION_STATE_NONE; decoderReinitializationState = REINITIALIZATION_STATE_NONE;
audioTrackNeedsConfigure = true; audioTrackNeedsConfigure = true;
} }
...@@ -245,8 +245,8 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements ...@@ -245,8 +245,8 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
} }
if (!audioTrack.isInitialized()) { if (!audioTrack.isInitialized()) {
if (audioSessionId == C.AUDIO_SESSION_ID_UNSET) { if (audioSessionId == AudioTrack.SESSION_ID_NOT_SET) {
audioSessionId = audioTrack.initialize(C.AUDIO_SESSION_ID_UNSET); audioSessionId = audioTrack.initialize(AudioTrack.SESSION_ID_NOT_SET);
eventDispatcher.audioSessionId(audioSessionId); eventDispatcher.audioSessionId(audioSessionId);
onAudioSessionId(audioSessionId); onAudioSessionId(audioSessionId);
} else { } else {
...@@ -425,7 +425,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements ...@@ -425,7 +425,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
@Override @Override
protected void onDisabled() { protected void onDisabled() {
inputFormat = null; inputFormat = null;
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
audioTrackNeedsConfigure = true; audioTrackNeedsConfigure = true;
waitingForKeys = false; waitingForKeys = false;
try { try {
...@@ -554,7 +554,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements ...@@ -554,7 +554,7 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
case C.MSG_SET_STREAM_TYPE: case C.MSG_SET_STREAM_TYPE:
@C.StreamType int streamType = (Integer) message; @C.StreamType int streamType = (Integer) message;
if (audioTrack.setStreamType(streamType)) { if (audioTrack.setStreamType(streamType)) {
audioSessionId = C.AUDIO_SESSION_ID_UNSET; audioSessionId = AudioTrack.SESSION_ID_NOT_SET;
} }
break; break;
default: default:
......
...@@ -244,7 +244,7 @@ import java.io.IOException; ...@@ -244,7 +244,7 @@ import java.io.IOException;
@Override @Override
public long getNextLoadPositionUs() { public long getNextLoadPositionUs() {
return enabledTrackCount == 0 ? C.TIME_END_OF_SOURCE : getBufferedPositionUs(); return getBufferedPositionUs();
} }
@Override @Override
......
...@@ -133,32 +133,4 @@ public interface MediaPeriod extends SequenceableLoader { ...@@ -133,32 +133,4 @@ public interface MediaPeriod extends SequenceableLoader {
*/ */
long seekToUs(long positionUs); long seekToUs(long positionUs);
// SequenceableLoader interface. Overridden to provide more specific documentation.
/**
* Returns the next load time, or {@link C#TIME_END_OF_SOURCE} if loading has finished.
* <p>
* This method should only be called after the period has been prepared. It may be called when no
* tracks are selected.
*/
@Override
long getNextLoadPositionUs();
/**
* Attempts to continue loading.
* <p>
* This method may be called both during and after the period has been prepared.
* <p>
* A period may call {@link Callback#onContinueLoadingRequested(SequenceableLoader)} on the
* {@link Callback} passed to {@link #prepare(Callback)} to request that this method be called
* when the period is permitted to continue loading data. A period may do this both during and
* after preparation.
*
* @param positionUs The current playback position.
* @return True if progress was made, meaning that {@link #getNextLoadPositionUs()} will return
* a different value than prior to the call. False otherwise.
*/
@Override
boolean continueLoading(long positionUs);
} }
...@@ -104,14 +104,15 @@ public final class HlsMediaSource implements MediaSource, ...@@ -104,14 +104,15 @@ public final class HlsMediaSource implements MediaSource,
SinglePeriodTimeline timeline; SinglePeriodTimeline timeline;
if (playlistTracker.isLive()) { if (playlistTracker.isLive()) {
// TODO: fix windowPositionInPeriodUs when playlist is empty. // TODO: fix windowPositionInPeriodUs when playlist is empty.
long windowPositionInPeriodUs = playlist.startTimeUs;
List<HlsMediaPlaylist.Segment> segments = playlist.segments; List<HlsMediaPlaylist.Segment> segments = playlist.segments;
long windowDefaultStartPositionUs = segments.isEmpty() ? 0 long windowDefaultStartPositionUs = segments.isEmpty() ? 0
: segments.get(Math.max(0, segments.size() - 3)).relativeStartTimeUs; : segments.get(Math.max(0, segments.size() - 3)).relativeStartTimeUs;
timeline = new SinglePeriodTimeline(C.TIME_UNSET, playlist.durationUs, timeline = new SinglePeriodTimeline(C.TIME_UNSET, playlist.durationUs,
playlist.startTimeUs, windowDefaultStartPositionUs, true, !playlist.hasEndTag); windowPositionInPeriodUs, windowDefaultStartPositionUs, true, !playlist.hasEndTag);
} else /* not live */ { } else /* not live */ {
timeline = new SinglePeriodTimeline(playlist.startTimeUs + playlist.durationUs, timeline = new SinglePeriodTimeline(playlist.durationUs, playlist.durationUs, 0, 0, true,
playlist.durationUs, playlist.startTimeUs, 0, true, false); false);
} }
sourceListener.onSourceInfoRefreshed(timeline, playlist); sourceListener.onSourceInfoRefreshed(timeline, playlist);
} }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
*/ */
package com.google.android.exoplayer2.text; package com.google.android.exoplayer2.text;
import android.graphics.Color;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.text.Layout.Alignment; import android.text.Layout.Alignment;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
...@@ -37,23 +36,19 @@ public class Cue { ...@@ -37,23 +36,19 @@ public class Cue {
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_UNSET, ANCHOR_TYPE_START, ANCHOR_TYPE_MIDDLE, ANCHOR_TYPE_END}) @IntDef({TYPE_UNSET, ANCHOR_TYPE_START, ANCHOR_TYPE_MIDDLE, ANCHOR_TYPE_END})
public @interface AnchorType {} public @interface AnchorType {}
/** /**
* An unset anchor or line type value. * An unset anchor or line type value.
*/ */
public static final int TYPE_UNSET = Integer.MIN_VALUE; public static final int TYPE_UNSET = Integer.MIN_VALUE;
/** /**
* Anchors the left (for horizontal positions) or top (for vertical positions) edge of the cue * Anchors the left (for horizontal positions) or top (for vertical positions) edge of the cue
* box. * box.
*/ */
public static final int ANCHOR_TYPE_START = 0; public static final int ANCHOR_TYPE_START = 0;
/** /**
* Anchors the middle of the cue box. * Anchors the middle of the cue box.
*/ */
public static final int ANCHOR_TYPE_MIDDLE = 1; public static final int ANCHOR_TYPE_MIDDLE = 1;
/** /**
* Anchors the right (for horizontal positions) or bottom (for vertical positions) edge of the cue * Anchors the right (for horizontal positions) or bottom (for vertical positions) edge of the cue
* box. * box.
...@@ -66,12 +61,10 @@ public class Cue { ...@@ -66,12 +61,10 @@ public class Cue {
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_UNSET, LINE_TYPE_FRACTION, LINE_TYPE_NUMBER}) @IntDef({TYPE_UNSET, LINE_TYPE_FRACTION, LINE_TYPE_NUMBER})
public @interface LineType {} public @interface LineType {}
/** /**
* Value for {@link #lineType} when {@link #line} is a fractional position. * Value for {@link #lineType} when {@link #line} is a fractional position.
*/ */
public static final int LINE_TYPE_FRACTION = 0; public static final int LINE_TYPE_FRACTION = 0;
/** /**
* Value for {@link #lineType} when {@link #line} is a line number. * Value for {@link #lineType} when {@link #line} is a line number.
*/ */
...@@ -81,12 +74,10 @@ public class Cue { ...@@ -81,12 +74,10 @@ public class Cue {
* The cue text. Note the {@link CharSequence} may be decorated with styling spans. * The cue text. Note the {@link CharSequence} may be decorated with styling spans.
*/ */
public final CharSequence text; public final CharSequence text;
/** /**
* The alignment of the cue text within the cue box, or null if the alignment is undefined. * The alignment of the cue text within the cue box, or null if the alignment is undefined.
*/ */
public final Alignment textAlignment; public final Alignment textAlignment;
/** /**
* The position of the {@link #lineAnchor} of the cue box within the viewport in the direction * The position of the {@link #lineAnchor} of the cue box within the viewport in the direction
* orthogonal to the writing direction, or {@link #DIMEN_UNSET}. When set, the interpretation of * orthogonal to the writing direction, or {@link #DIMEN_UNSET}. When set, the interpretation of
...@@ -95,7 +86,6 @@ public class Cue { ...@@ -95,7 +86,6 @@ public class Cue {
* For horizontal text and {@link #lineType} equal to {@link #LINE_TYPE_FRACTION}, this is the * For horizontal text and {@link #lineType} equal to {@link #LINE_TYPE_FRACTION}, this is the
* fractional vertical position relative to the top of the viewport. * fractional vertical position relative to the top of the viewport.
*/ */
public final float line; public final float line;
/** /**
* The type of the {@link #line} value. * The type of the {@link #line} value.
...@@ -122,7 +112,6 @@ public class Cue { ...@@ -122,7 +112,6 @@ public class Cue {
* {@code (line == -2 && lineAnchor == ANCHOR_TYPE_START)} position a cue so that only its first * {@code (line == -2 && lineAnchor == ANCHOR_TYPE_START)} position a cue so that only its first
* line is visible at the bottom of the viewport. * line is visible at the bottom of the viewport.
*/ */
@LineType @LineType
public final int lineType; public final int lineType;
/** /**
...@@ -133,7 +122,6 @@ public class Cue { ...@@ -133,7 +122,6 @@ public class Cue {
* and {@link #ANCHOR_TYPE_END} correspond to the top, middle and bottom of the cue box * and {@link #ANCHOR_TYPE_END} correspond to the top, middle and bottom of the cue box
* respectively. * respectively.
*/ */
@AnchorType @AnchorType
public final int lineAnchor; public final int lineAnchor;
/** /**
...@@ -145,7 +133,6 @@ public class Cue { ...@@ -145,7 +133,6 @@ public class Cue {
* text. * text.
*/ */
public final float position; public final float position;
/** /**
* The cue box anchor positioned by {@link #position}. One of {@link #ANCHOR_TYPE_START}, * The cue box anchor positioned by {@link #position}. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}. * {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
...@@ -156,7 +143,6 @@ public class Cue { ...@@ -156,7 +143,6 @@ public class Cue {
*/ */
@AnchorType @AnchorType
public final int positionAnchor; public final int positionAnchor;
/** /**
* The size of the cue box in the writing direction specified as a fraction of the viewport size * The size of the cue box in the writing direction specified as a fraction of the viewport size
* in that direction, or {@link #DIMEN_UNSET}. * in that direction, or {@link #DIMEN_UNSET}.
...@@ -164,16 +150,6 @@ public class Cue { ...@@ -164,16 +150,6 @@ public class Cue {
public final float size; public final float size;
/** /**
* Specifies whether or not the {@link #windowColor} property is set.
*/
public final boolean windowColorSet;
/**
* The fill color of the window.
*/
public final int windowColor;
/**
* Constructs a cue whose {@link #textAlignment} is null, whose type parameters are set to * Constructs a cue whose {@link #textAlignment} is null, whose type parameters are set to
* {@link #TYPE_UNSET} and whose dimension parameters are set to {@link #DIMEN_UNSET}. * {@link #TYPE_UNSET} and whose dimension parameters are set to {@link #DIMEN_UNSET}.
* *
...@@ -195,25 +171,6 @@ public class Cue { ...@@ -195,25 +171,6 @@ public class Cue {
*/ */
public Cue(CharSequence text, Alignment textAlignment, float line, @LineType int lineType, public Cue(CharSequence text, Alignment textAlignment, float line, @LineType int lineType,
@AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size) { @AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size) {
this(text, textAlignment, line, lineType, lineAnchor, position, positionAnchor, size, false,
Color.BLACK);
}
/**
* @param text See {@link #text}.
* @param textAlignment See {@link #textAlignment}.
* @param line See {@link #line}.
* @param lineType See {@link #lineType}.
* @param lineAnchor See {@link #lineAnchor}.
* @param position See {@link #position}.
* @param positionAnchor See {@link #positionAnchor}.
* @param size See {@link #size}.
* @param windowColorSet See {@link #windowColorSet}.
* @param windowColor See {@link #windowColor}.
*/
public Cue(CharSequence text, Alignment textAlignment, float line, @LineType int lineType,
@AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size,
boolean windowColorSet, int windowColor) {
this.text = text; this.text = text;
this.textAlignment = textAlignment; this.textAlignment = textAlignment;
this.line = line; this.line = line;
...@@ -222,8 +179,6 @@ public class Cue { ...@@ -222,8 +179,6 @@ public class Cue {
this.position = position; this.position = position;
this.positionAnchor = positionAnchor; this.positionAnchor = positionAnchor;
this.size = size; this.size = size;
this.windowColorSet = windowColorSet;
this.windowColor = windowColor;
} }
} }
...@@ -65,13 +65,6 @@ import java.util.List; ...@@ -65,13 +65,6 @@ import java.util.List;
* <li>Default: {@code true}</li> * <li>Default: {@code true}</li>
* </ul> * </ul>
* </li> * </li>
* <li><b>{@code default_artwork}</b> - Default artwork to use if no artwork available in audio
* streams.
* <ul>
* <li>Corresponding method: {@link #setDefaultArtwork(Bitmap)}</li>
* <li>Default: {@code null}</li>
* </ul>
* </li>
* <li><b>{@code use_controller}</b> - Whether playback controls are displayed. * <li><b>{@code use_controller}</b> - Whether playback controls are displayed.
* <ul> * <ul>
* <li>Corresponding method: {@link #setUseController(boolean)}</li> * <li>Corresponding method: {@link #setUseController(boolean)}</li>
...@@ -186,7 +179,6 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -186,7 +179,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
private SimpleExoPlayer player; private SimpleExoPlayer player;
private boolean useController; private boolean useController;
private boolean useArtwork; private boolean useArtwork;
private Bitmap defaultArtwork;
private int controllerShowTimeoutMs; private int controllerShowTimeoutMs;
public SimpleExoPlayerView(Context context) { public SimpleExoPlayerView(Context context) {
...@@ -202,7 +194,6 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -202,7 +194,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
int playerLayoutId = R.layout.exo_simple_player_view; int playerLayoutId = R.layout.exo_simple_player_view;
boolean useArtwork = true; boolean useArtwork = true;
int defaultArtwork = 0;
boolean useController = true; boolean useController = true;
int surfaceType = SURFACE_TYPE_SURFACE_VIEW; int surfaceType = SURFACE_TYPE_SURFACE_VIEW;
int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT; int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
...@@ -214,8 +205,6 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -214,8 +205,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
playerLayoutId = a.getResourceId(R.styleable.SimpleExoPlayerView_player_layout_id, playerLayoutId = a.getResourceId(R.styleable.SimpleExoPlayerView_player_layout_id,
playerLayoutId); playerLayoutId);
useArtwork = a.getBoolean(R.styleable.SimpleExoPlayerView_use_artwork, useArtwork); useArtwork = a.getBoolean(R.styleable.SimpleExoPlayerView_use_artwork, useArtwork);
defaultArtwork = a.getResourceId(R.styleable.SimpleExoPlayerView_default_artwork,
defaultArtwork);
useController = a.getBoolean(R.styleable.SimpleExoPlayerView_use_controller, useController); useController = a.getBoolean(R.styleable.SimpleExoPlayerView_use_controller, useController);
surfaceType = a.getInt(R.styleable.SimpleExoPlayerView_surface_type, surfaceType); surfaceType = a.getInt(R.styleable.SimpleExoPlayerView_surface_type, surfaceType);
resizeMode = a.getInt(R.styleable.SimpleExoPlayerView_resize_mode, resizeMode); resizeMode = a.getInt(R.styleable.SimpleExoPlayerView_resize_mode, resizeMode);
...@@ -257,9 +246,6 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -257,9 +246,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
// Artwork view. // Artwork view.
artworkView = (ImageView) findViewById(R.id.exo_artwork); artworkView = (ImageView) findViewById(R.id.exo_artwork);
this.useArtwork = useArtwork && artworkView != null; this.useArtwork = useArtwork && artworkView != null;
if (defaultArtwork != 0) {
this.defaultArtwork = BitmapFactory.decodeResource(context.getResources(), defaultArtwork);
}
// Subtitle view. // Subtitle view.
subtitleView = (SubtitleView) findViewById(R.id.exo_subtitles); subtitleView = (SubtitleView) findViewById(R.id.exo_subtitles);
...@@ -366,26 +352,6 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -366,26 +352,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
/** /**
* Returns the default artwork to display.
*/
public Bitmap getDefaultArtwork() {
return defaultArtwork;
}
/**
* Sets the default artwork to display if {@code useArtwork} is {@code true} and no artwork is
* present in the media.
*
* @param defaultArtwork the default artwork to display.
*/
public void setDefaultArtwork(Bitmap defaultArtwork) {
if (this.defaultArtwork != defaultArtwork) {
this.defaultArtwork = defaultArtwork;
updateForCurrentTrackSelections();
}
}
/**
* Returns whether the playback controls are enabled. * Returns whether the playback controls are enabled.
*/ */
public boolean getUseController() { public boolean getUseController() {
...@@ -603,9 +569,6 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -603,9 +569,6 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
} }
} }
if (setArtworkFromBitmap(defaultArtwork)) {
return;
}
} }
// Artwork disabled or unavailable. // Artwork disabled or unavailable.
hideArtwork(); hideArtwork();
...@@ -617,23 +580,18 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -617,23 +580,18 @@ public final class SimpleExoPlayerView extends FrameLayout {
if (metadataEntry instanceof ApicFrame) { if (metadataEntry instanceof ApicFrame) {
byte[] bitmapData = ((ApicFrame) metadataEntry).pictureData; byte[] bitmapData = ((ApicFrame) metadataEntry).pictureData;
Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length); Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length);
return setArtworkFromBitmap(bitmap); if (bitmap != null) {
} int bitmapWidth = bitmap.getWidth();
} int bitmapHeight = bitmap.getHeight();
return false; if (bitmapWidth > 0 && bitmapHeight > 0) {
} if (contentFrame != null) {
contentFrame.setAspectRatio((float) bitmapWidth / bitmapHeight);
private boolean setArtworkFromBitmap(Bitmap bitmap) { }
if (bitmap != null) { artworkView.setImageBitmap(bitmap);
int bitmapWidth = bitmap.getWidth(); artworkView.setVisibility(VISIBLE);
int bitmapHeight = bitmap.getHeight(); return true;
if (bitmapWidth > 0 && bitmapHeight > 0) { }
if (contentFrame != null) {
contentFrame.setAspectRatio((float) bitmapWidth / bitmapHeight);
} }
artworkView.setImageBitmap(bitmap);
artworkView.setVisibility(VISIBLE);
return true;
} }
} }
return false; return false;
......
...@@ -146,13 +146,9 @@ import com.google.android.exoplayer2.util.Util; ...@@ -146,13 +146,9 @@ import com.google.android.exoplayer2.util.Util;
// Nothing to draw. // Nothing to draw.
return; return;
} }
int windowColor = cue.windowColorSet ? cue.windowColor : style.windowColor;
if (!applyEmbeddedStyles) { if (!applyEmbeddedStyles) {
// Strip out any embedded styling. // Strip out any embedded styling.
cueText = cueText.toString(); cueText = cueText.toString();
windowColor = style.windowColor;
} }
if (areCharSequencesEqual(this.cueText, cueText) if (areCharSequencesEqual(this.cueText, cueText)
&& Util.areEqual(this.cueTextAlignment, cue.textAlignment) && Util.areEqual(this.cueTextAlignment, cue.textAlignment)
...@@ -165,7 +161,7 @@ import com.google.android.exoplayer2.util.Util; ...@@ -165,7 +161,7 @@ import com.google.android.exoplayer2.util.Util;
&& this.applyEmbeddedStyles == applyEmbeddedStyles && this.applyEmbeddedStyles == applyEmbeddedStyles
&& this.foregroundColor == style.foregroundColor && this.foregroundColor == style.foregroundColor
&& this.backgroundColor == style.backgroundColor && this.backgroundColor == style.backgroundColor
&& this.windowColor == windowColor && this.windowColor == style.windowColor
&& this.edgeType == style.edgeType && this.edgeType == style.edgeType
&& this.edgeColor == style.edgeColor && this.edgeColor == style.edgeColor
&& Util.areEqual(this.textPaint.getTypeface(), style.typeface) && Util.areEqual(this.textPaint.getTypeface(), style.typeface)
...@@ -191,7 +187,7 @@ import com.google.android.exoplayer2.util.Util; ...@@ -191,7 +187,7 @@ import com.google.android.exoplayer2.util.Util;
this.applyEmbeddedStyles = applyEmbeddedStyles; this.applyEmbeddedStyles = applyEmbeddedStyles;
this.foregroundColor = style.foregroundColor; this.foregroundColor = style.foregroundColor;
this.backgroundColor = style.backgroundColor; this.backgroundColor = style.backgroundColor;
this.windowColor = windowColor; this.windowColor = style.windowColor;
this.edgeType = style.edgeType; this.edgeType = style.edgeType;
this.edgeColor = style.edgeColor; this.edgeColor = style.edgeColor;
this.textPaint.setTypeface(style.typeface); this.textPaint.setTypeface(style.typeface);
......
...@@ -403,7 +403,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -403,7 +403,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
bufferPresentationTimeUs, unadjustedFrameReleaseTimeNs); bufferPresentationTimeUs, unadjustedFrameReleaseTimeNs);
earlyUs = (adjustedReleaseTimeNs - systemTimeNs) / 1000; earlyUs = (adjustedReleaseTimeNs - systemTimeNs) / 1000;
if (shouldDropOutputBuffer(earlyUs, elapsedRealtimeUs)) { if (earlyUs < -30000) {
// We're more than 30ms late rendering the frame. // We're more than 30ms late rendering the frame.
dropOutputBuffer(codec, bufferIndex); dropOutputBuffer(codec, bufferIndex);
return true; return true;
...@@ -437,17 +437,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -437,17 +437,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
return false; return false;
} }
/**
* Returns true if the current frame should be dropped.
*
* @param earlyUs Time indicating how early the frame is. Negative values indicate late frame.
* @param elapsedRealtimeUs Wall clock time.
*/
protected boolean shouldDropOutputBuffer(long earlyUs, long elapsedRealtimeUs) {
// Drop the frame if we're more than 30ms late rendering the frame.
return earlyUs < -30000;
}
private void skipOutputBuffer(MediaCodec codec, int bufferIndex) { private void skipOutputBuffer(MediaCodec codec, int bufferIndex) {
TraceUtil.beginSection("skipVideoBuffer"); TraceUtil.beginSection("skipVideoBuffer");
codec.releaseOutputBuffer(bufferIndex, false); codec.releaseOutputBuffer(bufferIndex, false);
......

354 Bytes | W: | H:

1.09 KB | W: | H:

library/src/main/res/drawable-hdpi/exo_controls_fastforward.png
library/src/main/res/drawable-hdpi/exo_controls_fastforward.png
library/src/main/res/drawable-hdpi/exo_controls_fastforward.png
library/src/main/res/drawable-hdpi/exo_controls_fastforward.png
  • 2-up
  • Swipe
  • Onion skin

323 Bytes | W: | H:

1.05 KB | W: | H:

library/src/main/res/drawable-hdpi/exo_controls_next.png
library/src/main/res/drawable-hdpi/exo_controls_next.png
library/src/main/res/drawable-hdpi/exo_controls_next.png
library/src/main/res/drawable-hdpi/exo_controls_next.png
  • 2-up
  • Swipe
  • Onion skin

108 Bytes | W: | H:

599 Bytes | W: | H:

library/src/main/res/drawable-hdpi/exo_controls_pause.png
library/src/main/res/drawable-hdpi/exo_controls_pause.png
library/src/main/res/drawable-hdpi/exo_controls_pause.png
library/src/main/res/drawable-hdpi/exo_controls_pause.png
  • 2-up
  • Swipe
  • Onion skin

286 Bytes | W: | H:

1.14 KB | W: | H:

library/src/main/res/drawable-hdpi/exo_controls_play.png
library/src/main/res/drawable-hdpi/exo_controls_play.png
library/src/main/res/drawable-hdpi/exo_controls_play.png
library/src/main/res/drawable-hdpi/exo_controls_play.png
  • 2-up
  • Swipe
  • Onion skin

292 Bytes | W: | H:

1.04 KB | W: | H:

library/src/main/res/drawable-hdpi/exo_controls_previous.png
library/src/main/res/drawable-hdpi/exo_controls_previous.png
library/src/main/res/drawable-hdpi/exo_controls_previous.png
library/src/main/res/drawable-hdpi/exo_controls_previous.png
  • 2-up
  • Swipe
  • Onion skin

347 Bytes | W: | H:

1.22 KB | W: | H:

library/src/main/res/drawable-hdpi/exo_controls_rewind.png
library/src/main/res/drawable-hdpi/exo_controls_rewind.png
library/src/main/res/drawable-hdpi/exo_controls_rewind.png
library/src/main/res/drawable-hdpi/exo_controls_rewind.png
  • 2-up
  • Swipe
  • Onion skin

192 Bytes | W: | H:

886 Bytes | W: | H:

library/src/main/res/drawable-ldpi/exo_controls_fastforward.png
library/src/main/res/drawable-ldpi/exo_controls_fastforward.png
library/src/main/res/drawable-ldpi/exo_controls_fastforward.png
library/src/main/res/drawable-ldpi/exo_controls_fastforward.png
  • 2-up
  • Swipe
  • Onion skin

167 Bytes | W: | H:

735 Bytes | W: | H:

library/src/main/res/drawable-ldpi/exo_controls_next.png
library/src/main/res/drawable-ldpi/exo_controls_next.png
library/src/main/res/drawable-ldpi/exo_controls_next.png
library/src/main/res/drawable-ldpi/exo_controls_next.png
  • 2-up
  • Swipe
  • Onion skin

91 Bytes | W: | H:

3.17 KB | W: | H:

library/src/main/res/drawable-ldpi/exo_controls_pause.png
library/src/main/res/drawable-ldpi/exo_controls_pause.png
library/src/main/res/drawable-ldpi/exo_controls_pause.png
library/src/main/res/drawable-ldpi/exo_controls_pause.png
  • 2-up
  • Swipe
  • Onion skin

182 Bytes | W: | H:

673 Bytes | W: | H:

library/src/main/res/drawable-ldpi/exo_controls_play.png
library/src/main/res/drawable-ldpi/exo_controls_play.png
library/src/main/res/drawable-ldpi/exo_controls_play.png
library/src/main/res/drawable-ldpi/exo_controls_play.png
  • 2-up
  • Swipe
  • Onion skin

187 Bytes | W: | H:

770 Bytes | W: | H:

library/src/main/res/drawable-ldpi/exo_controls_previous.png
library/src/main/res/drawable-ldpi/exo_controls_previous.png
library/src/main/res/drawable-ldpi/exo_controls_previous.png
library/src/main/res/drawable-ldpi/exo_controls_previous.png
  • 2-up
  • Swipe
  • Onion skin

214 Bytes | W: | H:

906 Bytes | W: | H:

library/src/main/res/drawable-ldpi/exo_controls_rewind.png
library/src/main/res/drawable-ldpi/exo_controls_rewind.png
library/src/main/res/drawable-ldpi/exo_controls_rewind.png
library/src/main/res/drawable-ldpi/exo_controls_rewind.png
  • 2-up
  • Swipe
  • Onion skin

255 Bytes | W: | H:

929 Bytes | W: | H:

library/src/main/res/drawable-mdpi/exo_controls_fastforward.png
library/src/main/res/drawable-mdpi/exo_controls_fastforward.png
library/src/main/res/drawable-mdpi/exo_controls_fastforward.png
library/src/main/res/drawable-mdpi/exo_controls_fastforward.png
  • 2-up
  • Swipe
  • Onion skin

276 Bytes | W: | H:

843 Bytes | W: | H:

library/src/main/res/drawable-mdpi/exo_controls_next.png
library/src/main/res/drawable-mdpi/exo_controls_next.png
library/src/main/res/drawable-mdpi/exo_controls_next.png
library/src/main/res/drawable-mdpi/exo_controls_next.png
  • 2-up
  • Swipe
  • Onion skin

153 Bytes | W: | H:

540 Bytes | W: | H:

library/src/main/res/drawable-mdpi/exo_controls_pause.png
library/src/main/res/drawable-mdpi/exo_controls_pause.png
library/src/main/res/drawable-mdpi/exo_controls_pause.png
library/src/main/res/drawable-mdpi/exo_controls_pause.png
  • 2-up
  • Swipe
  • Onion skin

228 Bytes | W: | H:

897 Bytes | W: | H:

library/src/main/res/drawable-mdpi/exo_controls_play.png
library/src/main/res/drawable-mdpi/exo_controls_play.png
library/src/main/res/drawable-mdpi/exo_controls_play.png
library/src/main/res/drawable-mdpi/exo_controls_play.png
  • 2-up
  • Swipe
  • Onion skin

227 Bytes | W: | H:

837 Bytes | W: | H:

library/src/main/res/drawable-mdpi/exo_controls_previous.png
library/src/main/res/drawable-mdpi/exo_controls_previous.png
library/src/main/res/drawable-mdpi/exo_controls_previous.png
library/src/main/res/drawable-mdpi/exo_controls_previous.png
  • 2-up
  • Swipe
  • Onion skin

273 Bytes | W: | H:

997 Bytes | W: | H:

library/src/main/res/drawable-mdpi/exo_controls_rewind.png
library/src/main/res/drawable-mdpi/exo_controls_rewind.png
library/src/main/res/drawable-mdpi/exo_controls_rewind.png
library/src/main/res/drawable-mdpi/exo_controls_rewind.png
  • 2-up
  • Swipe
  • Onion skin
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path android:fillColor="#FFF" android:pathData="M4,18l8.5,-6L4,6v12zM13,6v12l8.5,-6L13,6z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path android:fillColor="#FFF" android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path android:fillColor="#FFF" android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path android:fillColor="#FFF" android:pathData="M8,5v14l11,-7z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path android:fillColor="#FFF" android:pathData="M6,6h2v12L6,18zM9.5,12l8.5,6L18,6z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path android:fillColor="#FFF" android:pathData="M11,18L11,6l-8.5,6 8.5,6zM11.5,12l8.5,6L20,6l-8.5,6z"/>
</vector>

392 Bytes | W: | H:

1.44 KB | W: | H:

library/src/main/res/drawable-xhdpi/exo_controls_fastforward.png
library/src/main/res/drawable-xhdpi/exo_controls_fastforward.png
library/src/main/res/drawable-xhdpi/exo_controls_fastforward.png
library/src/main/res/drawable-xhdpi/exo_controls_fastforward.png
  • 2-up
  • Swipe
  • Onion skin

334 Bytes | W: | H:

1.33 KB | W: | H:

library/src/main/res/drawable-xhdpi/exo_controls_next.png
library/src/main/res/drawable-xhdpi/exo_controls_next.png
library/src/main/res/drawable-xhdpi/exo_controls_next.png
library/src/main/res/drawable-xhdpi/exo_controls_next.png
  • 2-up
  • Swipe
  • Onion skin

164 Bytes | W: | H:

685 Bytes | W: | H:

library/src/main/res/drawable-xhdpi/exo_controls_pause.png
library/src/main/res/drawable-xhdpi/exo_controls_pause.png
library/src/main/res/drawable-xhdpi/exo_controls_pause.png
library/src/main/res/drawable-xhdpi/exo_controls_pause.png
  • 2-up
  • Swipe
  • Onion skin

343 Bytes | W: | H:

1.58 KB | W: | H:

library/src/main/res/drawable-xhdpi/exo_controls_play.png
library/src/main/res/drawable-xhdpi/exo_controls_play.png
library/src/main/res/drawable-xhdpi/exo_controls_play.png
library/src/main/res/drawable-xhdpi/exo_controls_play.png
  • 2-up
  • Swipe
  • Onion skin

339 Bytes | W: | H:

1.34 KB | W: | H:

library/src/main/res/drawable-xhdpi/exo_controls_previous.png
library/src/main/res/drawable-xhdpi/exo_controls_previous.png
library/src/main/res/drawable-xhdpi/exo_controls_previous.png
library/src/main/res/drawable-xhdpi/exo_controls_previous.png
  • 2-up
  • Swipe
  • Onion skin

400 Bytes | W: | H:

1.64 KB | W: | H:

library/src/main/res/drawable-xhdpi/exo_controls_rewind.png
library/src/main/res/drawable-xhdpi/exo_controls_rewind.png
library/src/main/res/drawable-xhdpi/exo_controls_rewind.png
library/src/main/res/drawable-xhdpi/exo_controls_rewind.png
  • 2-up
  • Swipe
  • Onion skin

391 Bytes | W: | H:

1.29 KB | W: | H:

library/src/main/res/drawable-xxhdpi/exo_controls_next.png
library/src/main/res/drawable-xxhdpi/exo_controls_next.png
library/src/main/res/drawable-xxhdpi/exo_controls_next.png
library/src/main/res/drawable-xxhdpi/exo_controls_next.png
  • 2-up
  • Swipe
  • Onion skin

113 Bytes | W: | H:

611 Bytes | W: | H:

library/src/main/res/drawable-xxhdpi/exo_controls_pause.png
library/src/main/res/drawable-xxhdpi/exo_controls_pause.png
library/src/main/res/drawable-xxhdpi/exo_controls_pause.png
library/src/main/res/drawable-xxhdpi/exo_controls_pause.png
  • 2-up
  • Swipe
  • Onion skin

384 Bytes | W: | H:

1.16 KB | W: | H:

library/src/main/res/drawable-xxhdpi/exo_controls_play.png
library/src/main/res/drawable-xxhdpi/exo_controls_play.png
library/src/main/res/drawable-xxhdpi/exo_controls_play.png
library/src/main/res/drawable-xxhdpi/exo_controls_play.png
  • 2-up
  • Swipe
  • Onion skin

464 Bytes | W: | H:

1.26 KB | W: | H:

library/src/main/res/drawable-xxhdpi/exo_controls_previous.png
library/src/main/res/drawable-xxhdpi/exo_controls_previous.png
library/src/main/res/drawable-xxhdpi/exo_controls_previous.png
library/src/main/res/drawable-xxhdpi/exo_controls_previous.png
  • 2-up
  • Swipe
  • Onion skin

571 Bytes | W: | H:

1.17 KB | W: | H:

library/src/main/res/drawable-xxhdpi/exo_controls_rewind.png
library/src/main/res/drawable-xxhdpi/exo_controls_rewind.png
library/src/main/res/drawable-xxhdpi/exo_controls_rewind.png
library/src/main/res/drawable-xxhdpi/exo_controls_rewind.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
<declare-styleable name="SimpleExoPlayerView"> <declare-styleable name="SimpleExoPlayerView">
<attr name="use_artwork" format="boolean"/> <attr name="use_artwork" format="boolean"/>
<attr name="default_artwork" format="reference"/>
<attr name="use_controller" format="boolean"/> <attr name="use_controller" format="boolean"/>
<attr name="surface_type"/> <attr name="surface_type"/>
<attr name="show_timeout"/> <attr name="show_timeout"/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment