Merge pull request #3151 from google/dev-v2-r2.5.1

r2.5.1
This commit is contained in:
ojw28 2017-08-08 16:53:44 +01:00 committed by GitHub
commit 2f8c31d173
7 changed files with 44 additions and 22 deletions

View File

@ -1,5 +1,12 @@
# Release notes # # Release notes #
### r2.5.1 ###
* Fix an issue that could cause the reported playback position to stop advancing
in some cases.
* Fix an issue where a Surface could be released whilst still in use by the
player.
### r2.5.0 ### ### r2.5.0 ###
* IMA extension: Wraps the Google Interactive Media Ads (IMA) SDK to provide an * IMA extension: Wraps the Google Interactive Media Ads (IMA) SDK to provide an

View File

@ -24,7 +24,7 @@ project.ext {
supportLibraryVersion = '25.4.0' supportLibraryVersion = '25.4.0'
dexmakerVersion = '1.2' dexmakerVersion = '1.2'
mockitoVersion = '1.9.5' mockitoVersion = '1.9.5'
releaseVersion = 'r2.5.0' releaseVersion = 'r2.5.1'
modulePrefix = ':' modulePrefix = ':'
if (gradle.ext.has('exoplayerModulePrefix')) { if (gradle.ext.has('exoplayerModulePrefix')) {
modulePrefix += gradle.ext.exoplayerModulePrefix modulePrefix += gradle.ext.exoplayerModulePrefix

View File

@ -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="2500" android:versionCode="2501"
android:versionName="2.5.0"> android:versionName="2.5.1">
<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"/>

View File

@ -975,11 +975,10 @@ import java.io.IOException;
mediaPeriodInfoSequence.setTimeline(timeline); mediaPeriodInfoSequence.setTimeline(timeline);
Object manifest = timelineAndManifest.second; Object manifest = timelineAndManifest.second;
int processedInitialSeekCount = 0;
if (oldTimeline == null) { if (oldTimeline == null) {
if (pendingInitialSeekCount > 0) { if (pendingInitialSeekCount > 0) {
Pair<Integer, Long> periodPosition = resolveSeekPosition(pendingSeekPosition); Pair<Integer, Long> periodPosition = resolveSeekPosition(pendingSeekPosition);
processedInitialSeekCount = pendingInitialSeekCount; int processedInitialSeekCount = pendingInitialSeekCount;
pendingInitialSeekCount = 0; pendingInitialSeekCount = 0;
pendingSeekPosition = null; pendingSeekPosition = null;
if (periodPosition == null) { if (periodPosition == null) {
@ -996,7 +995,7 @@ import java.io.IOException;
} }
} else if (playbackInfo.startPositionUs == C.TIME_UNSET) { } else if (playbackInfo.startPositionUs == C.TIME_UNSET) {
if (timeline.isEmpty()) { if (timeline.isEmpty()) {
handleSourceInfoRefreshEndedPlayback(manifest, processedInitialSeekCount); handleSourceInfoRefreshEndedPlayback(manifest);
} else { } else {
Pair<Integer, Long> defaultPosition = getPeriodPosition(0, C.TIME_UNSET); Pair<Integer, Long> defaultPosition = getPeriodPosition(0, C.TIME_UNSET);
int periodIndex = defaultPosition.first; int periodIndex = defaultPosition.first;
@ -1005,8 +1004,10 @@ import java.io.IOException;
startPositionUs); startPositionUs);
playbackInfo = new PlaybackInfo(periodId, periodId.isAd() ? 0 : startPositionUs, playbackInfo = new PlaybackInfo(periodId, periodId.isAd() ? 0 : startPositionUs,
startPositionUs); startPositionUs);
notifySourceInfoRefresh(manifest, processedInitialSeekCount); notifySourceInfoRefresh(manifest);
} }
} else {
notifySourceInfoRefresh(manifest);
} }
return; return;
} }
@ -1015,7 +1016,7 @@ import java.io.IOException;
MediaPeriodHolder periodHolder = playingPeriodHolder != null ? playingPeriodHolder MediaPeriodHolder periodHolder = playingPeriodHolder != null ? playingPeriodHolder
: loadingPeriodHolder; : loadingPeriodHolder;
if (periodHolder == null && playingPeriodIndex >= oldTimeline.getPeriodCount()) { if (periodHolder == null && playingPeriodIndex >= oldTimeline.getPeriodCount()) {
notifySourceInfoRefresh(manifest, processedInitialSeekCount); notifySourceInfoRefresh(manifest);
return; return;
} }
Object playingPeriodUid = periodHolder == null Object playingPeriodUid = periodHolder == null
@ -1027,7 +1028,7 @@ import java.io.IOException;
int newPeriodIndex = resolveSubsequentPeriod(playingPeriodIndex, oldTimeline, timeline); int newPeriodIndex = resolveSubsequentPeriod(playingPeriodIndex, oldTimeline, timeline);
if (newPeriodIndex == C.INDEX_UNSET) { if (newPeriodIndex == C.INDEX_UNSET) {
// We failed to resolve a suitable restart position. // We failed to resolve a suitable restart position.
handleSourceInfoRefreshEndedPlayback(manifest, processedInitialSeekCount); handleSourceInfoRefreshEndedPlayback(manifest);
return; return;
} }
// We resolved a subsequent period. Seek to the default position in the corresponding window. // We resolved a subsequent period. Seek to the default position in the corresponding window.
@ -1055,7 +1056,7 @@ import java.io.IOException;
MediaPeriodId periodId = new MediaPeriodId(newPeriodIndex); MediaPeriodId periodId = new MediaPeriodId(newPeriodIndex);
newPositionUs = seekToPeriodPosition(periodId, newPositionUs); newPositionUs = seekToPeriodPosition(periodId, newPositionUs);
playbackInfo = new PlaybackInfo(periodId, newPositionUs); playbackInfo = new PlaybackInfo(periodId, newPositionUs);
notifySourceInfoRefresh(manifest, processedInitialSeekCount); notifySourceInfoRefresh(manifest);
return; return;
} }
@ -1072,14 +1073,14 @@ import java.io.IOException;
long newPositionUs = seekToPeriodPosition(periodId, playbackInfo.contentPositionUs); long newPositionUs = seekToPeriodPosition(periodId, playbackInfo.contentPositionUs);
long contentPositionUs = periodId.isAd() ? playbackInfo.contentPositionUs : C.TIME_UNSET; long contentPositionUs = periodId.isAd() ? playbackInfo.contentPositionUs : C.TIME_UNSET;
playbackInfo = new PlaybackInfo(periodId, newPositionUs, contentPositionUs); playbackInfo = new PlaybackInfo(periodId, newPositionUs, contentPositionUs);
notifySourceInfoRefresh(manifest, processedInitialSeekCount); notifySourceInfoRefresh(manifest);
return; return;
} }
} }
if (periodHolder == null) { if (periodHolder == null) {
// We don't have any period holders, so we're done. // We don't have any period holders, so we're done.
notifySourceInfoRefresh(manifest, processedInitialSeekCount); notifySourceInfoRefresh(manifest);
return; return;
} }
@ -1117,7 +1118,7 @@ import java.io.IOException;
} }
} }
notifySourceInfoRefresh(manifest, processedInitialSeekCount); notifySourceInfoRefresh(manifest);
} }
private MediaPeriodHolder updatePeriodInfo(MediaPeriodHolder periodHolder, int periodIndex) { private MediaPeriodHolder updatePeriodInfo(MediaPeriodHolder periodHolder, int periodIndex) {
@ -1131,6 +1132,10 @@ import java.io.IOException;
} }
} }
private void handleSourceInfoRefreshEndedPlayback(Object manifest) {
handleSourceInfoRefreshEndedPlayback(manifest, 0);
}
private void handleSourceInfoRefreshEndedPlayback(Object manifest, private void handleSourceInfoRefreshEndedPlayback(Object manifest,
int processedInitialSeekCount) { int processedInitialSeekCount) {
// Set the playback position to (0,0) for notifying the eventHandler. // Set the playback position to (0,0) for notifying the eventHandler.
@ -1143,6 +1148,10 @@ import java.io.IOException;
resetInternal(false); resetInternal(false);
} }
private void notifySourceInfoRefresh(Object manifest) {
notifySourceInfoRefresh(manifest, 0);
}
private void notifySourceInfoRefresh(Object manifest, int processedInitialSeekCount) { private void notifySourceInfoRefresh(Object manifest, int processedInitialSeekCount) {
eventHandler.obtainMessage(MSG_SOURCE_INFO_REFRESHED, eventHandler.obtainMessage(MSG_SOURCE_INFO_REFRESHED,
new SourceInfo(timeline, manifest, playbackInfo, processedInitialSeekCount)).sendToTarget(); new SourceInfo(timeline, manifest, playbackInfo, processedInitialSeekCount)).sendToTarget();

View File

@ -31,13 +31,13 @@ public final class ExoPlayerLibraryInfo {
* The version of the library expressed as a string, for example "1.2.3". * The version of the library expressed as a string, for example "1.2.3".
*/ */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public static final String VERSION = "2.5.0"; public static final String VERSION = "2.5.1";
/** /**
* The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. * The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}.
*/ */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final String VERSION_SLASHY = "ExoPlayerLib/2.5.0"; public static final String VERSION_SLASHY = "ExoPlayerLib/2.5.1";
/** /**
* The version of the library expressed as an integer, for example 1002003. * The version of the library expressed as an integer, for example 1002003.
@ -47,7 +47,7 @@ public final class ExoPlayerLibraryInfo {
* integer version 123045006 (123-045-006). * integer version 123045006 (123-045-006).
*/ */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final int VERSION_INT = 2005000; public static final int VERSION_INT = 2005001;
/** /**
* 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}

View File

@ -749,12 +749,12 @@ public class SimpleExoPlayer implements ExoPlayer {
} }
} }
if (this.surface != null && this.surface != surface) { if (this.surface != null && this.surface != surface) {
// If we created this surface, we are responsible for releasing it. // We're replacing a surface. Block to ensure that it's not accessed after the method returns.
player.blockingSendMessages(messages);
// If we created the previous surface, we are responsible for releasing it.
if (this.ownsSurface) { if (this.ownsSurface) {
this.surface.release(); this.surface.release();
} }
// We're replacing a surface. Block to ensure that it's not accessed after the method returns.
player.blockingSendMessages(messages);
} else { } else {
player.sendMessages(messages); player.sendMessages(messages);
} }

View File

@ -48,7 +48,9 @@ public final class ClippingMediaSource implements MediaSource, MediaSource.Liste
* start providing samples, in microseconds. * start providing samples, in microseconds.
* @param endPositionUs The end position within {@code mediaSource}'s timeline at which to stop * @param endPositionUs The end position within {@code mediaSource}'s timeline at which to stop
* providing samples, in microseconds. Specify {@link C#TIME_END_OF_SOURCE} to provide samples * providing samples, in microseconds. Specify {@link C#TIME_END_OF_SOURCE} to provide samples
* from the specified start point up to the end of the source. * from the specified start point up to the end of the source. Specifying a position that
* exceeds the {@code mediaSource}'s duration will also result in the end of the source not
* being clipped.
*/ */
public ClippingMediaSource(MediaSource mediaSource, long startPositionUs, long endPositionUs) { public ClippingMediaSource(MediaSource mediaSource, long startPositionUs, long endPositionUs) {
this(mediaSource, startPositionUs, endPositionUs, true); this(mediaSource, startPositionUs, endPositionUs, true);
@ -66,7 +68,9 @@ public final class ClippingMediaSource implements MediaSource, MediaSource.Liste
* start providing samples, in microseconds. * start providing samples, in microseconds.
* @param endPositionUs The end position within {@code mediaSource}'s timeline at which to stop * @param endPositionUs The end position within {@code mediaSource}'s timeline at which to stop
* providing samples, in microseconds. Specify {@link C#TIME_END_OF_SOURCE} to provide samples * providing samples, in microseconds. Specify {@link C#TIME_END_OF_SOURCE} to provide samples
* from the specified start point up to the end of the source. * from the specified start point up to the end of the source. Specifying a position that
* exceeds the {@code mediaSource}'s duration will also result in the end of the source not
* being clipped.
* @param enableInitialDiscontinuity Whether the initial discontinuity should be enabled. * @param enableInitialDiscontinuity Whether the initial discontinuity should be enabled.
*/ */
public ClippingMediaSource(MediaSource mediaSource, long startPositionUs, long endPositionUs, public ClippingMediaSource(MediaSource mediaSource, long startPositionUs, long endPositionUs,
@ -149,8 +153,10 @@ public final class ClippingMediaSource implements MediaSource, MediaSource.Liste
Assertions.checkArgument(!window.isDynamic); Assertions.checkArgument(!window.isDynamic);
long resolvedEndUs = endUs == C.TIME_END_OF_SOURCE ? window.durationUs : endUs; long resolvedEndUs = endUs == C.TIME_END_OF_SOURCE ? window.durationUs : endUs;
if (window.durationUs != C.TIME_UNSET) { if (window.durationUs != C.TIME_UNSET) {
if (resolvedEndUs > window.durationUs) {
resolvedEndUs = window.durationUs;
}
Assertions.checkArgument(startUs == 0 || window.isSeekable); Assertions.checkArgument(startUs == 0 || window.isSeekable);
Assertions.checkArgument(resolvedEndUs <= window.durationUs);
Assertions.checkArgument(startUs <= resolvedEndUs); Assertions.checkArgument(startUs <= resolvedEndUs);
} }
Period period = timeline.getPeriod(0, new Period()); Period period = timeline.getPeriod(0, new Period());