Find sbgp and sgpd boxes with grouping_type == seig in the case they don't
come first. Previoulsy we would only find them if they came first.
Issue: Issue: #7716
PiperOrigin-RevId: 325407819
The sniffer sniffs boxes at the start of the file to try and determine
whether the file is fragmented. However, if the file is extremely short
then it's possible that sniffing will try and read beyond the end of
the file, resulting i EOFException being thrown.
In general it's OK for sniffing to throw EOFException if the file is
not of the correct type. The problem in this case is that EOFException
can be thrown for an actual MP4 file, due to the sniffer continuing up
sniff atoms up to bytesToSearch in case the file is fragmented.
PiperOrigin-RevId: 325205389
Having both in the trun box is not allowed (see section section 8.8.8.1
of ISO/IEC 14496-12:2015) but this CL makes the code more robust in case
this happens. Before this change, the first sample flag was not read,
making subsequent reads incorrect.
Issue: #7698
PiperOrigin-RevId: 325212160
Float values are allowed to be > 0dbfs,
it is just not nominal as it will might
distort the signal when played without
attenuation.
This is also consistent with
[AudioTrack.write(FloatBuffer)](https://developer.android.com/reference/android/media/AudioTrack#write(float[],%20int,%20int,%20int)) that explicitly
allows it up to 3dbfs.
PiperOrigin-RevId: 321345077
On reaching the end of the content we would notify content complete
and skip unplayed ads, causing a timeline change. That timeline change
was handled in a way that caused a further timeline change in the
2.11.6 release, where we don't yet deduplicate no-op Timeline changes,
causing repeated timeline changes indefinitely.
At tip-of-tree, the timeline wouldn't refresh repeatedly. However the
code for sending content complete at the point of transitioning to
play a preloaded postroll ad was not correct in that it didn't mark
previous ads as skipped. Instead they happened to be marked as
skipped later on due to the timeline change handling content
completion code triggering again.
Fix this by only marking ads as skipped when content completes once,
to avoid the duplicate timeline change, and moving the skipped ad
marking so it happens in the same place as notifying content complete.
PiperOrigin-RevId: 318454908
Postrolls would be skipped because the period duration wasn't know at
the moment of resuming playback after backgrounding, so the position
wouldn't be resolved to resume the postroll ad.
We have the period duration stored in the AdPlaybackState, so we can
use that directly.
Issue: #7518
PiperOrigin-RevId: 317830418
The IMA SDK now preloads postrolls which is great as we no longer need
to rely on detecting buffering at the end of the stream to trigger
playing postrolls.
Add in the required logic to detect the period transition to playing
the postroll.
Issue: #7518
PiperOrigin-RevId: 317610682
We currently get float ad cue points from IMA, but store these as
longs in microseconds. The cast from double to long would take the
floor of the value, which could lead to stored ad cue points being
off-by-one. Use Math.round to avoid this.
ImaAdsLoader also has code to map a double AdPodInfo position (which
should match a cue point) onto the corresponding ad group index by
searching the long ad cue points. Match the calculation used where we
map float cue points, including narrowing the position to a float
first to avoid regressions if IMA SDK behavior changes to represent
positions in more than float precision later, and also remove the
requirement that the ad positions match exactly as a defensive
measure.
PiperOrigin-RevId: 317607017
After an ad pod coming up has preloaded, if the user seeks before it
plays we get pauseAd/stopAd called for that ad pod. Also, the ad will
not load again. Work around this unexpected behavior by handling
pauseAd/stopAd and discarding the ad.
In future, it's likely that the IMA SDK will stop calling those
methods, and will loadAd again for the preloaded ad that was
unexpectedly discarded. This change should be compatible with that,
because the ad won't be discarded any more due to not calling stopAd.
Issue: #7492
PiperOrigin-RevId: 316873699
Ads can appear due to asynchronous ad tag requests completing after
earlier ads in a pod have loaded, so remove the requirement that the
ad count can't change. The MediaPeriodQueue should handling discarding
buffered content if an ad appears before already buffered content, so
I think this case is actually handled correctly by the core player
already.
Also remove the requirement that an ad URI can't change. This is a
defensive measure for now, but it's likely that a later fix in the IMA
SDK for an issue where loadAd is not called after preloading then
seeking before a preloaded ad plays will result in loadAd being called
more than once, and I think it's possible that the second call to
loadAd may have a different URI. Because the ad URI should only change
after an intermediate seek to another MediaPeriod, there shouldn't be
any problems with buffered data not getting discarded.
Issue: #7477
PiperOrigin-RevId: 316871371
The release() method was added in the recent IMA API changes for
preloading and now 'collides' with the ExoPlayer AdsLoader release
method. This led to all ads completing being treated as a call to
completely release the ads loader, which meant that the ad playback
state was not updated on resuming after all ads had completed, which
in turn led to playback getting stuck buffering on returning from the
background after all ads played.
Move the IMA callbacks into an inner class to avoid this.
Issue: #7508
PiperOrigin-RevId: 316834561
- Leaving the TODO, since there are still MIME types we're unsure about.
- Removing AAC because xHE-AAC does not have this property. We may re-add
it with an additional profile check to exclude xHE-AAC in the future.
PiperOrigin-RevId: 316715147
We're then able to use this same helper class from tests, to avoid
running into spurious failures caused by long microseconds being
round-tripped through float seconds.
PiperOrigin-RevId: 316435084
Some but not all VideoAdPlayer callbacks from the IMA SDK included
defensive handling of unexpected cases. Add the remaining ones.
Issue: #7492
PiperOrigin-RevId: 316082651
In a later change it will be necessary to be able to destroy the ads
manager if all ads are skipped while creating ads rendering settings.
This change prepares for doing that by not having the ads manager
passed into the method (so the caller can null or initialize it).
PiperOrigin-RevId: 315488830
Previously the fake ads loader listener would always pass the same ad
durations to the fake player, but actually the known ad durations can
change during playback.
Make the fake behavior more realistic by only exposing durations for
ads that have loaded.
PiperOrigin-RevId: 314956223
We currently have a currentMediaPeriodId and an activeSessionId that are more
or less tracking the same thing unless the current media period isn't "active" yet.
Simplify this logic by using a single currentSessionId field and the respective
isActive flag of this session. Also move all session creation and activation code in
the same method to make it easier to reason about the code.
This change also fixes a subtle bug where events after a seek to a new window
are not ignored as they should.
PiperOrigin-RevId: 289432181
Currently, this method is only supposed to be called before removing
the listener from the player or when releasing the player.
If called at other times, it will throw an exception later when
a playback session is ended automatically.
issue:#7193
PiperOrigin-RevId: 308254993