Gradle Lint doesn't recognise `checkState` assertion and TargetApi should only ever be used for suppressing a bug in Android Lint. Hence, we keep @RequiresApi and add an if-statement explicitly. Also, fixes >26 to >=26 for the version check.
PiperOrigin-RevId: 555144577
(cherry picked from commit f7c31bd3ef)
Updates to the ad playback state are posted on the main handler,
so they may arrive after the source has already been released
(=the internal MediaSource is null). This can cause NPEs.
PiperOrigin-RevId: 555102426
(cherry picked from commit 20d2ce7ce8)
When hardware buttons are used to control the volume of the remote device, the call propagates to `MediaSessionCompat.setPlaybackToRemote(volumeProviderCompat)`. However, `volumeProviderCompat` was created incorrectly when the new device volume commands were present (COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS and COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS), i.e. with volumeControlType = `VOLUME_CONTROL_FIXED`. This resulted in `VolumeProviderCompat` which doesn't call `onSetVolumeTo` or `onAdjustVolume` and hence doesn't propagate the calls to the `Player`. Instead, it only worked with the deprecated commands which ensured the volumeControlType was `VOLUME_CONTROL_ABSOLUTE`.
This bug was introduced in c71e4bf1ff (1.0 media 3 release) when `PlayerWrapper`'s call to `createVolumeProviderCompat` was mostly rewritten to handle the new commands, but the two if-statements were not amended. Note: this change fixes the bug only for Android 11 and below. For 12 and above, there is a tracking bug for the regression that was introduced: https://issuetracker.google.com/issues/201546605http://Issue: androidx/media#554
PiperOrigin-RevId: 554966361
(cherry picked from commit dedccc596e)
This fixes a bug with playing very short audio files, introduced by
fe710871aa
The existing code using floor integer division results in playback never
transitioning to `STATE_ENDED` because at the end of playback for the
short sample clip provided `currentPositionUs=189937`,
`outputSampleRate=16000` and `(189937 * 16000) / 1000000 = 3038.992`,
while `writtenFrames=3039`. This is fixed by using `Util.ceilDivide`
so we return `3039`, which means
`AudioTrackPositionTracker.hasPendingData()` returns `false` (since
`writtenFrames ==
durationUsToFrames(getCurrentPositionUs(/* sourceEnded= */ false))`).
Issue: androidx/media#538
PiperOrigin-RevId: 554481782
(cherry picked from commit 6e91f0d4c5)
Refactored `CmcdLog` to `CmcdHeadersFactory` for improved representation of its purpose and updated implementations.
#minor-change
PiperOrigin-RevId: 552831995
Fix short term reference picture list parsing. Before this change, `deltaPocS0`
was derived by adding one to the value of the syntax element
`delta_poc_s0_minus1`, but (maybe surprising) the specification actually says
that `DeltaPocS0[stRpsIdx][i]` should be assigned the negation
`-(delta_poc_s0_minus1[i] + 1)` on the first iteration, then that value added
to the previous value on previous iterations. See equations (7-67) to (7-70) in
the 2021-08 version of the H.265/HEVC specification.
Also read the number of long term reference pictures once rather than on every
loop iteration (subsection 7.3.2.2.1).
PiperOrigin-RevId: 551852999
(cherry picked from commit ddb0f86604)
The current code multiplies the value by 1000 twice,
effectively converting to nanoseconds.
#minor-release
PiperOrigin-RevId: 551129750
(cherry picked from commit f766936140)
Updated `ExoTrackSelection` to provide the most recent bitrate estimate, enabling the inclusion of measured throughput (mtp) as a CMCD-Request field in Common Media Client Data (CMCD) logging.
Additionally, made changes to the `checkArgument` methods in `CmcdLog` to prevent the use of default values in certain cases.
PiperOrigin-RevId: 549369529
(cherry picked from commit cdb174c91a)
The streams return end-of-input if they read no samples, but know that
they are fully buffered to at least the clipped end time. This helps to
detect the end of stream even if there are no new buffers after the end
of the clip (e.g. for sparse metadata tracks).
The race condition occurs because the buffered position is evaluated
after reading the sample. So between reading "no sample" and checking
the buffered position, the source may have loaded arbitrary amounts
of data. This may lead to a situation where the source has not read
all samples, reads NOTHING_READ (because the queue is empty) and then
immediately returns end-of-stream (because the buffered position
jumped forward), causing all remaining samples in the stream to be
skipped. This can fixed by moving the buffered position check to
before reading the sample, so that it never exceeds the buffered
position at the time of reading "no sample".
#minor-release
PiperOrigin-RevId: 548646464
(cherry picked from commit c64d9fd6da)
Add Ogg ID Header and Comment Header Pages to the Ogg encapsulated Opus for offload playback. This further matches the RFC 7845 spec and provides initialization data to decoders.
PiperOrigin-RevId: 548080222
(cherry picked from commit 847f6f24d3)
This change also marks the buttons of the custom layout as
enabled/disabled according to available commands in the controller.
Accordingly, `CommandButton.Builder.setEnabled(boolean)` is deprecated
because the value is overridden by the library.
Issue: androidx/media#38
PiperOrigin-RevId: 547272588
(cherry picked from commit ea21d27a69)
Based on the spec, ETSI TS 102 366 V1.4.1 Annex F, 6 bits should have skipped instead of 6 bytes.
This correction was pointed out in Issue: androidx/media#474.
PiperOrigin-RevId: 545658365
(cherry picked from commit 07d4e5986b)
We introduced truncation to 32 chars in <unknown commit>
and included indent and offset in the calculation. I think this is
technically correct, but it causes problems with the content in
Issue: google/ExoPlayer#11019 and it doesn't seem a problem to only truncate actual
cue text (i.e. ignore offset and indent).
PiperOrigin-RevId: 544677965
(cherry picked from commit e8fdd83558)
Add a fail-fast check in `ExoPlayerImpl` to ensure the equality of the lengths of `ShuffleOrder` and the current playlist. Also improve the documentation of `setShuffleOrder(ShuffleOrder)` with explicit instruction on this.
Issue: androidx/media#480
#minor-release
PiperOrigin-RevId: 544009359
(cherry picked from commit d895a46b28)
It currently wrongly documents that it is only called before reading
streams (that has never been the case and all MediaPeriods already need
to handle calls after reading samples from the streams).
It was also a bit unclear what a discontinuity implies and the new
Javadoc calls out the main use case for discontinuties and the intended
meaning of returning a discontinuity.
#minor-release
PiperOrigin-RevId: 543989124
(cherry picked from commit b324b8aa72)
MP4 edit lists sometimes ask to start playback between two samples.
If this happens, we currently change the timestamp of the first
sample to zero to trim it (e.g. to display the first frame for a
slightly shorter period of time). However, we can't do this to audio
samples are they have an inherent duration and trimming them this
way is not possible.
PiperOrigin-RevId: 543420218
(cherry picked from commit 2322462404)
`MediaControllerImplBase` has 2 methods for updating listeners about `PlayerInfo` changes - `updatePlayerInfo` (for masking the state) and `onPlayerInfoChanged` (when communicating with the session). There is a set number of listener callbacks related to `PlayerInfo` updates and both methods should go through the same control flow (whether we know that masking will ignore most of them or not).
A unified method `notifyPlayerInfoListenersWithReasons` encapsulates only the shared logic of 2 methods - listeners' callbacks. This ensures that both methods call them in the same order and none are missed out.
PiperOrigin-RevId: 542587879
(cherry picked from commit c2d8051662)
The callbacks for `PlayerInfo` changes are currently in both `MediaControllerImplBase.updatePlayerInfo` (masking) and `MediaControllerImplBase.onPlayerInfoChanged`. But the order was different between them both and `ExoPlayerImpl.updatePlaybackInfo` which they are trying to mimic.
#minor-release
PiperOrigin-RevId: 542519070
(cherry picked from commit b8ac5b4210)
When an app tried to re-prepare a live streeam with server side inserted
ad after a playback exception, the player tried to find the ad group by
its index in the ad playback state of the next timeline when creating
the first period.
If a source that supports server side ad, has removed the ad playback
state when the source has been removed, this causes a crash. For live
streams this is a reasonable thing to do given the exception could be
caused by an invalid ad playback state.
This change removes the ad metadata from the current period for live
streams and the timeline. In case the ad playback state is not reset
by the source, the first timeline refresh would ad the metadata again.
PiperOrigin-RevId: 541959628
(cherry picked from commit 4604f0cde6)
Some events may arrive after the playlist is cleared (e.g. load
cancellation). In this case, the DefaultPlaybackSessionManager may
create a new session for the already removed item.
We already have checks in place that ignore events with old
windowSequenceNumbers, but these checks only work if the current
session is set (i.e. the playlist is non-empty). The fix is to add
the same check for empty playlists by keeping note of the last
removed window sequence number.
PiperOrigin-RevId: 541870812
(cherry picked from commit e0191ddded)
Instead of providing `playbackDurationUs` and `loadPositionUs` individually, which are used to calculate the buffer duration for CMCD logging, we can directly pass the pre-calculated `bufferedDurationUs` available in the `getNextChunk` method of the chunk source classes.
Issue: google/ExoPlayer#8699
#minor-release
PiperOrigin-RevId: 540630112
(cherry picked from commit be9b057dda)
Additionally, two existing methods to `buildDataSpec` in `DashUtil` have been deprecated, while a new method has been added that allows the inclusion of `httpRequestHeaders`.
Issue: google/ExoPlayer#8699
#minor-release
PiperOrigin-RevId: 540594444
(cherry picked from commit 52878b2aca)
Current behaviour causes an app to crash if it receives an unrecognized repeat mode send over the wire. In order to avoid the crash, a sensible default had to be chosen.
For `Player.RepeatMode`, it is `Player.REPEAT_MODE_OFF`, which is the same value we use as default when unbundling `PlayerInfo`.
For `PlaybackStateCompat.RepeatMode`, it is `PlaybackStateCompat.REPEAT_MODE_NONE`, which is what we use in the no-arg `LegacyPlayerInfo` constructor.
Issue: androidx/media#448
#minor-release
PiperOrigin-RevId: 540563792
(cherry picked from commit 501da109ce)
These comments reflect the parameter names of the constructor that
we're reflectively calling, but errorprone complains that they don't
match the parameter names of `Constructor.newInstance`.
PiperOrigin-RevId: 540348118
(cherry picked from commit 567890da9e)