commit
09d1e3e35d
@ -1,5 +1,11 @@
|
||||
# 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 ###
|
||||
|
||||
* IMA:
|
||||
|
@ -13,8 +13,8 @@
|
||||
// limitations under the License.
|
||||
project.ext {
|
||||
// ExoPlayer version and version code.
|
||||
releaseVersion = '2.8.3'
|
||||
releaseVersionCode = 2803
|
||||
releaseVersion = '2.8.4'
|
||||
releaseVersionCode = 2804
|
||||
// Important: ExoPlayer specifies a minSdkVersion of 14 because various
|
||||
// components provided by the library may be of use on older devices.
|
||||
// However, please note that the core media playback functionality provided
|
||||
|
@ -188,6 +188,7 @@ public class PlayerActivity extends Activity
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
releasePlayer();
|
||||
releaseAdsLoader();
|
||||
clearStartPosition();
|
||||
setIntent(intent);
|
||||
}
|
||||
|
@ -376,6 +376,9 @@ public final class ImaAdsLoader extends Player.DefaultEventListener implements A
|
||||
adDisplayContainer.setPlayer(this);
|
||||
if (imaSdkSettings == null) {
|
||||
imaSdkSettings = imaSdkFactory.createImaSdkSettings();
|
||||
if (DEBUG) {
|
||||
imaSdkSettings.setDebugMode(true);
|
||||
}
|
||||
}
|
||||
imaSdkSettings.setPlayerType(IMA_SDK_SETTINGS_PLAYER_TYPE);
|
||||
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) {
|
||||
long elapsedSinceEndMs = SystemClock.elapsedRealtime() - fakeContentProgressElapsedRealtimeMs;
|
||||
contentPositionMs = fakeContentProgressOffsetMs + elapsedSinceEndMs;
|
||||
expectedAdGroupIndex =
|
||||
int adGroupIndexForPosition =
|
||||
adPlaybackState.getAdGroupIndexForPositionUs(C.msToUs(contentPositionMs));
|
||||
if (adGroupIndexForPosition != C.INDEX_UNSET) {
|
||||
expectedAdGroupIndex = adGroupIndexForPosition;
|
||||
}
|
||||
} else if (imaAdState == IMA_AD_STATE_NONE && !playingAd && hasContentDuration) {
|
||||
contentPositionMs = player.getCurrentPosition();
|
||||
// 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) {
|
||||
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) {
|
||||
|
@ -29,11 +29,11 @@ public final class ExoPlayerLibraryInfo {
|
||||
|
||||
/** 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.
|
||||
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}. */
|
||||
// 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.
|
||||
@ -43,7 +43,7 @@ public final class ExoPlayerLibraryInfo {
|
||||
* integer version 123045006 (123-045-006).
|
||||
*/
|
||||
// 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}
|
||||
|
@ -598,10 +598,13 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
|
||||
// Output the sample metadata.
|
||||
if (segmentIndexEarliestPresentationTimeUs != C.TIME_UNSET) {
|
||||
long sampleTimeUs = segmentIndexEarliestPresentationTimeUs + presentationTimeDeltaUs;
|
||||
if (timestampAdjuster != null) {
|
||||
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
|
||||
}
|
||||
for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
|
||||
emsgTrackOutput.sampleMetadata(
|
||||
segmentIndexEarliestPresentationTimeUs + presentationTimeDeltaUs,
|
||||
C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0 /* offset */, null);
|
||||
sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, /* offset= */ 0, null);
|
||||
}
|
||||
} else {
|
||||
// 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;
|
||||
TrackOutput output = currentTrackBundle.output;
|
||||
int sampleIndex = currentTrackBundle.currentSampleIndex;
|
||||
long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L;
|
||||
if (timestampAdjuster != null) {
|
||||
sampleTimeUs = timestampAdjuster.adjustSampleTimestamp(sampleTimeUs);
|
||||
}
|
||||
if (track.nalUnitLengthFieldLength != 0) {
|
||||
// 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.
|
||||
@ -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.
|
||||
nalBuffer.setPosition(MimeTypes.VIDEO_H265.equals(track.format.sampleMimeType) ? 1 : 0);
|
||||
nalBuffer.setLimit(unescapedLength);
|
||||
CeaUtil.consume(fragment.getSamplePresentationTime(sampleIndex) * 1000L, nalBuffer,
|
||||
cea608TrackOutputs);
|
||||
CeaUtil.consume(sampleTimeUs, nalBuffer, cea608TrackOutputs);
|
||||
} else {
|
||||
// Write the payload of the NAL unit.
|
||||
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.BUFFER_FLAG_KEY_FRAME : 0;
|
||||
|
||||
@ -1298,10 +1299,17 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
while (!pendingMetadataSampleInfos.isEmpty()) {
|
||||
MetadataSampleInfo sampleInfo = pendingMetadataSampleInfos.removeFirst();
|
||||
pendingMetadataSampleBytes -= sampleInfo.size;
|
||||
long metadataTimeUs = sampleTimeUs + sampleInfo.presentationTimeDeltaUs;
|
||||
if (timestampAdjuster != null) {
|
||||
metadataTimeUs = timestampAdjuster.adjustSampleTimestamp(metadataTimeUs);
|
||||
}
|
||||
for (TrackOutput emsgTrackOutput : emsgTrackOutputs) {
|
||||
emsgTrackOutput.sampleMetadata(
|
||||
sampleTimeUs + sampleInfo.presentationTimeDeltaUs,
|
||||
C.BUFFER_FLAG_KEY_FRAME, sampleInfo.size, pendingMetadataSampleBytes, null);
|
||||
metadataTimeUs,
|
||||
C.BUFFER_FLAG_KEY_FRAME,
|
||||
sampleInfo.size,
|
||||
pendingMetadataSampleBytes,
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,8 +118,18 @@ public final class DefaultAllocator implements Allocator {
|
||||
}
|
||||
for (Allocation allocation : allocations) {
|
||||
// Weak sanity check that the allocation probably originated from this pool.
|
||||
Assertions.checkArgument(allocation.data == initialAllocationBlock
|
||||
|| allocation.data.length == individualAllocationSize);
|
||||
if (allocation.data != initialAllocationBlock
|
||||
&& allocation.data.length != individualAllocationSize) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected allocation: "
|
||||
+ System.identityHashCode(allocation.data)
|
||||
+ ", "
|
||||
+ System.identityHashCode(initialAllocationBlock)
|
||||
+ ", "
|
||||
+ allocation.data.length
|
||||
+ ", "
|
||||
+ individualAllocationSize);
|
||||
}
|
||||
availableAllocations[availableCount++] = allocation;
|
||||
}
|
||||
allocatedCount -= allocations.length;
|
||||
|
Loading…
x
Reference in New Issue
Block a user