Merge pull request #4675 from google/dev-v2-r2.8.4

r2.8.4
This commit is contained in:
ojw28 2018-08-17 22:05:50 +01:00 committed by GitHub
commit 09d1e3e35d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 19 deletions

View File

@ -1,5 +1,11 @@
# Release notes # # Release notes #
### 2.8.4 ###
* IMA: Improve handling of consecutive empty ad groups
([#4030](https://github.com/google/ExoPlayer/issues/4030)),
([#4280](https://github.com/google/ExoPlayer/issues/4280)).
### 2.8.3 ### ### 2.8.3 ###
* IMA: * IMA:

View File

@ -13,8 +13,8 @@
// limitations under the License. // limitations under the License.
project.ext { project.ext {
// ExoPlayer version and version code. // ExoPlayer version and version code.
releaseVersion = '2.8.3' releaseVersion = '2.8.4'
releaseVersionCode = 2803 releaseVersionCode = 2804
// Important: ExoPlayer specifies a minSdkVersion of 14 because various // Important: ExoPlayer specifies a minSdkVersion of 14 because various
// components provided by the library may be of use on older devices. // components provided by the library may be of use on older devices.
// However, please note that the core media playback functionality provided // However, please note that the core media playback functionality provided

View File

@ -188,6 +188,7 @@ public class PlayerActivity extends Activity
@Override @Override
public void onNewIntent(Intent intent) { public void onNewIntent(Intent intent) {
releasePlayer(); releasePlayer();
releaseAdsLoader();
clearStartPosition(); clearStartPosition();
setIntent(intent); setIntent(intent);
} }

View File

@ -376,6 +376,9 @@ public final class ImaAdsLoader extends Player.DefaultEventListener implements A
adDisplayContainer.setPlayer(this); adDisplayContainer.setPlayer(this);
if (imaSdkSettings == null) { if (imaSdkSettings == null) {
imaSdkSettings = imaSdkFactory.createImaSdkSettings(); imaSdkSettings = imaSdkFactory.createImaSdkSettings();
if (DEBUG) {
imaSdkSettings.setDebugMode(true);
}
} }
imaSdkSettings.setPlayerType(IMA_SDK_SETTINGS_PLAYER_TYPE); imaSdkSettings.setPlayerType(IMA_SDK_SETTINGS_PLAYER_TYPE);
imaSdkSettings.setPlayerVersion(IMA_SDK_SETTINGS_PLAYER_VERSION); imaSdkSettings.setPlayerVersion(IMA_SDK_SETTINGS_PLAYER_VERSION);
@ -619,8 +622,11 @@ public final class ImaAdsLoader extends Player.DefaultEventListener implements A
} else if (fakeContentProgressElapsedRealtimeMs != C.TIME_UNSET) { } else if (fakeContentProgressElapsedRealtimeMs != C.TIME_UNSET) {
long elapsedSinceEndMs = SystemClock.elapsedRealtime() - fakeContentProgressElapsedRealtimeMs; long elapsedSinceEndMs = SystemClock.elapsedRealtime() - fakeContentProgressElapsedRealtimeMs;
contentPositionMs = fakeContentProgressOffsetMs + elapsedSinceEndMs; contentPositionMs = fakeContentProgressOffsetMs + elapsedSinceEndMs;
expectedAdGroupIndex = int adGroupIndexForPosition =
adPlaybackState.getAdGroupIndexForPositionUs(C.msToUs(contentPositionMs)); adPlaybackState.getAdGroupIndexForPositionUs(C.msToUs(contentPositionMs));
if (adGroupIndexForPosition != C.INDEX_UNSET) {
expectedAdGroupIndex = adGroupIndexForPosition;
}
} else if (imaAdState == IMA_AD_STATE_NONE && !playingAd && hasContentDuration) { } else if (imaAdState == IMA_AD_STATE_NONE && !playingAd && hasContentDuration) {
contentPositionMs = player.getCurrentPosition(); contentPositionMs = player.getCurrentPosition();
// Update the expected ad group index for the current content position. The update is delayed // Update the expected ad group index for the current content position. The update is delayed
@ -1096,6 +1102,16 @@ public final class ImaAdsLoader extends Player.DefaultEventListener implements A
if (pendingAdLoadError == null) { if (pendingAdLoadError == null) {
pendingAdLoadError = AdLoadException.createForAdGroup(error, adGroupIndex); pendingAdLoadError = AdLoadException.createForAdGroup(error, adGroupIndex);
} }
// Discard the ad break, which makes sure we don't receive duplicate load error events.
adsManager.discardAdBreak();
// Set the next expected ad group index so we can handle multiple load errors in a row.
adGroupIndex++;
if (adGroupIndex < adPlaybackState.adGroupCount) {
expectedAdGroupIndex = adGroupIndex;
} else {
expectedAdGroupIndex = C.INDEX_UNSET;
}
pendingContentPositionMs = C.TIME_UNSET;
} }
private void handleAdPrepareError(int adGroupIndex, int adIndexInAdGroup, Exception exception) { private void handleAdPrepareError(int adGroupIndex, int adIndexInAdGroup, Exception exception) {

View File

@ -29,11 +29,11 @@ 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.8.3"; public static final String VERSION = "2.8.4";
/** 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.8.3"; public static final String VERSION_SLASHY = "ExoPlayerLib/2.8.4";
/** /**
* The version of the library expressed as an integer, for example 1002003. * The version of the library expressed as an integer, for example 1002003.
@ -43,7 +43,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 = 2008003; public static final int VERSION_INT = 2008004;
/** /**
* 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

@ -598,10 +598,13 @@ public final class FragmentedMp4Extractor implements Extractor {
// Output the sample metadata. // Output the sample metadata.
if (segmentIndexEarliestPresentationTimeUs != C.TIME_UNSET) { if (segmentIndexEarliestPresentationTimeUs != C.TIME_UNSET) {
long sampleTimeUs = segmentIndexEarliestPresentationTimeUs + presentationTimeDeltaUs;
if (timestampAdjuster != null) {
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
}
for (TrackOutput emsgTrackOutput : emsgTrackOutputs) { for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
emsgTrackOutput.sampleMetadata( emsgTrackOutput.sampleMetadata(
segmentIndexEarliestPresentationTimeUs + presentationTimeDeltaUs, sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, /* offset= */ 0, null);
C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0 /* offset */, null);
} }
} else { } else {
// We need the first sample timestamp in the segment before we can output the metadata. // We need the first sample timestamp in the segment before we can output the metadata.
@ -1208,6 +1211,10 @@ public final class FragmentedMp4Extractor implements Extractor {
Track track = currentTrackBundle.track; Track track = currentTrackBundle.track;
TrackOutput output = currentTrackBundle.output; TrackOutput output = currentTrackBundle.output;
int sampleIndex = currentTrackBundle.currentSampleIndex; int sampleIndex = currentTrackBundle.currentSampleIndex;
long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L;
if (timestampAdjuster != null) {
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
}
if (track.nalUnitLengthFieldLength != 0) { if (track.nalUnitLengthFieldLength != 0) {
// Zero the top three bytes of the array that we'll use to decode 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. // they're only 1 or 2 bytes long.
@ -1248,8 +1255,7 @@ public final class FragmentedMp4Extractor implements Extractor {
// If the format is H.265/HEVC the NAL unit header has two bytes so skip one more byte. // If the format is H.265/HEVC the NAL unit header has two bytes so skip one more byte.
nalBuffer.setPosition(MimeTypes.VIDEO_H265.equals(track.format.sampleMimeType) ? 1 : 0); nalBuffer.setPosition(MimeTypes.VIDEO_H265.equals(track.format.sampleMimeType) ? 1 : 0);
nalBuffer.setLimit(unescapedLength); nalBuffer.setLimit(unescapedLength);
CeaUtil.consume(fragment.getSamplePresentationTime(sampleIndex) * 1000L, nalBuffer, CeaUtil.consume(sampleTimeUs, nalBuffer, cea608TrackOutputs);
cea608TrackOutputs);
} else { } else {
// Write the payload of the NAL unit. // Write the payload of the NAL unit.
writtenBytes = output.sampleData(input, sampleCurrentNalBytesRemaining, false); writtenBytes = output.sampleData(input, sampleCurrentNalBytesRemaining, false);
@ -1265,11 +1271,6 @@ public final class FragmentedMp4Extractor implements Extractor {
} }
} }
long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L;
if (timestampAdjuster != null) {
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
}
@C.BufferFlags int sampleFlags = fragment.sampleIsSyncFrameTable[sampleIndex] @C.BufferFlags int sampleFlags = fragment.sampleIsSyncFrameTable[sampleIndex]
? C.BUFFER_FLAG_KEY_FRAME : 0; ? C.BUFFER_FLAG_KEY_FRAME : 0;
@ -1298,10 +1299,17 @@ public final class FragmentedMp4Extractor implements Extractor {
while (!pendingMetadataSampleInfos.isEmpty()) { while (!pendingMetadataSampleInfos.isEmpty()) {
MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst(); MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst();
pendingMetadataSampleBytes -= sampleInfo.size; pendingMetadataSampleBytes -= sampleInfo.size;
long metadataTimeUs = sampleTimeUs + sampleInfo.presentationTimeDeltaUs;
if (timestampAdjuster != null) {
metadataTimeUs = timestampAdjuster.adjustSampleTimestamp(metadataTimeUs);
}
for (TrackOutput emsgTrackOutput : emsgTrackOutputs) { for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
emsgTrackOutput.sampleMetadata( emsgTrackOutput.sampleMetadata(
sampleTimeUs + sampleInfo.presentationTimeDeltaUs, metadataTimeUs,
C.BUFFER_FLAG_KEY_FRAME, sampleInfo.size, pendingMetadataSampleBytes, null); C.BUFFER_FLAG_KEY_FRAME,
sampleInfo.size,
pendingMetadataSampleBytes,
null);
} }
} }
} }

View File

@ -118,8 +118,18 @@ public final class DefaultAllocator implements Allocator {
} }
for (Allocation allocation : allocations) { for (Allocation allocation : allocations) {
// Weak sanity check that the allocation probably originated from this pool. // Weak sanity check that the allocation probably originated from this pool.
Assertions.checkArgument(allocation.data == initialAllocationBlock if (allocation.data != initialAllocationBlock
|| allocation.data.length == individualAllocationSize); && allocation.data.length != individualAllocationSize) {
throw new IllegalArgumentException(
"Unexpected allocation: "
+ System.identityHashCode(allocation.data)
+ ", "
+ System.identityHashCode(initialAllocationBlock)
+ ", "
+ allocation.data.length
+ ", "
+ individualAllocationSize);
}
availableAllocations[availableCount++] = allocation; availableAllocations[availableCount++] = allocation;
} }
allocatedCount -= allocations.length; allocatedCount -= allocations.length;