In general, metrics collection should not lead to Transformer thorwing and crashing the app.
PiperOrigin-RevId: 739099456
(cherry picked from commit 3f5019b9088555e8bbbd492901c272ae47b5fb67)
If a recoverable renderer error occurred just before playing period transition(aka media item transition) then the player may enter a continuous loop of retrying to play the previous media item.
This was most easily reproduced in an audio offload scenario where init in offload mode always fails. In initializing the following media, the process would fail with recoverable error to try in non-offload mode. The player would try to recover with playing the previous media item. Most times it would skip to the next track but not always.
Issue: androidx/media#2229
PiperOrigin-RevId: 741213293
The current instanceof check accidentally unpacks the child,
returning the inner period instead of the one passed to the source.
PiperOrigin-RevId: 746556825
(cherry picked from commit 68538029c926642da42a7ebf40543f480c38146e)
Compute a precise average bitrate using total sample size (from `stsz`) and media duration (from `mdhd`), overriding any existing bitrate read from `btrt` or `esds` boxes.
PiperOrigin-RevId: 746497934
(cherry picked from commit 6f5982792aadc9fa795629758015d952323d5654)
In `PreloadMediaSource` we accesses the `MediaPeriod.getBufferedPositionUs()` when we receive `onContinueLoadingRequested()` from the period. For `ProgressiveMediaPeriod` which requires loading a portion of media file to get it prepared, there is a chance that it needs more than one round of `onContinueLoadingRequested()` -> `continueLoading()` to complete preparation, for example, when the `setContinueLoadingIntervalBytes()` is small enough to not include the full information for preparation. Thus we should avoid `MediaPeriod.getBufferedPositionUs()` being called before period is prepared, as it will fail at `assertPrepared`.
Issue: androidx/media#2315
PiperOrigin-RevId: 746490375
(cherry picked from commit 344f249511ad67a42d8328e79102f02bbbec5201)
Some interactions create a default notification provider if
no custom one is set yet (e.g. setForegroundServiceTimeoutMs).
This means a later call to setMediaNotificationProvider will
silently fail to apply the new provider.
This can be fixed by making the media notification provider
updatable.
Issue: androidx/media#2305
PiperOrigin-RevId: 746428193
(cherry picked from commit 9ca8540f85fba2ff5c8ff151706f36e7b30b46e6)
In `PlayerWrapper.getCurrentTimelineWithCommandCheck()` we
always return `new CurrentMediaItemOnlyTimeline(this)` in
case the wrapped player doesn't have `COMMAND_GET_TIMELINE`
available but has `COMMAND_GET_CURRENT_MEDIA_ITEM`. This is
emulating a single item timeline with a static window count
of 1 which isn't correct when the wrapped player is empty.
Instead, when the wrapped player is empty we need to return
an empty timeline to match the wrapped player.
Issue: androidx/media#2320
PiperOrigin-RevId: 746071237
(cherry picked from commit 5f940af3df5e644b33d45c78cd5103f78566efd0)
Currently, a notification may be recreated even if a user dismissed
it as long as the standard conditions for a notification are true.
To avoid this effect, we plumb the dismissal event to the notification
controller, so that it can override its `shouldShowNotification`
decision. The plumbing sets an extra on the media key intent, which
the session forwards as a custom event to the media notification
controller if connected.
Issue: androidx/media#2302
PiperOrigin-RevId: 745989590
(cherry picked from commit f672590b2deeffb06435eb542cfe0d0630894e92)
The surface must only be used by one player at a time. To ensure
that, we can keep a reference to the previously used player
and clear its surface reference before assigning to a new one.
Note that we do not need to clear the surface in onDispose
of a DisposableEffect because the lifecycle management of the
surface is moved to the Player and the Player takes care of
unregistering its surface reference as soon as the surface is
destroyed (which happens when the AndroidView element is no longer
is the Composable tree).
PiperOrigin-RevId: 745558414
(cherry picked from commit f9617e1f8dade2b957fefd7eaa69da6d5c158eb8)
Previously, encrypted media segments did not have the chunk duration set,
causing an assertion failure during `CmcdData` creation. With this change,
the chunk duration is always set, while `CmcdData` ensures it is applied
only for media chunks.
Issue: androidx/media#2312
PiperOrigin-RevId: 745196718
(cherry picked from commit 9182b413dc6e14ed06817d8ad4ae65ce01d85f1b)
This is a workaround for a bug where the positionUs seen by
MCVR jumps when audio pre-roll samples are discarded.
PiperOrigin-RevId: 743538208
(cherry picked from commit 036bed36326130294f50264659913bdcecb4c9bc)
ExoPlayer disables sleeping for offload when the reading period advances and re-evaluates turning it back on when the playing period advances. For playlists of short items where the reading period could advance much further than the playing period, sleeping should still be disabled until the playing period advances to match the current reading period.
Issue: androidx/media#1920
PiperOrigin-RevId: 743503063
(cherry picked from commit 8327a2a52dd72a98d4abc123f33cfe1250898318)
The assertion is changed to check that the number of passed
in arrays of durations is always matching `adGroupCount`
according to the behavior of `withRemoveAdGroupCount(int)`.
Issue: androidx/media#2267
PiperOrigin-RevId: 743185176
(cherry picked from commit d133300627a3d5757c7dd63fc008b2cf9afc70ba)
Applications providing custom `AudioSink` implementations should have the dynamic scheduling for audio playback fallback to the static interval if they are not implementing `AudioSink#getAudioTrackBufferSizeUs()`.
PiperOrigin-RevId: 743082057
(cherry picked from commit 9e80d6d263d04021e24d4897f415898964a93a05)
Frame rate is correctly determined using the media duration from the `mdhd` box and the sample count from the `stsz` box. The fallback calculation using the edited sample count and `tkhd` box duration is incorrect, as added silence at the beginning can increase the track duration without affecting the sample count.
No-op change, as we never use the fallback calculation for our sample files in the test.
PiperOrigin-RevId: 743081118
(cherry picked from commit c0e518df9709cc858c0610e4694d8753bdb638b7)
The proxy classes Android(Embedded)ExternalSurface just provide a
simple API surface around AndroidView wrapping SurfaceView and
TextureView respectively. However, this prevents accessing the
underlying views directly, which is needed for full lifecycle
tracking by the Player and to access surface size updates (which
are not available when the API is reduced to just `Surface`).
Instead of the proxy classes, we can directly use AndroidView from
PlayerSurface. This allows to call the proper Player APIs to set
SurfaceView or TextureView, so that the Player can keep track of
the view lifecycle and update its internal state and size tracking
accordingly. Because the player keeps tracks of the lifecycle,
none of the callback structure in Android(Embedded)ExternalSurface
is needed, nor are the additional setters for options that are
all default.
PiperOrigin-RevId: 743079058
(cherry picked from commit a1ed0d4ff63fc9e359c8ef1bc53aae43e4b709e3)
For now, even if a recoverable error occurs during pre-warming, the current process will be that pre-warming is disabled until subsequent media item transition.
PiperOrigin-RevId: 740349517
(cherry picked from commit 6e510c26df0d354312abe480b238afa47abedd3d)
If the `RtspMediaSource.Factory` is provided a `MediaItem` containing a uri with the scheme `rtspt`, then the factory will create its `RtspMediaSource` configured to use TCP.
Issue: androidx/media#1484
PiperOrigin-RevId: 740340604
(cherry picked from commit a220b0cb5e16e6cb8d8719a0e1ffa7e00859abc0)
The `KEY_TRACK_ID` was incorrectly set to the track index instead of the track ID from the media file.
PiperOrigin-RevId: 738761146
(cherry picked from commit 99f364992afa35aa1dba6621ffaa0dc7f1247327)
Language codes in the `mdhd` box are stored as three 5-bit values, each representing a letter ('a' to 'z') using an offset of `0x60`. If the decoded characters are not in this range, the language should be treated as undefined.
PiperOrigin-RevId: 738470544
(cherry picked from commit 2a4cbc3be47b54a59aef384b288ea802e34fb2f0)
The comment sounds like it is worried the next header won't fit after
`limit` and before the end of `data`, but the code was previously only
checking the space between `position` and `limit`. This led to some
unnecessary copies.
Running the Robolectric `FlacExtractorTest.sample()` test in only the
'partial reads' and I/O errors case (worst case for this bug) results
in 57271 copies without this fix, and 19 copies with it.
Sample of the first 10 copies before this fix, showing a copy is made
for every byte read from the input:
```
W/ibaker: Making a copy. input.position=8881, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8882, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8883, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8884, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8885, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8886, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8887, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8888, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8889, data.length=32768, pos=1, lim=1
W/ibaker: Making a copy. input.position=8890, data.length=32768, pos=1, lim=1
```
And the first 10 copies after the fix:
```
W/ibaker: Making a copy. input.position=41648, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=74401, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=107154, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=139907, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=172660, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=41648, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=74401, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=107154, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=139907, data.length=32768, pos=32753, lim=32768
W/ibaker: Making a copy. input.position=172660, data.length=32768, pos=32753, lim=32768
```
PiperOrigin-RevId: 738341007
(cherry picked from commit 71ff9c661cccaf2d0c0f9c67008911b4ec5a4397)
This field has been used for encoded FLAC data since ba8f55694a
PiperOrigin-RevId: 736811640
(cherry picked from commit fe8163838ed4adead705e2a537973d3c741f5d8e)
In certain bluetooth playback scenarios, it was found that the delta of audio duration written by the AudioSink from the current playback position was greater than the size of the audio track buffer, causing underruns.
The solution is to utilize the audio track buffer size as an upper limit for an audio renderer's getDurationToProgress.
PiperOrigin-RevId: 735761604
(cherry picked from commit 2729dbb8a9c9ea29d49efd5ffc30e734b7c86048)
Calling a real method on an interface is not supported by
the Mockito version run by Gradle.
#cherrypick
PiperOrigin-RevId: 738358342
(cherry picked from commit d6b9988eb073d30c7074bae44dba2a48e5d6e687)
Pass the temporary CookieHandler as a parameter instead of setting it as a temporary process-default. This avoids a rare race condition, where the player is sending a request with preserveCookies option and runs the `CookieHandler.getDefault()` before a different thread sets a default cookie handler. Over 5 or so lines of code the new default might be reverted to null - this is now fixed.
PiperOrigin-RevId: 738052152
(cherry picked from commit d0d76f214a3417ec39f86b1003dd0850a88638d9)
Ideally, we'd find a more targeted exclusion as it may depend on
specific codecs. The current workaround should help with the
reported issues that are limited to Xiaomi and OPPO.
Issue: androidx/media#2059
#cherrypick
PiperOrigin-RevId: 738017969
(cherry picked from commit 06c0f5549e366071ad98050e85ed0e8f1cd36fdf)
With a [previous change](f05e6a7d6e), we makes `hasPendingData()` return `false` once we've found that the `AudioTrack` has played out all the written frames, to avoid it permanently stays `true` even when the source has ended. However, this is aggressive as the audio output device can still have latency in playing out those frames. So `hasPendingData()` should stay `true` a bit longer (for the duration of `latencyUs`) until finally turn to `false`, as well as the `getCurrentPositionUs()` should increment smoothly without a jump for the duration of `latencyUs`.
PiperOrigin-RevId: 738004292
(cherry picked from commit 6470c97af415d91ad46a1f21c7f2ab5b0716f39c)
The original behaviour of the `handleSetCookieRequests` is preserved.
A bug is addressed, where it woulld set `Set-Cookie` header in the client request (as opposed to the expected `Cookies`).
PiperOrigin-RevId: 732945338
(cherry picked from commit 814d368d9f54f47f6f0372c7905846104c549322)
The original behaviour of the `handleSetCookieRequests` is preserved.
A bug is addressed, where it woulld set `Set-Cookie` header in the client request (as opposed to the expected `Cookies`).
PiperOrigin-RevId: 730857996
(cherry picked from commit 3b38a7a43bc35de1f77338a30bd5dce1d6991e82)
The matroska file works without further changes. The FLAC container
file works with `lib-flac-decoder` depending on a bundled `libflac`
implementation, but not when using
`androidx.media3.extractor.flac.FlacExtractor` with a `MediaCodec` FLAC
decoder because the media3 extractor doesn't support 32-bit FLAC yet.
The fix for that is in a follow-up change.
`bear_32bit.flac` was generated from `bear.flac` with `ffmpeg`:
```shell
$ ffmpeg \
-i bear.flac \
-c:a flac \
-sample_fmt s32 \
-strict experimental \
bear_32bit.flac
```
`bear-flac-32bit.mka` was generated by re-muxing `bear_32bit.flac`,
also with `ffmpeg` (trying to convert `bear-flac-24bit.mka` to 32-bit
didn't work, the resulting file was still 24-bit):
```shell
$ ffmpeg \
-i ../flac/bear_32bit.flac \
-c:a copy \
bear-flac-32bit.mka
```
Issue: androidx/media#2197
PiperOrigin-RevId: 736552251
(cherry picked from commit dfebe72b6a175ed92420c1946bd06b952d85132d)
We currently pretend to be ready when using a placeholder
surface irrespective of whether the renderer is actually
ready to immediately render when a surface is attached.
This causes issues in two ways:
- Apps don't know when a player without a surface can be
connected to a surface and immediately start playing
- A paused player without a surface will use the 1 second
default doSomeWork loop, causing any pending decoding
to be extremely slow (see Issue: androidx/media#1973).
The fix is to let the placeholder surface case use the same
paths as the regular surface and with marking the first
frame as available as soon as the codec output buffer for it
is pending and ready for release.
PiperOrigin-RevId: 737942496
(cherry picked from commit eef678f26382e74edbbd872173508c8642621160)
This brings the parts related to video frame release decision making
in a single place and simplifies the calling side in
MediaCodecVideoRenderer.
PiperOrigin-RevId: 737941729
(cherry picked from commit 0e169ab1bea3a4cd9ff2772d77618c66b5262f3c)
We want to skip the buffers in sync with playback, which
only makes progress once started. This means we can simplify
the logic to only apply the 30ms threashold when started
(which was indirectly the threashold used already because the
frame release would return TRY_AGAIN_LATER).
This means we can remove the
shouldSkipLateBuffersWhileUsingPlaceholderSurface as it was
only used in tests to prevent skipping while we were not
started.
PiperOrigin-RevId: 736533043
(cherry picked from commit 816d5cb86b13629a7ca23dba122f943f175d3bb9)
Calling a real method on an interface is not supported by
the Mockito version run by Gradle.
#cherrypick
PiperOrigin-RevId: 737940266
(cherry picked from commit 4daa43b25727d1d197095d0a9e2cc5a3610d881a)
We currently throw an exception if the start time exceeds the
auto-detected end time at the duration even though an app can't
know this in advance in all cases. We should still throw an
exception if app-provided input values are non-sensical, but
auto-adjust the start time to the duration if needed similar to
how we already adjust the end time.
PiperOrigin-RevId: 737585207
(cherry picked from commit 343a7b054e3e90974c6930f56230b2e96c440d4e)
Previously we only enable `SeekParameter.*_SYNC` for HLS when `EXT-X-INDEPENDENT-SEGMENTS` is set in the playlist. However, this condition can actually be loosened. To seek in HLS, we need to download the segment in which the resolved seek position locates under any circumstance. If `SeekParameter.PREVIOUS_SYNC` or `SeekParameter.CLOSEST_SYNC` is passed, and that segment happens to start with sync samples, then the seek can be done quicker with that adjusted seek position. And if that segment doesn't start with sync samples, then the behaviour will be the same as we set the adjusted seek position to the exact original position. But we still cannot safely enable `SeekParameter.NEXT_SYNC` as it will potentially cause the seeking to miss more content than seeking to the exact position.
Issue: androidx/media#2209
PiperOrigin-RevId: 737580861
(cherry picked from commit 42b71c29e8bca0369381d100d5cec912e1c1e7ef)
This transforms the reported format support from `supported=YES` to
`supported=NO_EXCEEDS_CAPABILITIES`. Playback is still attempted in the
main demo app, and hangs as described in
https://github.com/androidx/media/issues/2197#issuecomment-2722322954.
PiperOrigin-RevId: 737568955
(cherry picked from commit 27eb204542dd461a8d77ff58d4ec9599ce336a33)
Without this, 32-bit files fail to play with `Playback stuck buffering
and not loading`. With this change, playback works on devices where the
`MediaCodec` FLAC decoder supports 32-bit, and crashes on devices with a
`MediaCodec` FLAC decoder that does not support 32-bit.
A follow-up change will aim to transform the 'unsupported' case from a
crash into a report that the track format is not supported.
32-bit support was only fully incorporated into the spec when RFC 9639
was [published in December
2024](https://xiph.org/flac/2024/12/19/rfc-9639-published.html), and
it was been supported by `libflac` (for encode and decode) [since
September 2022](https://xiph.org/flac/2022/09/09/flac-1-4-0-released.html).
The original version of this `FlacExtractor` was written before either
of these, so only supported up to 24-bit.
Issue: androidx/media#2197
PiperOrigin-RevId: 737559285
(cherry picked from commit 8837ab25643bf4ed8a0c973ac637b3221e778f6a)
These classes are often logged in error messages or tests. The
current output is just the hash code which makes it hard to debug.
PiperOrigin-RevId: 736799086
(cherry picked from commit 54c64b41c45397f7cc5892a27c541fdbf6a3cd58)
The spec technically allows to mark adaptation sets with the switching
property if they allow seamless switching with non-overlapping
segments. This is typically only used for compatible content (e.g.
different codecs), but the spec allows it to be used for other
content as well (e.g. different languages, roles). ExoPlayer's concept
of a TrackGroup only allows formats with the same language and role
flags to be merged, so we should check that before merging.
Issue: androidx/media#2222
PiperOrigin-RevId: 736564055
(cherry picked from commit d37f05238a2d8b45ea2e5f4ac026084b917f30df)
And improve error message if access to the notification controller
happens without a base context.
#cherrypick
PiperOrigin-RevId: 736545574
(cherry picked from commit 41722be02e34199543dc92c44e12ff95a35cb378)
This allows apps to set a shorter timeout if so desired.
Issue: androidx/media#2206
#cherrypick
PiperOrigin-RevId: 735360459
(cherry picked from commit 222950cfd1bdc942b90e0991e6b96a3f2c86518a)
We currently combine stopping the FGS and optionally removing the
notification in one method, which unnecessarily gates its logic on
checking the desired foreground state again. This causes a bug where
the notification should be removed (because shouldShowNotification
returns false), but stays visible because the service is allowed
to stay in the foreground and the notification removal code is not
triggered.
Issue: androidx/media#2211
PiperOrigin-RevId: 735126704
(cherry picked from commit 91ecc16198bbb48d114a6d581669a9e670c161da)
PlayerSurface exposing the Modifier argument means the gradle dependency needs to be stricter
#cherrypick
PiperOrigin-RevId: 734237616
(cherry picked from commit 8dcfa1afbead8d7af1e11e871df9359052f107c6)
This was requested in Issue: androidx/media#2191 for playback of Opus and Vorbis
files with more than two channels with a float PCM pipeline.
Also, add ChannelMappingAudioProcessorTest.
PiperOrigin-RevId: 733766680
(cherry picked from commit f996a5e3e4b395fe1782392ae90fb088143aa806)
A state holder that handles interaction with a UI component that toggles through a range of playback speeds.
[demo-compose] Use PlaybackSpeedState to create PlaybackSpeedTextButton
Add the button to the bottom extra controls.
PiperOrigin-RevId: 731449526
(cherry picked from commit addf01b9a84bcea945107b3b2993540ec59fbb54)
AudioManager internally assumes the thread is was created on can be
used as a callback thread. Since the AudioManager is only created
once in the lifetime of an app, we need to make sure its obtained
on a thread that stays alive.
#cherrypick
PiperOrigin-RevId: 732072255
(cherry picked from commit 2088697a19ac85feb26ba2521a70647803246571)
On API < 26, the callback thread couldn't be set and the current compat
code assumes it's always the main thread. This isn't true, however,
because AudioManager uses the thread on which it was first instantiated
anywhere in the app.
#cherrypick
PiperOrigin-RevId: 731696188
(cherry picked from commit 1ac82d982460f47589484052f57e27a63b0eb08b)
Without this change, content that contains a PSSH box with only
the ClearKey UUID is not playable on devices with API < 27.
This includes our `sample_fragmented_clearkey.mp4` test content.
PiperOrigin-RevId: 731308444
(cherry picked from commit 275e7d3dbddd04792b472a06ff808f748237f8d5)
When there is both audio and video track, then fragment
creation is driven by video track (a combination of duration
so far + next key frame). But if there is no video track, then
the duration so far drives the fragment creation.
Due to bug, when there is only audio track, only first
fragment was created as expected and then a new fragment is
created for every audio sample.
PiperOrigin-RevId: 731257696
(cherry picked from commit d16fdcb8cc832909b1ff531a00e595c64df5c799)
This ensures all AudioManager calls are moved off the main
thread.
Having the audio focus management on the playback thread
also allows future improvements like requesting audio focus
only just before the player becomes ready (which is recommended
but not currently done by ExoPlayer).
PiperOrigin-RevId: 730962299
(cherry picked from commit 19c7b2127568e05b829efe2d9943be04657cefd1)
This resolves an app crash on devices with Google Play Services
installed but disabled due to `FLAG_MUTABLE` on a `PendingIntent`.
Issue: androidx/media#2178
#cherrypick
PiperOrigin-RevId: 730885329
(cherry picked from commit c4eef6042bbd814cbf25b3bb91ae1433618a290a)
Before API 27, the platform DRM components incorrectly expected
`C.COMMON_PSSH_UUID` instead of `C.CLEARKEY_UUID` in order to perform
ClearKey decryption. `FrameworkMediaDrm` is responsible for doing this
adjustment on these API levels, but this call was missed when
refactoring some DRM code in
c872af4bc0.
This led to `MediaCodec$CryptoException: Operation not supported in this
configuration` errors when doing ClearKey playback on devices with
API < 27. This was because the earlier, clearer error from the
`MediaCrypto` constructor was being swallowed and transformed to
`requiresSecureDecoder = true` by the `catch` logic in
`FrameworkMediaDrm.requiresSecureDecoder`.
This change also makes the error handling in
`FrameworkMediaDrm.requiresSecureDecoder` more robust by assuming
`requiresSecure = false` for ClearKey (and true for all other DRM
schemes), since we know that ClearKey never supports secure decoding.
This will help avoid more ClearKey playback failures if we see other,
unrelated, errors at this point.
Issue: androidx/media#1732
#cherrypick
PiperOrigin-RevId: 730882278
(cherry picked from commit ecb83f3b738db25f503153617ba9db7bb9dc5b4b)
HLS extractors were missing
experimentalSetCodecsToParseWithinGopSampleDependencies prior to this patch.
PiperOrigin-RevId: 730878460
(cherry picked from commit da402cfd64ef3ae60607491730f01138177a077b)
This was introduced in 841bdc6efe.
There's no need to cast the `char` (2 bytes) down to a `byte` in order
to pack it into an `int` (4 bytes) alongside a short (2 bytes).
We also don't need to use `short` to track the character count (max 4
with UTF-8) - a single byte is enough. This change also uses
`Ints.fromBytes` to avoid having to reason about how casting &
bit-shifting interact.
This change introduces a test which reproduces the failure reported in
Issue: androidx/media#2167.
#cherrypick
PiperOrigin-RevId: 730809219
(cherry picked from commit fe19d8c9be94bbf1a1be8d3f49b2de52f0e2f1ae)
If the deprecated path without a context is used, the capabilities
are set externally and can't recover automatically back to the real
capabilities.
Issue: androidx/media#2168
PiperOrigin-RevId: 730427339
(cherry picked from commit 5610cc846589aafa416c39567f4f5599e98a77ef)
Dropping too many consecutive input buffers reduces the update
frequency of MCVR.shouldDropDecoderInputBuffers and can lead to
dropping too many consecutive input buffers.
Discarding input buffers of type OBU_FRAME_HEADER with
show_existing_frame = 1 saves a smaller amount of resources
than discarding input buffers of type OBU_FRAME.
PiperOrigin-RevId: 730362707
(cherry picked from commit 67e99f46481dbc5fff9ffd04ff13119dac9199bb)
`onConnect_controllerInfo_sameInstanceFromServiceToConnectedControllerManager`
was flaky because `onDestroy()` of `MockMediaSessionService` was cleaning
up the `TestServiceRegistry`. This includes releasing the session of the service
after which no further `MediaSession.Callback` methods are called. This created
a race between `Callback.onDisconnected` and the `Mediasession.release()` being
called.
`onDestroy()` is called unexpectedly early because the controller unbinds as the
last controller from the service that never was started (`onStartCommand` never
called). In such a case the service is immediately terminated by the system after
the last client unbinds from the service, which called `onDestroy()` on the mock
service.
This change making `MockMediaSessionService` optionally not clean up the
registry in `onDestroy()` prevents the session from being released too early.
Alternatively, starting playback and hence starting the service into the
foreground would prevent the problem as well for the purpose of the test.
Another alternative to fix the test would be removing the session from the
service before releasing the controller.
PiperOrigin-RevId: 730361199
(cherry picked from commit fbe186a70ccb588889d0909ccfc07affaf49ec51)
If the name does not match patten, it gets skipped when reporting.
PiperOrigin-RevId: 729463344
(cherry picked from commit 23ebea7ab4afe1cff4b4c3fce222e33639dfd34e)
We currently only catch IOExceptions to close the opened data source.
This means any other type of exception leaves the data source open,
which can caused SimpleCache to be blocked forever when another
data source tries to access the same cache area (which is still
locked by the open data source).
This problem was the cause for flakiness in DownloadManagerDashTest.
#cherrypick
Issue: google/ExoPlayer#9760
PiperOrigin-RevId: 729441817
(cherry picked from commit 72c85aa48393e47642688c8147bdf18d6e3d4bbf)
In some cases, the ExoPlayer immediately transitions to `STATE_IDLE` or `STATE_ENDED` on application thread, while `isLoading` can still remain as `true` before it is finally updated from playback thread.
Issue: androidx/media#2133
#cherrypick
PiperOrigin-RevId: 728724157
(cherry picked from commit daf8f9ff584e52128b94b4b08a1e9cf7ba94dee2)
This is done by getting the session ID for the `EditingSession` and making sure it's unique from the other session ID.
PiperOrigin-RevId: 728680628
(cherry picked from commit ae3eed234382d95bd9187c965c6b949be97fda63)
Add VP9 and APV codecs to the list of supported video mimetypes for Mp4Muxer and Fragmented Mp4Muxer.
PiperOrigin-RevId: 728603222
(cherry picked from commit 1461e9e93a94e2cb27c096dea2c6c2eee934c3df)
This ensures it's easier to handle these State updates in other
helper classes if needed.
Issue: androidx/media#2128
PiperOrigin-RevId: 728264396
(cherry picked from commit f1c62c12394e3c408b24d98ed2472ed88db3e918)
The publish task currently forces to run lint and test
even though there is no technical dependency. If a
process (e.g. releasing a new library) wants to verify
lint and test work, it should run these steps explicitly.
#cherrypick
PiperOrigin-RevId: 728234811
(cherry picked from commit 4b991ad42f3139e7e528a87bf19056bfdb5d9f5a)
This includes creating a new Factory for `MetricsReporter` and adding it to Transformer. This is done as we need to create a new `MetricsReporter` for each export operation, so it makes sense to have a Factory.
PiperOrigin-RevId: 727798528
(cherry picked from commit 6d408c2d31bddacb254bb0cc917e4ecd5d0e4b66)
Update the CSD to contain only the APVDecoderConfigurationRecord and the apvC box to be a full box. The apv clip is also updated to be consistent with the new [specification](https://github.com/AcademySoftwareFoundation/openapv/blob/main/readme/apv_isobmff.md#isobmff-binding-for-apv).
The clip is provided by the openAPV team under BSD-3 license.
PiperOrigin-RevId: 727868656
(cherry picked from commit 653470f73be98e01e972513ec80e58c2d36cbb3a)
Otherwise it's impossible to install the androidTest apk
of both lib-datasource and lib-exoplayer on the same device
#cherrypick
PiperOrigin-RevId: 727867871
(cherry picked from commit 527e1d52aedbff53e3ba670d2b6a3cf0b0a84abb)
Following the README, a libflac directory is created, which
needs to be ignored in VCSs
#cherrypick
PiperOrigin-RevId: 727103140
(cherry picked from commit b306b1059772c2e279020f65ac60ae975fca3fbf)
Currently, as soon as the playback is considered disengaged (not
ready and playing), the foreground service is stopped.
This causes problems if the app or the user attempts to restart
playback after a short amount of time, where apps may run into
foreground service start restrictions.
Almost all of these short-term interaction issues can be solved
by keeping the foreground service running for an additional
timeout period, which is chosen to be 10 minutes to match the
behavior of future Android system enforcements. For any longer
term interactions, apps need to implement playback resumption
paths that can restart the service with the previous playback.
One caveat is that we currently use player.pause() as a way to
stop the foreground service in onTaskRemoved() if the app wants
to abandon playback at this point. With the timeout, the service
can no longer be stopped immediately just by calling pause(),
so we need to explicitly disable the timeout in the corresponding
helper method.
Issue: androidx/media#1928
Issue: androidx/media#111
PiperOrigin-RevId: 726942625
(cherry picked from commit 8a888d0d1801ce018b5bca5dbab78be44507286e)
500ms may not be enough to start playback on a slow device
#cherrypick
PiperOrigin-RevId: 726940099
(cherry picked from commit 792a2ae05dbade27d9cd5a8923a1f3cebf083a91)
Controller and browsers are typically obtained with
Futures.addCallback(future, getMainExecutor()), which triggers
the onSuccess callback with a message post. We currently send
the initial media button preferences inline, causing the callback
in MediaController.Listener.onMediaButtonPreferencesChanged to
arrive before the FutureCallback.onSuccess callback.
In the test controller app, which causes crashed when
connecting to existing sessions for example. We can make this
more robust by also posting the initial update of the media button
preferences.
PiperOrigin-RevId: 726923498
(cherry picked from commit d5df227b3ae4d87ec4876cc19ecca814c91c5fd7)
We currently set both actions depending on the playWhenReady state
and we require both actions when converting a platform session to
a Media3 session (if ACTION_PLAY_PAUSE isn't set anyway).
This causes problems in two situations:
- A controller using the platform ACTION_PAUSE/ACTION_PLAY to
determine which button to show in a UI. This needs to be aligned
to the existing Util.shouldShowPlayButton we already use when
setting the PlaybackStateCompat state.
- A session only setting either ACTION_PAUSE or ACTION_PLAY
depending on its state. We should check if the action triggered
by setPlayWhenReady(...) is possible and allow COMMAND_PLAY_PAUSE
accordingly.
PiperOrigin-RevId: 726916720
(cherry picked from commit 28bfb27fb59ceb0cd209ac1eebd803d31f78afa4)
When converting to platform states, STATE_ENDED is mapped to
STATE_STOPPED, but the reverse mapping always assumes STATE_STOPPED
means STATE_IDLE at the moment. We can use the same logic we already
apply for STATE_PAUSED to figure out if we are ended.
PiperOrigin-RevId: 726902064
(cherry picked from commit 982403a0ccab31de1f293fb0b8591e2132e11dd2)
Currently the notification disappears immediately when the player
enters an error or stopped state, but still has its media and
could resume on user request.
This can be fixed by only checking the existence of media and not
the state when deciding to show a notification.
PiperOrigin-RevId: 726901050
(cherry picked from commit f0da364d3fdd8574c8506f0682a7d2ecf8135ad8)
Added tests for APIs `getDrmInitData()`, `getPsshInfo()`, `getLogSessionId()` and `setLogSessionId(LogSessionId)`.
The Widevine encrypted sample was created from already existing `sample_fragmented.mp4` using `mp4encrypt`.
PiperOrigin-RevId: 726881977
(cherry picked from commit e9df85b48d5c8c0727146ace4528293e3f6ecfd5)
This means the volume is available in the internal player,
which is a preparation step to moving the audio focus
handling to the internal player too.
PiperOrigin-RevId: 726880098
(cherry picked from commit ef9b6d212e74c304730161434200244183ae23e6)
This avoids distributing the logic between multiple classes and
keeps ExoPlayerImpl simpler.
PiperOrigin-RevId: 726874038
(cherry picked from commit 1015ef8b565ed04e88a9c596798d294327d05536)
The creation can be moved to the playback thread (to guarantee it
happens in sync other initialization after playback start) and the
potentially blocking calls to the reporting methods can be moved
to the generic shared BackgroundExecutor (it can't use the playback
thread because it no longer exists when the session is ended after
the player is released).
PiperOrigin-RevId: 726872818
(cherry picked from commit d386e002d2b34817178d088f277ced3bf3943ef2)
The mute value usually changes in line with volume == 0.
Also update the test to provide better coverage of the
immediate and delayed state changes.
PiperOrigin-RevId: 726839927
Updating the list of supported codec in Mp4Muxer and
FragmenetdMp4Muxer is often missed when a new codec is added
in Boxes.java.
PiperOrigin-RevId: 726397337
Add a new ByteBufferAllocator interface, with a simple
LinearByteBufferAllocator implementation that supports basic memory
allocations and reuse.
Add an AnnexBToAvccConverter.process override that takes a custom allocator
PiperOrigin-RevId: 726380184
In all these cases I found at least one public method that takes or
returns a type from the dependency, or a type that inherits from a type
defined in the dependency.
PiperOrigin-RevId: 726130595
When possible, make it the caller's responsibility to release the
GlObjectsProvider. It's good practice that the class creating an object
also releases it. It avoids releasing the same object (here, the
GlObjectsProvider) multiple times, which was causing
DefaultVideoCompositorPixelTest to fail.
PiperOrigin-RevId: 725983417
This ensures that when the input sample rate handled by the encoder differs from the output of the AudioGraph, that output audio will not be broken.
PiperOrigin-RevId: 725610384
The change includes adding a `MetricsReporter` interface with a default implementation to allow testing the `EditingMetricsCollector`.
PiperOrigin-RevId: 725607330
The new asset loader is a wrapper around a provided `MediaProjection` and
`SurfaceAssetLoader`.
The test relies on automating the UI to get a `MediaProjection` instance, which
doesn't work reliably on all devices, so it's restricted to Pixel devices from
API 29 onwards.
For now only video is supported. The plan is to add support for audio playback
capture (also using `MediaProjection`) in a later change(s).
PiperOrigin-RevId: 725241962
In a image sequence, seek to after the image duration should render the final
image frame. But currently it hangs as ConstantRateTimestampIterator doesn't
output any timestamp in this case
PiperOrigin-RevId: 724295475
This test also changes the image seeking behavior to match ExoPlayer: now if
seeking to after the end of the image, the last frame of the image would still
be presented.
PiperOrigin-RevId: 724054371
In the case of replace stream media item transition, it is important that dynamic scheduling does not set the next work task later than the transition boundary.
#cherrypick
PiperOrigin-RevId: 723502204
AV1 input buffers contain multiple compressed pictures.
Enable skipping only the last showable frame, while leaving
any reference pictures to be decoded later, as part of
the next decoder input buffer.
Partial skipping of AV1 input buffer is only applied when:
* fewer than 8 OBUs are delayed
* there's likely to be enough capacity in the decoder input buffer
for the next frame
PiperOrigin-RevId: 723496060
Parsing AV1 bitstreams allows us to identify frames that are
not used as reference, and improve seeking or frame dropping
behavior.
The AV1 bitstream format is relatively quick to parse
PiperOrigin-RevId: 723462680
From the `sampleMimeType`, we can know whether the media item contains video data, image data, and audio data. This is done for input media items, and the output media item.
PiperOrigin-RevId: 723459732
- It's never used and handling multi-threading is costly.
- If the VideoCompositor and the VideoFrameProcessors use separate
threads and the same GlObjectsProvider, the GlObjectsProvider is
accessed from multiple threads. This class doesn't seem designed for
multi-threading.
PiperOrigin-RevId: 723448013
When a timeline change occurs, the `AdTagLoader` will post an adLoad timeout task if currently waiting for an ad to load. Once sdk calls `loadAd`, any pending timeout tasks are removed. If the timeout occurs, the ad group is canceled and content will resume.
If the SDK proceeded to resume content without calling `loadAd`, then any pending timeout tasks should be removed or else a future ad group may error due to a previous timeout task.
PiperOrigin-RevId: 723442852
Seeking will reset media periods following the current playing period. This includes resetting any current pre-warming media periods. Therefore while seeking, any current pre-warming should be disabled and reset.
#cherrypick
PiperOrigin-RevId: 723439145
When sample batching is disabled, copying of the ByteBuffer data
is not necessary as samples are written as they arrive.
Copying of the BufferInfo is necessary because the info is needed
for writing the moov atom.
The input ByteBuffer can be in little endian order, or have its
position set. AnnexBUtils now ensures big endian order before
inspecting bytes, and supports reading from a non-zero position.
This change reduces the amount of memory allocations by Mp4Muxer
in its default configuration
PiperOrigin-RevId: 723401822
Previously, the codec names for the input were collected from `Format.codecs` which return the RFC 6381 string not the codec name used. This was changed to retain the decoder name from `ProcessedInput` instead.
PiperOrigin-RevId: 723129667
This will allow the listeners who are interested in the `SeekMap` to get informed once the period has done the preparation.
PiperOrigin-RevId: 723027718
MediaCodecVideoRenderer is becoming unwieldy with the numerous constructors and optional settings. This refactors MediaCodecVideoRenderer to use a builder pattern for simplicity.
PiperOrigin-RevId: 723022129
It includes entering a custom text and setting the alpha scale. When the effect is applied, it shows the text in the center of the screen. A following change will include changing the color of the text.
PiperOrigin-RevId: 721828892
Also updated DefaultVideoFrameProcessor to create GlShaderPrograms with the working ColorInfo rather than the output ColorInfo.
PiperOrigin-RevId: 721748002
This means we need convert some of the assertions in
ClippingMediaPeriod to contrain the output value to clipped
range instead, because unseekable media will return zero
as a start and seek position in all cases.
PiperOrigin-RevId: 721463824
Most of the values for the output `MediaItemInfo` will be retained from the `ExportResult`, so it's now passed to `onExportSuccess` and `onExportError` directly. For now, the duration of the ouput is recorded for metrics, and more values will be added in the following CLs.
PiperOrigin-RevId: 721324689
This is necessary for prewarming. With prewarming, in a sequence of 2
videos, the second renderer is enabled before the first one is disabled,
and decode-only frames should be skipped before the second renderer is
started. The problem is that the second renderer will forward frames to
a BufferingVideoSink before it is started, which will delay the frame
handling and therefore not skip the frame before the renderer is
started.
PiperOrigin-RevId: 721032049
The exception occurred when an edit list started at a non-sync frame with no preceding sync frame. The fix searches forward for the next sync frame in such cases, preventing the out-of-bounds access.
Issue: androidx/media#2062
#cherrypick
PiperOrigin-RevId: 720642687
Add an option to GlMatrixTransformation to choose the OpenGL texture
minification filter.
When mipmaps are requested, mipmaps are generated with
`glGenerateMipmap()`.
PiperOrigin-RevId: 720629807
This avoids that these settings have to be resolved inline,
potentially blocking the main thread. They can be resolved at
the time of track selection on a background thread instead.
As a side effect, we can also remove the context parameter from
the Builder. Having the Context in the Builder is also a bad sign
in the first place because it implies the potentially blocking
calls can happen.
PiperOrigin-RevId: 720523139
The calls to Util.isTV and the interactions with the spatializer are
potentially blocking and were triggered from the constructor,
setAudioAttributes and release.
setAudioAttributes and release are both documented to be called by
the Player and should be triggered on the playback thread anyway.
The constructor initialization can be delayed until the spatializer
might be needed to avoid the blocking call.
The threading clean-up also allows to remove the lock from the
audioAttributes and the spatializer fields as they are now
accessed on the playback thread only.
PiperOrigin-RevId: 720488979
Before the change, `SequenceAssetLoader#onTrackAdded` was being called twice, for audio and video. `ExportResult.ProcessedInput` took one format, which was the latest to be written. The change leads to capturing both, the audio and video formats of the input, and prevents the issue of a format overwriting the other.
PiperOrigin-RevId: 720487697
playback_sequencesOfVideos_effectsReceiveCorrectTimestamps is failing
for prewarming. The following is happening:
- For prewarming, there are 2 alternating video renderers per sequence.
- When the first MediaItem ends (for both sequences), signalEndOfInput
is not called on the InputVideoSink (which is expected).
- The DefaultVideoCompositor doesn't receive the end-of-input-source
signal (which is also expected).
- As a result, the DefaultVideoCompositor never outputs the last frame
because it waits for more input frames to be fed.
- The VideoGraph thus doesn't output the last frame either, and the
first video renderer never ends.
- This causes playback to get stuck.
This is similar to the problem of supporting multiple video sequences
with images and videos in CompositionPlayer.
PiperOrigin-RevId: 720106413
Usage:
* call queueInputBuffer() with initialization data or sample data in decode
order - updates the parser state
* call sampleLimitAfterSkippingNonReferenceFrame to identify if the sample
contains a frame without dependencies
PiperOrigin-RevId: 720098835
Previously, the input media item's duration was collected from `ProcessedInput.durationUs`. However, this value turned out to be the duration of the media item after clipping. Getting the duration of the input media item before clipping is tricky, so it will be dropped from Editing Metrics V1.
PiperOrigin-RevId: 719254077
When reading quickly this suggests something 'real' was null (similar to
a `NullPointerException`), but it's actually just the message from the
superclass.
Seen in stack trace in Issue: androidx/media#2074:
```
Caused by: androidx.media3.common.ParserException: null {contentIsMalformed=true, dataType=1}
```
PiperOrigin-RevId: 719240235
The fix is to update `AudioGraphInputAudioSink.lastHandledPositionUs` when a buffer is handled, and end the `AudioGraphInputAudioSink` as the final audio sink plays out further than this position.
PiperOrigin-RevId: 718901825
The file in Issue: androidx/media#2052 contains a cue with the following timecode:
```
0:00:00:00,0:00:00:00
```
The content of this cue seems to be some 'converted by' metadata, i.e.
it's basically a comment and clearly not intended to be shown on
screen (since it has zero duration).
There is some fiddly logic later in `SsaParser` to support overlapping
cues with the old `Subtitle` structure [1], and this logic gets tripped
up by the start and end time being equal, which results in a
**single**, empty `List<Cue>` being added - which trips up another
assumption that every SSA cue line results in at least two `List<Cue>`
entries (one containing the cue text, and another containing an empty
list to signal the end of the cues).
This fiddly logic is no longer required, because overlapping
`CuesWithTiming` objects can now be merged in `TextRenderer`, so there
is a possible future simplification to `SsaParser` which removes a lot
of this complexity.
[1] Added in <unknown commit>
PiperOrigin-RevId: 718380386
This requires some additional state handling to update the full
state atomically and guess placeholder states while updates are
in progress, using the newly added BackgroundThreadStateHander.
Some tests also needed to be adjusted to account for the fact
that the actual audio system change doesn't happen inline
anymore.
PiperOrigin-RevId: 716702141
This is pre work required to remove `Muxer.java` interface
from the muxer module.
`Mp4Muxer` and `FragmentedMp4Muxer` will no longer implement
the `Muxer` interface.
PiperOrigin-RevId: 716669531
This is a common pattern in media3 libraries where tasks are handled on a
background thread, but the calling thread sees an immediate state update
with a best-guess placeholder. This makes the integration for the caller
very easy as the API surface appears to be synchronous.
This util is a helper class to handle this logic and test it separately.
PiperOrigin-RevId: 716233966
The `DataSpace` contains the Color Standard, Range, and Transfer. These values were mapped as follows:
* Standard: From `@C.ColorSpace` to `@DataSpace.DataSpaceStandard`
* Range: From `@C.ColorRange` to `@DataSpace.DataSpaceRange`
* Transfer: From `@C.ColorTransfer` to `@DataSpace.DataSpaceTransfer`
PiperOrigin-RevId: 716157142
If a format is passed to `ExportResult.ProcessedInput`, the `containerMimeType` and `sampleMimeType` are extracted from the Format and passed inside the `MediaItemInfo` object.
PiperOrigin-RevId: 715840400
To receive multiple schemes of metadata emitted by a stream, multiple
`MetadataRenderer` instances need to be used. This change makes
`DefaultRenderersFactory` add two metadata renderers by default.
PiperOrigin-RevId: 715790821
This is aligned with the documentation of `MediaCodec` which says the
timestamp of a buffer with `BUFFER_FLAG_END_OF_STREAM` should be
ignored:
https://developer.android.com/reference/android/media/MediaCodec#end-of-stream-handling
Add a test that exercises this by clipping off the end of a sample with
CEA-608 captions, because this creates an EOS-flagged buffer with a
non-EOS timestamp.
Also add a straightforward playback test for the
`fragmented_captions.mp4` sample.
PiperOrigin-RevId: 715716036
This is to prevent facing errors in apps using Transformer. It will be enabled again once the project is done and comprehensive tests are added.
PiperOrigin-RevId: 715435613
These tests were earlier using `MediaExtractor`, hence
they were in androidTest. Now `MediaExtractor` has been
replaced with `media3 MediaExtractorCompat` so these
test can be robolectric.
PiperOrigin-RevId: 715424470
Some checks in SingleInputVideoGraph were causing CompositionPlayer to
throw for a single media item sequence when repeat mode was enabled. The
reason was that, in this case, no new input stream is registered to the
VideoFrameProcessor.
PiperOrigin-RevId: 715409509
Currently, if a seek occurs when the audio sink was providing back pressure, the audio renderers will provide a durationToProgress based on the last non-writable sample prior to the seek.
Solution is to reset the value used for the `getDurationToProgress` when onPositionReset occurs.
This CL also makes sure to reset the value whenever the audiosink is flushed or reset.
PiperOrigin-RevId: 715361834
In `AudioTrackPositionTracker.hasPendingData()` method, `sourceEnded=false` is always passed. Thus, if the `AudioTimestampPoller` hasn't entered the `STATE_TIMESTAMP_ADVANCING` before the stream ends, then the current position can be inaccurately calculated in the absence of a correct `sourceEnded` value, and `AudioTrackPositionTracker.hasPendingData` will return a wrong result.
We used to avoid calling `getPlayheadPosition()` too often, which involves expensive binder request. However, here we need to adjust a bit back to compare the `writtenFrames` directly with `getPlayheadPosition()` after handling the end of stream, when not being able to declare `sourceEnded=true` can have significant difference.
PiperOrigin-RevId: 715358137
This renaming helps prevent the consumer from including `PlayerSurface` in a Compose tree based on `state.showSurface`. This field intuitively felt like the default would be not to show the surface (correct), but had an unintended consequence of not initialising `AndroidExternal(Embedded)Surface` (since the PlayerSurface Composable would be omitted).
To avoid this confusion, the `PresentationState` should communicate to the consumer when the Surface is not ready and hence should be covered with some overlay (shutter) to prevent poor UX from observing Surface resizing/freezing/flickering.
PiperOrigin-RevId: 714951607
Deprecate BundledChunkExtractor.experimentalParseWithinGopSampleDependencies
in favour of
ChunkExtractor.experimentalSetCodecsToParseWithinGopSampleDependencies
which takes a VideoCodecFlags IntDef flags that represent a set of codecs.
Add a DASH test using the new API with an H.265 video.
PiperOrigin-RevId: 714901602
In this mode there isn't an explicit signal from upstream that an input frame
is going to arrive at the `SurfaceTexture`. This means that when end-of-stream
is signaled we don't know when there won't be any more input frames.
Reject new frames in `onFrameAvailable` after input EOS is handled for the case
of reregistering frames automatically. This avoids those frames entering the
pipeline and causing us to unexpectedly handle frames after EOS.
PiperOrigin-RevId: 714858039
Earlier muxer wrote a different entry for every chunk but as
per the spec (ISO 14496-12) exact same chunks can be combined
and only the first chunk number can be written.
PiperOrigin-RevId: 714154531
It captures the information needed for the UI logic related to rendering of the video track (and later images) to the surface.
The video size will be correct only after the Player decoded the video onto the surface and can't be reliably extracted from MediaItem's metadata. The information about the video's true aspect ratio helps inform the UI elements (such as PlayerSurface Composable) how to customize the Modifiers.
Use this state in demo-compose to show off functionality of changing `PlayerSurface`'s aspectRatio
PiperOrigin-RevId: 714104260
Added the creation of `MediaItemInfo` for each MediaItem and passed the duration of the MediaItem to it. This is done for export operations that complete with success or with error.
PiperOrigin-RevId: 714056270
In some cases encoders include a sample rate in their AudioCapabilities but do not support encoding at that sample rate. This breaks the assumption used to write these tests, so disable them for now until the fallback logic is updated to handle this limitation.
PiperOrigin-RevId: 714055556
Add a new flag to FragmentedMp4Extractor
FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES_H265
Read two bytes from H.265 videos to determine NAL unit type and
temporal layer id.
PiperOrigin-RevId: 714046987
When the current MediaMetadata is automatically derived from the
MediaItem and Tracks, the result may change when state.buildUpon()
is used and new input data is provided (e.g. new current index).
To avoid reusing the previously derived MediaMetadata, we need to
reset it to null and re-evaluate it on every call to build()
Issue: androidx/media#1940
PiperOrigin-RevId: 714021424
Added reporting 2 values from Transformer:
- `exporterName`: name of the package calling for export. Example: "androidx.media3.transformer".
- `muxerName`: name of the muxer used for the export operation. Example: "androidx.media3.muxer".
PiperOrigin-RevId: 714000672
The initial discontinuity is currently only reported if
the period is prepared at the clip start position. However,
we need the discontinuity whenever we prepare at a non-zero
position (unless we know all samples are sync samples).
PiperOrigin-RevId: 713994155
ExoPlayer assumed 4-bytes for length in two places (by assuming the
length is the same as the 4-byte NAL start code):
1. In `AvcConfig` we transform length-delimited to start-delimited
before writing into `initializationData`, and then skip
'nal unit length field' bytes when parsing from `initializationData`
(when we should skip 'start code length' bytes instead).
2. In `Mp4Extractor.readSample` we modify the local variable
`sampleSize` to fix the difference between length field length and
start code length, but **only on the first attempt to read a
sample**. If we are resuming in the middle of reading a sample (after
a recoverable I/O error), this fix for `sampleSize` is not done,
which means we end up missing the last 2-3 bytes of the sample when
the NAL length is 1-2 bytes.
* This is fixed by moving the `sampleSize` 'fixing' code to outside
the `if (sampleCurrentNalBytesRemaining == 0)` block.
* `FragmentedMp4Extractor` has very similar code, but uses a
field for `sampleSize`, rather than a local, so doesn't look
vulnerable to the same problem (though I haven't totally
tested this).
This change adds a test file with 2-byte NAL lengths, generated by
hacking the media3 muxer to emit 2-byte NAL lengths and transforming
`sample.mp4` using the transformer demo app.
PiperOrigin-RevId: 713709203
We only care about the duration and don't want to force an initial
discontinuity.
The problem is not currently visible due to a bug in
ClippingMediaPeriod that ignores all dicontinuities if they don't
happen at the clip start position.
PiperOrigin-RevId: 713686333
The previous FragmentedMp4 captions test asset doesn't have captions.
Fix a bug where captions before extractor seek were output after.
PiperOrigin-RevId: 713665817
When CompositionPlayer added repeat modes in d0afb96c40, it
changed the logic in SimpleBasePlayer to workaround the specific
scenario in CompositionPlayer that didn't seem to work correctly.
The workaround is not really generically applicable though. The
source of the original problem was that the position values of
all state objects were connected to the "live" source of the
current player so that the repetition case couldn't be detected
(the position before and after the seek looked the same). The
solution is to use the newly added LivePositionSuppliers and
disconnect them before seeking.
PiperOrigin-RevId: 713659638
In some cases the position is supplied from a "live" source
that keeps changing its value at repeated calls. This typically
happens when forwarding to another backend with unpredictable
position values. The problem is that as soon as the backend
system has a position discontinuity, any previously created
PositionSupplier now returns a position that no longer makes
sense in the context of the State object it belongs to.
ForwardingSimpleBasePlayer already works around this issue by
having a util class to disconnect these live sources. This
change moves the same util to SimpleBasePlayer itself so it
can be reused by other implementations.
PiperOrigin-RevId: 713658046
If `experimentalSetEnableMediaCodecVideoRendererPrewarming` is set with `true`, `DefaultRenderersFactory` will provide `ExoPlayer` with a secondary `MediaCodecVideoRenderer` for use in pre-warming through its `createSecondaryRenderer` and `buildSecondaryVideoRenderer` implementations. `ExoPlayer` will then pre-process video of subsequent media items to reduce media item transition latency.
PiperOrigin-RevId: 713605911
The audio decoder is sometimes failing with error "previous call to
queue exceeded timeout - Codec reported err 0x80000000, actionCode 0,
while in state 6/STARTED". This is probably because the emulator is too
slow.
PiperOrigin-RevId: 713564117
At the point of playing period transition pre-warming has completed and the renderers should receive necessary resources for playback. This CL adds the `Renderer.MessageType` `MSG_TRANSFER_RESOURCES` to direct a renderer to transfer relevant resources to another renderer.
PiperOrigin-RevId: 713372754
We currently force discontinuities for all clipped content periods
that don't start from zero. This shouldn't be done for server-side
ad insertion streams where we are guaranteed to get a continuous
underlying stream.
To enable the right decision, we need to add a flag to
MediaPeriodInfo for isPrecededByTransitionFromSameStream, which
mirrors the existing isFollowedByTransitionToSameStream.
The problem is currently not visible due to a bug in
ClippingMediaPeriod that automatically ignores most discontinuities
that don't match the start of the clip.
PiperOrigin-RevId: 713315398
If an error occurred in the player before the test was calling one of
the waitUntilSomething() methods, a timeout exception was thrown instead
of the actual error.
PiperOrigin-RevId: 713292292
DASH periods can have a duration that is less than the end of the
last chunk in the period. In these cases, the sample data needs to
be clipped to the declared period duration. This already happens
IF the period duration is known at the point where we start loading
the media chunk. However, if the duration becomes known later or is
reduced (e.g. in a live stream), the existing media chunks are not
clipped. This causes unclean transitions across periods where the
player tries to transition to the next period, but renderers struggle
to output all the remaining surplus samples that should have been
clipped.
This can be fixed by asking ChunkSampleStream to discard surplus
samples that were loaded beyond a clipped duration when evaluating
the sample queue between chunk loads.
Issue: androidx/media#1698
PiperOrigin-RevId: 713288221
If a playback exception was thrown before or during awaiting the
frameCountBeforeBlockLatch, a TimeoutException was thrown instead of the
playback exception, hiding the actual cause of the failing test.
PiperOrigin-RevId: 713279627
This method is already quite complex and I will need to add more
complexity, so split it into multiple smaller methods.
This CL is a refactoring. There are no functional changes.
PiperOrigin-RevId: 713266816
The new `currentPlayer` was only used to check the available command. It should also be used for setting and clearing the Surface.
The PlayerSurface was still behaving correctly, perhaps due to the lambda being reevaluated with the new player (since `currentPlayer` is of type MutableState). Which meant it was also using the latest `player` that `PlayerSurface` was recomposed with (in the argument), rather than holding onto the original object.
PiperOrigin-RevId: 713264041
Add a new Mp4Extractor.FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES_H265
Read two bytes from H.265 videos to determine NAL unit type and
temporal layer id.
PiperOrigin-RevId: 713248154
The number of temporal sub-layers is required for
H.265 non-reference frame identification as
only frames from the highest temporal sub-layer can be
discarded.
PiperOrigin-RevId: 713247354
The number of temporal sub-layers is required for
H.265 non-reference frame identification as
only frames from the highest temporal sub-layer can be
discarded.
PiperOrigin-RevId: 713242894
Expose NalUnitUtil.H265SpsData.maxSubLayersMinus1
Required for H.265 non-reference frame identification as
only frames from the highest temporal sub-layer can be
discarded.
PiperOrigin-RevId: 713232825
The change includes setting the final progress percentage when the export completes with error or is cancelled. The value for the progress is collected by calling `Transformer.getProgress()` before `transformerInternal` is set to null.
PiperOrigin-RevId: 713227568
Added the first overlay effect to the Effect demo. It includes an emitter of confetti that drops from the center of the frame.
PiperOrigin-RevId: 712940163
Reflects that FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES only parses
H.264 bitstream, and that H.265 parsing will be controlled with
another flag.
PiperOrigin-RevId: 712921990
This will be useful for recording use cases, including screen recording with
audio queued via `RawAssetLoader`, where the duration is unknown.
PiperOrigin-RevId: 712895577
This change simplifies SpeedChangingAudioProcessor by removing unneeded
heuristics and synchronization added as workarounds to estimate input
and output frame counts.
The synchronization between the video processing and audio processing
threads cannot be completely removed yet because the static methods
depend on the input sample rate for the calculations. However, once
`SpeedChangingAudioProcessor` has been configured, then
`#getSpeedAdjustedTimeAsync()` should invoke the callback immediately.
PiperOrigin-RevId: 712893246
It captures some information needed for the UI logic related to rendering of the video track (and later images) to the surface.
Supporting `EVENT_RENDERED_FIRST_FRAME` helps improve the UX by covering the surface with an overlay (scrim/shutter) until the first frame is ready. This helps avoid sudden flickering during MediaItem transitions.
PiperOrigin-RevId: 712889568
We previously parsed an arbitrary number of decimal places, but assumed
the value was in milliseconds, which doesn't make sense if there is
greater or fewer than 3. This change restricts the parsing to match
exactly 3, meaning the millisecond assumption is always true.
The WebVTT spec requires there to be exactly 3 decimal places:
https://www.w3.org/TR/webvtt1/#webvtt-timestamp
The SubRip spec is less clearly defined, but the Wikipedia article
defines it as having exactly 3 decimal places
(https://en.wikipedia.org/wiki/SubRip#Format) and ExoPlayer has always
assumed 3 decimal places (anything else is already handled incorrectly),
so this change just ensures we don't show subtitles at the wrong time.
Issue: androidx/media#1997
PiperOrigin-RevId: 712885023
If the caller is another asset loader (or another asset loader factory) that is
delegating to a `SurfaceAssetLoader`, it may want to call methods on the
`SurfaceAssetLoader`. Return the concrete type so that a cast isn't necessary
at the call site.
PiperOrigin-RevId: 712881130
This avoids requesting storage permissions for URLs that don't require it.
Also tidy clean-up into `cleanUpExport`, rename `releasePlayer` to
`releasePlayers` as there are players for both input and output, and reduce
live range of `uri` variable.
PiperOrigin-RevId: 712857115
Removed the check for `released` flag to be able to pass the actual progress when the export completes.
Also, removed resetting the `progressState` and `progressValue` to be able to get the actual progress. This block is also not necessary to have at this point.
PiperOrigin-RevId: 712851526
After this change, if the sample rate supported by the encoder differs from the requested sample rate and enableFallback is true, the AudioSampleExporter will convert audio to a sample rate supported by the encoder. This fixes a bug where the audio track is distorted when an unsupported sample rate is requested.
PiperOrigin-RevId: 712822358
This lets us provide a append-only output stream with overridden write() methods - unlocking use cases where we process the muxed data in a streaming fashion, as it's generated by the fragmented muxer.
PiperOrigin-RevId: 712581859
This will ensure that the new `ui-compose` module gets published on Maven
The fix is not necessary for `demo-effect` and `demo-compose` because they are not publishable
PiperOrigin-RevId: 712555702
Take care of releasing the player and re-initialising when returning to the app to prevent memory leaks.
Instead of overriding onStart, onPause, onResume, onStop - use Lifecycle*Effects for a more native compose cleanup. Requires a higher version of the lifecycle library.
PiperOrigin-RevId: 712542884
The latest version of `androidx.compose.foundation:foundation` fixed an issue where `AndroidEmbeddedExternalSurface` would not reset properly. This in turn prevented PlayerSurface Composable with type `SURFACE_TYPE_TEXTURE_VIEW` from being redrawn after returning to a stopped activity.
PiperOrigin-RevId: 712501647
Added reporting 2 values from Transformer:
- elapsed time since creation of the `editingSession` in milliseconds.
- the `ErrorCode` for export errors. The error codes were mapped from `@ExportException.ErrorCode` int to `@EditingEndedEvent.ErrorCode`.
PiperOrigin-RevId: 712472849
For the [0.5; 1) speed range, the combination of having a "slow down"
speed (i.e. more output frames than input frames), and Sonic potentially
needing to copy more input frames that are available in the input buffer
can lead to an unexpected underflow.
Specifically, the underflow happens in Sonic#queueEndOfStream() when the
following conditions are met (skipping some minor ones):
1. `inputFrameCount < remainingInputToCopyFrameCount`
2. `0.5f <= speed < 1`.
3. `outputFrameCount <
(inputFrameCount / remainingInputToCopyFrameCount) / 2`.
This underflow caused `SonicAudioProcessor#isEnded()` to return a false
negative (because `getOutputSize() != 0`), which would stall the
`DefaultAudioSink` waiting for processing to end after EOS.
In practical terms, the underflow is relatively easy to reproduce if we
consume all of Sonic's output and then immediately queue EOS without
queueing any more input in between. This should cause both
`inputFrameCount` and `outputFrameCount` to drop to 0.
PiperOrigin-RevId: 711773565
Added a new `EditingMediaMetrics` class that interacts with the platform's `MediaMetricsManager` through an `EditingSession` created when export starts.
Currently, only the `finalState` of the export event is reported to the `EditingSession`. Future changes will collect additional metrics based on the export operation's output.
PiperOrigin-RevId: 711721801
Some videos include zero length NAL units in the
length-delimited MP4 samples.
Empty NAL units are not spec-compliant (see ISO/IEC 14496-15 section 4.3.3.3),
but other players are able to play these videos (with warnings or errors).
With this change, we check track.sampleTable.sizes[sampleIndex] before
reading a byte from the NAL unit itself.
PiperOrigin-RevId: 711720621
The static method can estimate the number of input frames needed to get
a given number of output frames with a given Sonic configuration.
This CL is prework to remove the dependency of
`SpeedChangingAudioProcessor#getMediaDurationUs()` on non-static output
based heuristics and simplify `SpeedChangingAudioProcessor`.
PiperOrigin-RevId: 711446999
On many devices (for example pixel 7) a dolby vision file can be
decoded (either using dolby vision decoder or H265 decoder)
but they can't be re-encoded to dolby vision.
Allow test to encode to H265.
The test now passes on pixel 7. It was getting skipped earlier.
PiperOrigin-RevId: 711383794
A device (for example pixel 7) might support HDR encoding
but with H265 sample mime type but the existing condition made
assumption false on such devices.
The test still does not pass on pixel 7 because the format
matching condition is incorrect. It will be fixed in a separate CL.
PiperOrigin-RevId: 711368798
Replaced an existing APV file as bitstream syntax has now changed and
previous clip is not a valid bitstream anymore.
This clip was provided by the openAPV team and is under BSD-3 license.
PiperOrigin-RevId: 711318578
After this change if a sample rate is requested that is not supported by the available encoders and enableFallback is true, DefaultEncoderFactory will fall back to the encoder with the closest matching sample rate.
In the case when an encoding profile is included in requestedAudioEncoderSettings, an encoder matching that profile will continue to be preferenced.
PiperOrigin-RevId: 708295869
Added a new `usePlatformDiagnostics` in Transformer. This parameter enables/disables forwarding editing events and performance data to the platform.
This is pre-work for metrics support in Transformer. In the following CLs, metrics collection and forwarding will be implemented.
PiperOrigin-RevId: 707930368
- Added a condition to ensure `requiredIntervalUs > 0` in `DashMediaSource`.
- Resolves an issue where negative `requiredIntervalUs` triggered an infinite loop in `onPlaylistUpdateRequested()`, leading to application/stream freezes.
This fix restores smooth playback for multi-period DASH streams.
AMR-NB and AMR-WB are inherently mono, so channel count is set to 1. Sample rate is also hard-coded to adhere to codec standards.
Also removed unused parameter `hasAdditionalViews` in `StriData`.
#cherrypick
PiperOrigin-RevId: 707606245
The dump file for VP9 mp4 clips varied across SDK versions due to inconsistent CSDs from the platform extractor. By replacing the platform extractor with `MediaExtractorCompat`, the Media3 extractor will provide consistent CSDs across all SDK versions.
PiperOrigin-RevId: 707509473
This enables `AdsMediaSource` to be used with a live media
source that has a growing `AdPlaybackState` to which ad groups
can be appended.
Before this change, `AdsMediaSource` asserted that the number
of ad groups was kept the same, else an exception was thrown.
After this change, the assertion checks the validity of the
update and throws in case the update isn't considered valid.
An update is valid if ad groups are appended to the existing
`AdPlaybackState` or ads are appended to existing ad groups.
Further the `adGroupIndex` and `timeUs`of an existing ad
group can not be changed and once a media item is set for a
given ad, that media item can't be changed either.
PiperOrigin-RevId: 707244455
It seems that changes via Robolectric's `ShadowBuild.setManufacturer()`
and similar methods don't propagate correctly (or quickly?) to these
aliases.
This change resolves a failure caused by different test ordering in
`AudioCapabilitiesTest` in order to unblock the 1.6.0-alpha01 release.
A follow-up change will migrate other usages from `Util.XXX` to
`Build.XXX`.
PiperOrigin-RevId: 707125446
Added a contrast effect and the connection needed to apply the video effects to ExoPlayer.
The effect can be applied to the video by checking the "Contrast" card, and use the slider to change the contrast value. The effects are applied when `Apply effects` button is clicked.
PiperOrigin-RevId: 707092041
Both classes provide utilities widely used by apps that are not
yet available in Media3. This change imports the existing logic as
it is with style adjustments to the Media3 codebase.
PiperOrigin-RevId: 707067512
There are reproducible issues with codec timeouts when using
this API, so we disable it entirely until we know more about
potential fixes and where they are available.
Issue: androidx/media#1641
#cherrypick
PiperOrigin-RevId: 707025950
There are reproducible issues with codec timeouts when using
this API, so we disable it entirely until we know more about
potential fixes and where they are available.
Issue: androidx/media#1641
PiperOrigin-RevId: 707025950
(cherry picked from commit 71f82df57f53c69fe34417bbde64847049e27894)
`MediaCodecVideoRenderer` will skip frames if a surface has not been set and video frame presentation time is early but too close to the current playback position. In the case that the `VideoFrameReleaseControl` says to `FRAME_RELEASE_TRY_AGAIN_LATER`, these frames should not be skipped.
PiperOrigin-RevId: 706711734
`Parcelable` is not safe for IPCs between binaries with potentially
different class definitions (e.g. two apps built from different versions
of media3).
If we get a use case to bundle metadata, then the `Metadata` and
`Metadata.Entry` classes needs to provide a `toBundle()` method.
PiperOrigin-RevId: 706678892
Metadata does not provide a `toBundle` method. It implements
`Parcelable` which is not safe for IPCs between binaries with
potentially different class definitions (e.g. two apps built from
different versions of media3).
If we get a use case to bundle metadata as well, then the `Metadata`
class needs to provide a `toBundle()` method.
PiperOrigin-RevId: 705920231
This change adds a new stable overload of
`SessionToken.createSessionToken` which takes the platform `Token` type
(instead of `Parcelable`). It also stabilises
`MediaController.getCustomLayout` & the corresponding listener.
PiperOrigin-RevId: 705917161
Custom actions are more naturally associated with a user intent
than commands (that are meant to be used for automated inter-app
communication without user interaction).
PiperOrigin-RevId: 705797057
Custom actions are more naturally associated with a user intent
than commands (that are meant to be used for automated inter-app
communication without user interaction).
PiperOrigin-RevId: 705797057
(cherry picked from commit 3bce3af1a39540bd41823b2eaa7e642a668ed34c)
Reads HLS interstitials information from the playlist and
populates the `AdPlaybackState` accordingly to play the ads.
An app can register a `Listener` to be informed about ad
related events.
Only VOD streams are supported and X-ASSET-LIST attibutes
are ignored with this change.
PiperOrigin-RevId: 705604201
When `PlayerSurface` composable gets a new `Player` object, it should initialise a new Android(Embedded)External Surface with it. However, the lambdas used for that are remembered with the reference to the old Player, even if it has been null'd and released properly.
Android(Embedded)ExternalSurface is an interop - `AndroidView` wrapping `SurfaceView` and `TextureView` under the hood. It uses the `onInit` lambda in its factory to create the View and reuses it on later recompositions, making it a longer-lived object than our Player.
`RememberUpdatedState` acts makes a mutable State out of the Player and always gets its latest value. One can think of it as creating a reference to the Player object and telling the lambdas to always resolve that reference in the moment, rather than hold onto the Player than was passed-by-value.
This change is a precursor to a better lifecycle management of Player and Surface in demo-compose.
PiperOrigin-RevId: 705529626
This test was testing a scenario that never happens in production.
Indeed, in this test, a frame was registered to the
ExternalTextureManager but never rendered on the decoder ouput surface.
This never happens in production because both actions are normally
performed in
PlaybackVideoGraphWrapper.InputVideoSink.handleInputFrame().
This test was also failing on API 31 emulator. As the frame was never
rendered, the timeout to release all registered frames in
ExternalTextureManager was always exceeded. This sometimes caused the
decoder to fail on this emulator because there was no interaction with
the decoder for a long time.
PiperOrigin-RevId: 705490910
Moved the `getObjectType` method from `CmcdData.Factory` to `CmcdData` and updated the logic to derive the object type directly within `CmcdData`. This change eliminates the need for chunk source classes to set this value explicitly.
PiperOrigin-RevId: 705457755
The `toBundle()` method is implemented incorrectly as it uses
`parcelable` implementation to bundle `Format.metadata`.
The `parcelable` is not compatible and is likely to cause crashes if
a new field is added or removed.
Moreover, the `fromBundle` method is likely unused as in session
module the exception is [unbundled](df887a9422/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java (L1021)) as `PlaybackException`.
This is a non breaking change as all the calls to `toBundle()` and
`fromBundle` will now go to the parent class `PlaybackException`.
If this specific bundling is required in future then `Format.Metadata`
and all the `Metadata.Entry` classes need to provide `toBundle()`
and `fromBundle()` method.
PiperOrigin-RevId: 705167002
Currently as there is no formal support for MV-HEVC within Android framework, the profile is not correctly specified by the underlying codec; just assume the profile obtained from the MV-HEVC sample is supported.
PiperOrigin-RevId: 705164738
Currently as there is no formal support for MV-HEVC within Android framework, the profile is not correctly specified by the underlying codec; just assume the profile obtained from the MV-HEVC sample is supported.
PiperOrigin-RevId: 705164738
(cherry picked from commit 3936c27b6d0fd5e5795beab029c0216613e3f0ba)
- Moved static fields for object type, stream type, etc. from `CmcdData.Factory` to `CmcdData`.
- Removed redundant `CmcdData` prefix from `@ObjectType` and `@StreamingFormat` annotations.
#cleanup
PiperOrigin-RevId: 705159876
Before this change, the value of the `dwLength` in the stream header was
interpreted as the number of chunks in the file. Seeking and timestamp
calculation use the media duration and total chunk count. However, in some
files the `dwLength` field appears not to store the number of chunks. For
example, there are CBR MP3 and AC3 files where this field seems to store the
total number of bytes of compressed media instead. That caused seeking and
timestamp calculation to give much smaller values than expected (because the
`dwLength` is very large), which broke seeking.
Work around this using the `idx1` index header if present. We only support
audio formats where every audio sample is a sync sample in AVI, and all chunks
should therefore be listed in this index. Based on testing on many sample AVI
files this gives a reliable total chunk count and fixes seeking.
The test media file is a transcoded version of Big Buck Bunny but manually
edited to overwrite the length, rate and sample size header files to simulate
the error case.
PiperOrigin-RevId: 705103651
Playback was never ending in the case where the video graph rendered
the last frame to the output surface before the end-of-current-input
signal was received. This CL handles this specific case.
PiperOrigin-RevId: 705086366
`AudioTrackPositionTracker.pause` "re-arms" the event, to ensure it
fires again when playback resumes. However the `AudioTrack` position
advances by about 100ms **after** `AudioTrack.pause()`, which
consistently causes the event to fire immediately after pausing (and
then **not** after a subsequent resumption).
This change checks whether the `AudioTrack` is paused before firing
the event, to avoid this spurious trigger.
PiperOrigin-RevId: 704759929
The legacy custom layout doesn't support disabled buttons or buttons
with non-custom actions. These are currently filtered out, but in
inconsistent ways:
- MediaControllerImplBase doesn't filter at all.
- DefaultNotificationProvider filters before converting
mediaButtonPreferences, PlayerWrapper filters after the conversion.
- PlayerWrapper doesn't disable buttons that are unavailable.
To ensure it's consistent, we can add these checks to the existing util
method in CommandButton and also make sure PlayerWrapper disables
unavailable buttons before triggering the util method.
This also means we can simplify some of the tests that rely on the
mediaButtonPreference to customLayout conversion in MediaController.
This change also includes two bug fixes in PlayerWrapper that
became evident in the tests: The extras need to be copied to
avoid modifying a Bundle instance that be used elsewhere and
we need to update the custom layout and potentially the session
extras when the available commands change, as they depend on them.
PiperOrigin-RevId: 704678404
Added functionality to `Choose preset input` button. The picker allows the user to select a preset input from a list of loaded preset playlists. The selected preset input is then used to populate the ExoPlayer with the corresponding media items.
PiperOrigin-RevId: 704626144
`RenderersFactory#createSecondaryRenderer` can be implemented to provide secondary renderers for pre-warming. These renderers must match their primaries in terms of reported track type support and `RendererCapabilities`.
If a secondary renderer is provided, ExoPlayer will enable it for a subsequent media item as soon as its `MediaPeriod` is prepared. This will cause the renderer to start decoding and processing content so that it is ready to play as soon as playback transitions to that media item.
PiperOrigin-RevId: 704326302
AAC is the only format where the codec data buffer is actually used.
Invalid or obscure versions of the relevant syntax can break extraction when we
try to read the codec data, so it's better to read it only when it's required.
PiperOrigin-RevId: 704308925
It's expected that the subtitle load errors are emitted as a non-fatal
error, but it's not defined exactly when they will be emitted. By
consistently ignoring these every time we 'advance' the player, this
de-flakes the test (currently it fails when `untilFullyBuffered()`
triggers a non-fatal error).
PiperOrigin-RevId: 704219317
This is inspired from TestExoPlayerBuilder.
Adding this class has a few advantages:
- It makes testing easier for apps by configuring Transformer for unit
tests (for example, by setting the clock).
- It removes the Transformer setters that apps should not use for unit
testing (for example, the video MIME type should not be set because
it would cause Transformer to transcode.
- It allows us to add additional setters in the future, for example to
build a Transformer that always fails.
PiperOrigin-RevId: 704181927
Add FrameExtraction.setMediaItem() method
Prefer non-vendor software codecs by default because
vendor codecs sometimes fail when we attempt reuse.
PiperOrigin-RevId: 703486235
The test complements the existing E2E test for HLS in `HlsPlaybackTest` by verifying similar functionality for DASH in `DashPlaybackTest`.
PiperOrigin-RevId: 703454388
After removing `Transformer.Builder.setFlattenForSlowMotion()`, there is no need to keep `flattenForSlowMotion` in Transformer since it's now set in `EditedMediaItem`.
The change also includes making `audioProcessors` and `videoEffects` attributes final.
PiperOrigin-RevId: 703076023
The JSON file contains a list of playlists, each with a name and a list of media items. The EffectActivity loads the JSON file and creates a list of PlaylistHolder objects, which contain the playlist name and the list of media items.
PiperOrigin-RevId: 703069411
`equals`, `hashCode`, and `getPeriodByUid` are correctly implemented on
`Timeline`. Overriding these in a way that maintains correctness is
fiddly, so this CL prevents that for the 'simple' case of subclasses of
`ForwardingTimeline`. Implementations of `Timeline` that need to
override these methods for performance should extend `Timeline` or
`AbstractConcatenatedTimeline` instead of `ForwardingTimeline`.
PiperOrigin-RevId: 703035721
* Select an encoder that supports HDR editing.
* Set KEY_PROFILE to an HDR10 option
* Use DecodeOneFrameUtil test util to return the MediaCodec format,
which includes HDR_STATIC_INFO
PiperOrigin-RevId: 702752639
The method previously discarded the cue that was active at `timeUs`,
meaning it had started before but had not ended by `timeUs`.
Issue: androidx/media#1939
#cherrypick
PiperOrigin-RevId: 702707611
The method previously discarded the cue that was active at `timeUs`,
meaning it had started before but had not ended by `timeUs`.
Issue: androidx/media#1939
PiperOrigin-RevId: 702707611
(cherry picked from commit e927d7b986229a89a43d749a0b51cb9d53722d26)
With this CL, PlaybackVideoGraphWrapper doesn't call the
VideoFrameRenderControl directly anymore (which is one of the goals of
DefaultVideoSink).
PiperOrigin-RevId: 702673821
This code previously passed null or 'default' for every parameter.
Now it tries to mock non-final types, and recursively constructor final
types if possible, eventually giving up and passing null instead.
The previous null-passing behaviour led to a quite confusing failure in
`ForwardingPlayer.addListener` when writing 25c927e9f3 due to an NPE
when trying to compare parameter equality in `Mockito.verify` [1].
With this change, the failure is much clearer [2].
There's a relatively simple case this code still doesn't handle: A final
type like `PlaybackParameters` where the constructor parameters **have**
to be non-default primitives (greater than zero in that case).
-------
[1]
```
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at androidx.media3.test.utils.TestUtil.assertForwardingClassForwardsAllMethodsExcept(TestUtil.java:687)
at androidx.media3.common.ForwardingPlayerTest.forwardingPlayer_forwardsAllPlayerMethods(ForwardingPlayerTest.java:110)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:588)
at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:290)
at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:101)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.NullPointerException: Cannot invoke "Object.hashCode()" because "this.listener" is null
at androidx.media3.common.ForwardingPlayer$ForwardingListener.hashCode(ForwardingPlayer.java:1140)
at java.base/java.lang.Object.toString(Object.java:256)
at java.base/java.lang.String.valueOf(String.java:4220)
at org.mockito.internal.verification.argumentmatching.ArgumentMatchingTool.toStringEquals(ArgumentMatchingTool.java:54)
at org.mockito.internal.verification.argumentmatching.ArgumentMatchingTool.getSuspiciouslyNotMatchingArgsIndexes(ArgumentMatchingTool.java:36)
at org.mockito.internal.verification.checkers.MissingInvocationChecker.checkMissingInvocation(MissingInvocationChecker.java:45)
at org.mockito.internal.verification.Times.verify(Times.java:37)
at org.mockito.internal.verification.MockAwareVerificationMode.verify(MockAwareVerificationMode.java:30)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:75)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:34)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:82)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:56)
at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor$DispatcherDefaultingToRealMethod.interceptAbstract(MockMethodInterceptor.java:161)
at androidx.media3.common.Player$MockitoMock$1276619531.addListener(Unknown Source)
... 22 more
```
----
[2]
```
Argument(s) are different! Wanted:
player.addListener(
Mock for Listener, hashCode: 107929032
);
-> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Actual invocations have different arguments:
player.addListener(
androidx.media3.common.ForwardingPlayer$ForwardingListener@af47cec0
);
-> at androidx.media3.common.ForwardingPlayer.addListener(ForwardingPlayer.java:81)
```
PiperOrigin-RevId: 702378861
This only affects the default SDK level that Robolectric tests run at.
Also upgrade the Robolectric version to 4.14.1 to pick up
4f32042afe
which is needed for async `ShadowMediaCodec` support (the default in
ExoPlayer from API 31+).
Some tests fail on Robolectric at API 31. This change configures them to
continue running on API 30, so the failures can be investigated and
fixed in follow-up changes.
PiperOrigin-RevId: 702357124
Earlier this year, we explored frame extraction built on top of Transformer
or ImageReader.
We decided against these approaches because random-access of frames
is a key requirement. And ImageReader behaviour is unreliable.
PiperOrigin-RevId: 702303490
This means we can complete preparation (and trigger track selection)
before opening a `DataSource`, which then means we only end up loading
the data for a selected subtitle track (instead of all tracks as
currently happens).
By making preparation trivial in this case (with no reasonable cause
of error), we can also remove the `suppressPrepareError` option added in
b3290eff10.
This change also fixes the implementation of
`ProgressiveMediaPeriod.maybeStartDeferredRetry` to only short-circuit
return `false` if the chosen track is not audio or video **and** there
is at least one audio or video track in this period.
Issue: androidx/media#1721
PiperOrigin-RevId: 702275968
This method was taking positionUs and elapsedRealtimeUs parameters and
throwing a VideoSinkException because it was calling render() to make
room for a new input frame. Instead of doing that, this CL makes sure
render() is called before handleInputFrame() in the renderer (even
though it may not make a significant difference).
PiperOrigin-RevId: 702273587
Add missing ones for `ForwardingExtractorInput` and `ForwardingSeekMap`.
`ForwardingTimeline` is a bit more fiddly, so it's left for a follow-up
change.
PiperOrigin-RevId: 701988492
Previously cancelling one FrameExtractor.getFrame
ListenableFuture caused the following requests to fail.
Implement ability to cancel Futures, and correctly issue
next player seek commands after all past requests complete.
Removes uses of SettableFuture, and replaces them with
CallbackToFutureAdapter.
Adds a dependency on androidx.concurrent:concurrent-futures
PiperOrigin-RevId: 701941403
Frame Extractor was getting stuck with SeekParameters.CLOSEST_SYNC.
onPositionDiscontinuity callback was sometimes being called with a
non-adjusted new position.
Fix this by monitoring player state ready.
For the player to become ready, we have to override renderer isReady.
PiperOrigin-RevId: 701924752
When a session sets a custom layout, we currently convert it to the
media button preferences in MediaControllerImplBase and convert it back
to a custom layout for consumers of MediaController.getCustomLayout.
To avoid unnecessary conversions and potential changes, we can
directly use the provided custom layout to get the same logic as
before. This also means we avoid notifying a change to the custom layout
if only the implicit slots changed that weren't relevant before
introducing them (=we can remove some tests for this behavior).
PiperOrigin-RevId: 701903475
The isLastBuffer flag passed to MediaCodecRenderer.processOutputBuffer()
is unreliable. It is true for the last frames (plural) of a video
stream, which makes it possible for the video renderer to end before all
the frames have been rendered to the output surface.
PiperOrigin-RevId: 700941685
This aligns the behavior with `MediaExtractor`, which sets this key in its [`MediaFormat`](https://developer.android.com/reference/android/media/MediaExtractor#getTrackFormat(int)) output.
Additionally, unnecessary `selectTrack` calls have been removed from the existing `getTrackFormat_...` tests, as they are not required to fetch the track format.
PiperOrigin-RevId: 700741326
Currently, `size` is cached in `SampleMetadata` when samples are committed in `SampleQueue`, which worked because we didn't support reading files with `CryptoInfo`. This change prepares for future `CryptoInfo` support, as the size changes when reading samples with encrypted data. Caching the size at commit time could lead to incorrect buffer `size` calculations.
Existing tests verify the correctness of the `getSampleSize()` API.
PiperOrigin-RevId: 700714178
Also add an explicit warning about how fiddly `ForwardingPlayer` can be
to use correctly.
PiperOrigin-RevId: 700698032
(cherry picked from commit 60133b0c7edccaf350c56193022147bd46509039)
The Android SKD version 30 is stable, allowing us to remove the `@SuppressLint("Override")` annotations from `InputReaderAdapterV30` and `OutputConsumerAdapterV30`.
PiperOrigin-RevId: 700681115
The previous version (3.33.0) is known to have some bugs, and the latest
version (3.36.0) is also known to be buggy.
PiperOrigin-RevId: 700657484
(cherry picked from commit 6cf3004d623b9e5fa0e2c1dfc0ba8da1fc4f2cb1)
The previous code assumed that the `VBRI` Table of Contents (ToC)
covers all the MP3 data in the file. In a file with an invalid VBRI ToC
where this isn't the case, this results in playback silently stopping
mid-playback (and either advancing to the next item, or continuing to
count up the playback clock forever). This change considers the `bytes`
field to determine the end of the MP3 data, in addition to deriving it
from the ToC. If they disagree we log a warning and take the max value.
This is because we handle accidentally reading non-MP3 data at the end
(or hitting EoF) better than stopping reading valid MP3 data partway
through.
Issue: androidx/media#1904
#cherrypick
PiperOrigin-RevId: 700319250
(cherry picked from commit 46578ee0a6e8adf4c56b7b45b43713b132e35cca)
Introduced a `mediaSourceFactory` attribute to CompositionPlayer. This allows for the use of a custom MediaSource.Factory when creating media sources, providing more flexibility and control over media source creation. Previously, the default `MediaSource.Factory` was used in all cases.
PiperOrigin-RevId: 700391911
The previous code assumed that the `VBRI` Table of Contents (ToC)
covers all the MP3 data in the file. In a file with an invalid VBRI ToC
where this isn't the case, this results in playback silently stopping
mid-playback (and either advancing to the next item, or continuing to
count up the playback clock forever). This change considers the `bytes`
field to determine the end of the MP3 data, in addition to deriving it
from the ToC. If they disagree we log a warning and take the max value.
This is because we handle accidentally reading non-MP3 data at the end
(or hitting EoF) better than stopping reading valid MP3 data partway
through.
Issue: androidx/media#1904
#cherrypick
PiperOrigin-RevId: 700319250
The current code assumes that the first Table of Contents segment
includes the `VBRI` frame, but I don't think this is correct and it
should only include real/audible MP3 ata - so this change updates the
logic to assume the first ToC segment starts at the frame **after** the
`VBRI` frame.
Issue: androidx/media#1904
#cherrypick
PiperOrigin-RevId: 700269811
The current code assumes that the first Table of Contents segment
includes the `VBRI` frame, but I don't think this is correct and it
should only include real/audible MP3 ata - so this change updates the
logic to assume the first ToC segment starts at the frame **after** the
`VBRI` frame.
Issue: androidx/media#1904
PiperOrigin-RevId: 700269811
(cherry picked from commit f257e5511f12f57eb8397ec0801f32361a482f4f)
This was hand-crafted with a 4-entry ToC by modifying
`bear-vbr-xing-header.mp3` in a hex editor.
The output difference from 117 samples to 116 samples is due to the
calculation in `VbriSeeker` assuming that the ToC includes the VBRI
frame itself, which I don't think is correct (fix is in a follow-up
change).
Issue: androidx/media#1904
#cherrypick
PiperOrigin-RevId: 700254516
This was hand-crafted with a 4-entry ToC by modifying
`bear-vbr-xing-header.mp3` in a hex editor.
The output difference from 117 samples to 116 samples is due to the
calculation in `VbriSeeker` assuming that the ToC includes the VBRI
frame itself, which I don't think is correct (fix is in a follow-up
change).
Issue: androidx/media#1904
#cherrypick
PiperOrigin-RevId: 700254516
(cherry picked from commit 3eb36d67bd90d6d962df26dfdf29701a45902b4a)
This CL also aligns supported color space in `media3 common` and `media3 muxer`.
Earlier `muxer` would take even those values which are considered invalid
in `media3` in general.
Earlier muxer would throw if a given `color standard` is not recognized
but with the new change, it will rather put default `unspecified` value.
#cherrypick
PiperOrigin-RevId: 698683312
(cherry picked from commit 407bc4fec9d834ad9ab85c21ad236af6bf6fbc55)
Mp4Muxer caches the samples and then writes them in batches.
The new API allows disabling the batching and writing sample
immediately.
PiperOrigin-RevId: 689352771
(cherry picked from commit f181855c5e1577b2df2d61ca49b04e6a202679b0)
Support extracting frames from HDR input by tone mapping
to SDR (BT.709).
ExperimentalFrameExtractor must be public because HDR tests
live in a different package.
PiperOrigin-RevId: 699994112
Adds a configuration option to Frame Extractor to choose MediaCodecSelector.
Add a MediaCodecSelector that lists software decoders first
PiperOrigin-RevId: 699962365
Renderers join when they can start processing but not produce output.
In CompositionPlayer before this change, the VideoSink will be flushed when
position is reset regardless. This is useful for seeking, as seeking triggers position reset. But with pre-warming, a video renderer can be joining - it is
enabled (which also triggers position reset) before the previous image renderer
is disabled. At this moment, as the image renderer is still producing frames,
we should not flush the video sink just now.
PiperOrigin-RevId: 699943882
We are currently waiting until stream 1 is completely rendered on screen
before registering stream 2 but that is not necessary anymore because
VideoFrameProcessor supports registering stream 2 before stream 1 is
fully processed.
PiperOrigin-RevId: 699929943
Before this CL, the following scenario could happen:
- A new input stream is registered to the DefaultVideoFrameProcessor.
- Before the pipeline is reconfigured, a seek is issued andd the
DefaultVideoFrameProcessor is flushed.
- As a result, the new input stream registration is never taken into
account.
As a result:
- If an input stream is registered after the seek (before queueing any
frame), registerInputStream will block indefinitely because
inputStreamRegisteredCondition will be closed.
- If a frame is queued after the seek, it will be linked to the input
stream information of the previous frames.
This CL makes sure that any pending input stream is registered after a
flush.
PiperOrigin-RevId: 698736866
This call does 2 things:
1. It's used to estimate the frame rate early but this is incorrect as
the frame rate can be changed by effects. I have tested playback on
my device and I don't see any difference.
2. For ExoPlayer.setVideoEffects() only: it allows dropping all the
frames until the next key frame in case the input frame is "very
late". This doesn't seem really necessary though because because we
do the same thing after applying effects.
This change is also a step towards moving all the calls to
VideoFrameRelease/RenderControl to DefaultVideoSink.
PiperOrigin-RevId: 698732161
Changes includes making sure the same `defaultMediaSourceFactory` is used when creating a new media source in `setPrimaryPlayerSequence` and `setSecondaryPlayerSequence`.
This is pre-work for introducing a new attribute `mediaSourceFactory` that can be optionally used instead of the default one. This will allow developers to pass a customized media source factory to CompositionPlayer.
PiperOrigin-RevId: 698721139
This CL also aligns supported color space in `media3 common` and `media3 muxer`.
Earlier `muxer` would take even those values which are considered invalid
in `media3` in general.
Earlier muxer would throw if a given `color standard` is not recognized
but with the new change, it will rather put default `unspecified` value.
#cherrypick
PiperOrigin-RevId: 698683312
Adds a Frame extractor test that verifies decoder
respects rotation metadata from the mp4 container.
Do not rely on the MediaCodec decoder rotate the input.
Rotate via a video effect instead.
PiperOrigin-RevId: 698381282
This non-functional refactor inlines and simplifies the logic of
`BaseAudioProcessor` used by `SpeedChangingAudioProcessor`, and makes
the latter implement `AudioProcessor` directly.
`SpeedChangingAudioProcessor` acts as a wrapper over
`SonicAudioProcessor` and does not actually modify any samples,
so it had very little use for the affordances provided by
`BaseAudioProcessor`.
PiperOrigin-RevId: 698342962
3P app reported it's slow to see the first image frame on the screen, when
`playWhenReady` is false. This is because the player would wake up less
frequently when `playWhenReady` is false. This CL adds a runnable to wake up
the player any time a new frame is made available.
PiperOrigin-RevId: 698066887
SpeedChangingAudioProcessor is redundantly bypassing SonicAudioProcessor
when the speed is set to 1f. SpeedChangingAudioProcessor should not make
assumptions about the underlying audio processing and moreover should
not be bypassing any AudioProcessor based on parameter values. Default
parameter values are a valid state for an active AudioProcessor.
Sonic already handles the "default case" state by just copying the input
buffer onto the output buffer.
This CL also simplifies SonicAudioProcessor, which would mark itself as
inactive when configured with a valid set of default parameters. The API
contract for `isActive()` makes no mention about parameter state, which
makes changes in `isActive()` after applying new valid parameters quite
unintuitive.
PiperOrigin-RevId: 698000500
The following was happening:
- VideoFrameRenderControl.render() was calling
VideoFrameReleaseAction.getFrameReleaseAction().
- VideoFrameReleaseAction.getFrameReleaseAction() was calling
FrameTimingEvaluator.shouldIgnoreFrame(), which is implemented in
MediaCodecVideoRenderer.
- MediaCodecVideoRenderer.shouldIgnoreFrame(), when returning true,
was also flushing the VideoSink, which was flushing the
VideoFrameRenderControl.
- VideoFrameRenderControl.render() was removing the frame from the
presentationTimestampsUs queue, but the frame had already been removed
by the flush operation, causing an exception to be thrown.
This fix removes the last step.
PiperOrigin-RevId: 697915692
To do this, refactor stream start position handling so that
VideoFrameRenderControl is only passed a start position when it should
be applied, and therefore doesn't need to take a timestamp associated
with each start position anymore
PiperOrigin-RevId: 697544416
From [ the last change in `DefaultPreloadManagerTest`](2b54b1ebbe), the preloadManager began to use a separate `preloadThread` in `release_returnZeroCount_sourcesAndRendererCapabilitiesListReleased`, which unveils a bug in `PreloadMediaSource`. When `PreloadMediaSource.releasePreloadMediaSource` is called, `preloadHandler` will post a `Runnable` on the preload looper to release the internal resources. Before this `Runnable` is executed, it is possible that the [`stopPreloading`](https://github.com/androidx/media/blob/main/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java#L442) method is executed just as the result of preloading has completed. This is expected to remove the posted `Runnable`s for further preloading, however, the posted `Runnable` for releasing will also be removed from the message queue.
Ideally we should use `postDelayed(runnable, token, delayMillis)` to post the runnables so that the token will be useful to identify which messages to remove in `removeCallbacksAndMessages(token)`, but that `postDelayed` method is only available from API 28. So in this change we are using a separate handler for releasing, and then the call of `preloadHandler.removeCallbacksAndMessages` won't impact the runnable for releasing.
#cherrypick
PiperOrigin-RevId: 696894483
This method returns a `PersistableBundle` containing metrics data for the current media container. The bundle includes attributes and values for the media container, as described in `MediaExtractor.MetricsConstants`.
PiperOrigin-RevId: 696893276
The new callback allows an app to read data from the content
timeline to populate the `AdPlaybackState`. To avoid a deadlock
between the `AdMediaSource` waiting for the `AdPlaybackState` and
the app waiting for the content `Timeline`, a boolean flag
`useLazyContentSourcePreparation` is introduced to tell the
`AdsMediaSource` to prepare the content source immediately
to make the `Timeline` available.
A unit test verifies that in none of the cases (lazy preparation or
immediate preparation) a `Timeline` without ad data is leaked to the
caller. This ensures that in the case of a preroll, the player won't
initially and accidentally read content media data before starting to
load the preroll ad. While the content source is prepared early, no
content media period must be created before the preroll starts.
PiperOrigin-RevId: 696885392
ISO/IEC 23001-8 has been withdrawn. The corresponding definition for channel configuration is available in ISO/IEC 23091-3. Update the comment to reflect this change.
The content in Issue: androidx/media#1863 has every sample incorrectly marked as a
sync sample in the MP4 metadata, which results in flushing the
re-ordering queue on every sample, so nothing gets re-ordered, so the
subtitles are garbled.
There are currently two "uses" for this call on every keyframe:
1. It offers a safety valve if we don't read a `maxNumReorderSamples`
value from the video. Without this, the queue will just keep growing
and end up swallowing all subtitle data (similar to the bug fixed by
39c734963f).
2. When we do read (or infer) a `maxNumReorderSamples` it means we can
emit samples from the queue slightly earlier - but this is pretty
marginal, given i think the max possible value for
`maxNumReorderSamples` is 16, so the most benefit we would get is 16
frames (~0.53s at 30fps) - in most cases we will have more than 0.5s
of buffer ahead of the playback position, so the subtitles will still
get shown at the right time with no problem.
(1) is resolved in this change by setting the queue size to zero (no
reordering) if we don't have a value for `maxNumReorderSamples`.
(2) has minimal impact, so we just accept it.
We may be able to inspect the NAL unit to determine IDR vs non-IDR
instead - we will consider this as a follow-up change, but given the
minimal impact of (2) we may not pursue this.
#cherrypick
PiperOrigin-RevId: 696583702
- Rename a few methods/variable to improve readability.
- Refactor how video size changes are tracked. This will simplify the
upcoming logic to refactor the timestamp logic in
VideoFrameRenderControl because we will use the same logic for
outputVideoSize and for outputStreamStartPositionUs.
PiperOrigin-RevId: 696026515
Earlier watchdog timer was started only after all the tracks are
added. For the cases where export is stuck before adding tracks,
the export would hang forever and will not timeout automatically.
With the changes, watchdog timer is started as soon as export is
started/resumed. Now if the pipeline is stuck before writing any samples,
it will timeout and report error to the caller.
Existing test case: c35a9d62ba/libraries/transformer/src/test/java/androidx/media3/transformer/MediaItemExportTest.java (L996)
PiperOrigin-RevId: 695781654
The behaviour was changed in 1.4.0 with 0f42dd4752,
so that the buffer timestamp is compared to `outputStartTimeUs` when
deciding whether to discard a "decode only" buffer before decoding
(instead of the deprecated/removed `isDecodeOnly` property). This breaks
when the buffer timestamp is `TIME_END_OF_SOURCE` (which is
`Long.MIN_VALUE`), because `TIME_END_OF_SOURCE < outputStartTimeUs` is
always true, so the end-of-stream buffer is never passed to the decoder
and on to `TextRenderer` where it is used to
[set `inputStreamEnded = true`](40f187e4b4/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/TextRenderer.java (L434-L436))
and so playback hangs.
#cherrypick
Issue: androidx/media#1863
PiperOrigin-RevId: 695767247
Implemented `getCachedDuration()` to provide an estimate of cached data in memory and `hasCacheReachedEndOfStream()` to indicate if the cache has reached the end of the stream.
Note: The Javadoc for the newly added methods closely follows that of the platform `MediaExtractor`. While the current implementation always uses a cache and therefore never returns `-1` from `getCachedDuration`, this leaves room for future changes should caching behavior or conditions evolve.
PiperOrigin-RevId: 695694460
A skeleton implementation that doesn't actually return decoded frames.
In the current state, we use ExoPlayer to seek to a position, and
ExoPlayer.setVideoEffects to record the presentation time selected.
Seeking and processing frames are synchronized via ListenableFuture
callbacks.
PiperOrigin-RevId: 695691183
In some cases, callers will need to pass in both BitmapLoader and Codec.DecoderFactory without specifying a custom MediaSource.Factory. Omitting the annotation will result in NULL_FOR_NONNULL_TYPE compilation errors in Kotlin.
PiperOrigin-RevId: 695481606
This is because the method is called for each media item, the current name
implies that the method is only called once for all videos in a sequence.
PiperOrigin-RevId: 695332916
This method will replace the current estimation mechanism in place on
`getSpeedAdjustedTimeAsync()`, which relies on heuristics from previous
output rates and depends on the state of the `AudioProcessor`. The new
static method should be considerably more accurate.
PiperOrigin-RevId: 694607264
This ensures it works correctly when there are multiple SEI messages per
sample and the max size is set from e.g. H.264's
`max_num_reorder_frames`.
PiperOrigin-RevId: 694526152
The `RendererCapabilities` and `TrackSelector` objects are accessed on the preload thread during the preloading, when releasing them, they need to be released on the same thread. Otherwise, it is possible that they have already released on the application thread, while the PreloadMediaSource still tries to access them on the preload thread before the source is released.
#cherrypick
PiperOrigin-RevId: 694173131
Note: `androidx.media3.common.DrmInitData` is returned instead of the platform `android.media.DrmInitData` because the platform class has a package-private constructor, making it impossible to implement the abstract class outside the platform.
PiperOrigin-RevId: 694096542
Added the functionality for `Choose local file` button to be able to go and select a local file from the device. The file was then displayed by using ExoPlayer inside PlayerView.
PiperOrigin-RevId: 693756565
Added a basic UI to the effect demo app, including a PlayerView, buttons to choose preset input and choose local file, and a button to apply effects. The buttons are currently not implemented, and the app will show a snackbar message when they are clicked.
PiperOrigin-RevId: 693751272
Changed the dependency of `lib-common` in `lib-ui` from an `implementation` dependency to an `api` dependency. This change ensures that classes and interfaces from `lib-common` used in the public API of `lib-ui` are correctly exposed to consumers of `lib-ui`.
For example, `PlayerView implements AdViewProvider` where the latter is from `androidx.media3.common.AdViewProvider`.
PiperOrigin-RevId: 693734349
Enable transformer to transmux into alternative sample MIME types.
For example, some Dolby Vision profiles have a backwards-compatible
AVC or HEVC layer. MV-HEVC is backwards compatible with HEVC.
This change enables Transformer to transmux into the backwards compatible
format to improve compatibility with legacy APIs such as
MediaMetadataRetriever.
PiperOrigin-RevId: 693667597
All instances of PlaybackVideoGraphWrapper use the same
VIDEO_FRAME_PROCESSOR_FACTORY_SUPPLIER which uses the same
DefaultGlObjectsProvider.
Each call to DefaultGlObjectsProvider.release() releases
all previously created EGLContexts.
Lazily create a new DefaultGlObjectsProvider for each
DefaultVideoFrameProcessor (not one per factory).
PiperOrigin-RevId: 693658458
The tests became more flaky after 76e4abe428, likely because playback
was able to start slightly earlier, exaggerating any existing race
conditions. Fix the flakiness by letting all tests with subtitle
parsing wait until all data is fully loaded before starting to play.
PiperOrigin-RevId: 693380656
When a new media session sets media button preferences, we need to
"translate" them back to a custom layout to ensure the user preferences
are represented as closely as possible when the controller uses the
old button placement rules.
PiperOrigin-RevId: 693306153
The method currently modifies the input Bundle, but it's easier to
reason about it if the method is side-effect free and the places
that need to modify a Bundle do this after calling the method.
PiperOrigin-RevId: 693288031
Implemented `setLogSessionId(LogSessionId)` and `getLogSessionId()` methods.
Note: The `LogSessionId` is currently **not** forwarded to `MediaParser`, but this will be addressed once `MediaParser` can be used to configure `MediaExtractorCompat`.
PiperOrigin-RevId: 692945255
* Provide a helper Composable for remembering the state instance and launching the listening coroutine that observes the changes in the Player
* Add an example to demo-compose of using Shuffle- and Repeat- ButtonStates inside a Shuffle- and RepeatButton Composable.
* Reformat the MainActivity usage of `Shuffle` and `Repeat` buttons to form extra Player Controls and combine Prev/Play-Pause/Next with Shuffle/Repeat (Minimal controls + Extra controls = `PlayerControls`)
PiperOrigin-RevId: 692939825
The test has been moved to an instrumentation test as it relies on APIs that vary by SDK version. Robolectric’s emulation lacks sufficient realism in some cases, which impacts test accuracy. By using an instrumentation test, we ensure that the tests run in a real Android environment, providing reliable results for SDK-dependent APIs.
PiperOrigin-RevId: 692933259
Also move the `lint.xml` config which disables the `NewApi` check from
`lib-session` to the existing top-level file, and limit it to cover all
Robolectric tests by path matching.
Follow-up to 76db936d68
PiperOrigin-RevId: 692913646
This change keeps getSurfaceForCodec and hasSurfaceForCodec in sync.
Before this change when ExoPlayer is configured with setVideoEffects
and no display surface, codecs that need Set Output Surface Workaround
would not be initialized because hasSurfaceForCodec always returns false
PiperOrigin-RevId: 692900899
Restructured sample metadata management in `MediaExtractorCompat` to maintain a queue of `SampleMetadata` objects, each containing `timeUs`, `flags`, `size`, and `trackIndex`, rather than storing only track indices.
Introduced a pooling mechanism for `SampleMetadata` to reduce object allocation and improve memory efficiency. The new `SampleMetaDataQueue` centralizes metadata for easier access and management, eliminating the need to allocate a buffer or peek into the `SampleQueue` to retrieve sample metadata.
This change does not change existing behavior, it optimizes the internal structure, and existing tests already verify the relevant APIs.
PiperOrigin-RevId: 692285581
This CL adds utility methods to obtain sample-aligned timestamps from a
`SpeedProvider` to solve in a unified way the issues arising from
conversions between sample positions and microseconds.
The new utility methods will also help with the implementation of a
static method like `getDurationAfterProcessorApplied()` that will remove
the need for thread synchronization between the video and audio pipeline
for speed changing effects.
PiperOrigin-RevId: 692233318
If audio processors report a drifting position, we currently update
the media position parameters to correct this drift. However, this
means we pass in the wrong value to
audioProcessorChain.getMediaDuration, which reuqires the time since
the last flush.
To fix this problem, we can instead save the drift seperately and
apply it where needed.
PiperOrigin-RevId: 692202219
Also makes muxer shift the first video timestamp to zero, if it's not.
The trim position should respect the media timeline.
For example in a video that is 10s long (without edit list), if an edit list
adds 1_000ms to each video sample, and trimming 100ms, here's the expected:
- The video duration is 10.9s (`10s + 1s edit - 0.1s trim`)
- The first video frame time would be at 0.9s (`1s edit - 0.1s trim`)
PiperOrigin-RevId: 692187399
* Provide a helper Composable for remembering the state instance and launching the listening coroutine that observes the changes in the Player
* Add an example to demo-compose of using Previous- and Next- ButtonStates inside a Previous- and NextButton Composable.
* Reformat the MainActivity usage of `Previous`, `PlayPause`, `Next` buttons to form Minimal Player Controls
PiperOrigin-RevId: 691943147
Provide a helper Composable for remembering the state instance and launching the listening coroutine that observes the changes in the Player
Add an example to demo-compose of using PlayPauseButtonState inside a PlayPauseButton Composable.
The smart State object has been deemed a preferred solution over collecting Flows due to queuing/timing/buffering limitations. Instead, it uses the new `Player.listen` suspending extension function to catch the relevant events.
PiperOrigin-RevId: 691879975
This affects both `AnalyticsListener` and `MediaSourceEventListener`
This was introduced by d051b4b993
Also fix a missing 'load started' event for HLS media playlists (this
was also introduced by d051b4b993).
PiperOrigin-RevId: 691580183
Replaced the custom `LibraryLoader` instance with `OpusLibrary.isAvailable()` to verify the library loading. This simplifies the code by leveraging the existing library loading mechanism.
#cherrypick
PiperOrigin-RevId: 691457871
Using frames instead of bytes helps simplify the processing logic for
the component and will help with the move towards sample-based
`SpeedProvider`s. By using frames, we also abstract away the complexity
related to sample encoding.
This is a non-functional refactor.
PiperOrigin-RevId: 691444106
The overload that takes a `Format` is preferred, because it can detect
SEI NAL units in Dolby Vision tracks too.
Submitting this in a separate change so we can avoid cherry-picking it
into `1.5.0-rc01`, otherwise it would naturally be part of
27371db225.
Issue: androidx/media#1820
PiperOrigin-RevId: 691408725
Previously, `getTrackFormat()` in `MediaExtractorCompat` returned a `MediaFormat` without setting `MediaFormat.KEY_DURATION`. With this change:
- `MediaFormat.KEY_DURATION` is set based on the track's duration, if available.
- If the track duration is unset, the duration from the seek map is used as a fallback.
- When neither duration is set, `MediaFormat.KEY_DURATION` remains unset.
This ensures that `MediaFormat.KEY_DURATION` is populated when possible, enhancing duration information availability.
PiperOrigin-RevId: 691395114
This method will likely be removed in the next release, and is currently
only needed from within the `source` package.
#cherrypick
PiperOrigin-RevId: 691351449
This change ensures that the test uses `assumeTrue` to avoid failures when the `libiamf` library is not pre-built.
#cherrypick
PiperOrigin-RevId: 691333564
The logic in assumeFormatsSupported assumes that portrait videos are
always rotated before encoding but that's not the case when portrait
encoding is enabled.
PiperOrigin-RevId: 691042881
In some cases, the streamOffsetUs was passed to
VideoFrameReleaseControl.getFrameReleaseAction() but it should be the
streamStartPositionUs.
PiperOrigin-RevId: 691040172
When transitioning to the next media position parameter checkpoint
we estimate the position because the audio processor chain no longer
provides access to the actual playout duration.
The estimate using the declared speed and the last checkpoint may
have drifted over time, so we currently estimate relative to the
next checkpoint, which is closer and presumably provides a better
estimate. However, this assumes that these checkpoint are perfectly
aligned without any position jumps.
The current approach has two issues:
- The next checkpoint may include a position jump by design, e.g.
if it was set for a new item in the playlist and the duration of
the current item wasn't perfectly accurate.
- The sudden switch between two estimation methods may cause a jump
in the output position, which is visible when we add new media
position checkpoints to the queue, not when we actually reach the
playback position of the checkpoint.
We can fix both issues by taking a slightly different approach:
- Continuously monitor the estimate using the current checkpoint. If
it starts drifting, we can adjust it directly. This way the estimate
is always aligned with the actual position.
- The change above means we can safely switch to using the estimate
based on the previous checkpoint. This way we don't have to make
assumptions about the next checkpoint and any position jumps will
only happen when we actually reach this checkpoint (which is more
what a user expects to see, e.g. at a playlist item transition).
Issue: androidx/media#1698
PiperOrigin-RevId: 690979859
Removed deprecated `Transformer.PROGRESS_STATE_NO_TRANSFORMATION`, `Transformer.setListener`, and `Transformer.startTransformation` from Transformer.
PiperOrigin-RevId: 690971992
Adjusted logic to accurately calculate sizes and durations for the last valid cue point when cue timestamps are greater than the total duration.
Fixes the issue where the reported duration of the MKV file was greater than the total duration specified by the duration element. Verified this using `mkvinfo` and `mediainfo` tools.
PiperOrigin-RevId: 690961276
A player that is being released may report an error with
null `player.getPlayerError()`. Do not try to read errors
of players that are released.
PiperOrigin-RevId: 690953083
This method allows `Sonic` to statically and accurately report the
expected number of output frames for any given parameter configuration.
This change is required prework for `SpeedChangingAudioProcessor` to
implement a similar static method and allow precise, non-blocking
timestamp adjustments for the experimental speed changing effect.
PiperOrigin-RevId: 690669627
Also, fix incorrectly stretched golden file that was not detected with previous, less sensitive, average pixel error comparison.
PiperOrigin-RevId: 690643520
GLSL 3.00 mediump doesn't require enough precision near zero
to correctly represent PQ colors where the [0, 1] GL range
represents [0, 10_000] nits.
This caused `noEffects_hlg10InputAndHdr10Output_matchesGoldenFile`
to fail on some devices.
PiperOrigin-RevId: 690627069
The old code that uses MediaCodec directly has a race condition
that causes the decoder to incorrectly crop the decoded picture.
PiperOrigin-RevId: 690620868
This is prework for `Sonic` to provide a precise calculation of output
sample counts, and thus allow `SpeedChangingAudioProcessor` to replace
`getSpeedAdjustedTimeAsync()` with an accurate synchronous calculation.
This is a non functional change.
PiperOrigin-RevId: 690608520
This method is already called below in the
`else if (sps.isCompleted())` block which applies when
`hasOutputFormat == true`, but this is only ever entered if we are
parsing SPS and PPS NAL units **after** we've emitted a format, which
is only the case if
`DefaultTsPayloadReaderFactory.FLAG_DETECT_ACCESS_UNITS` is set (which
it isn't by default).
The equivalent call in `H265Reader` is already inside the
`if (!hasOutputFormat)` block, so doesn't need a similar fix.
#cherrypick
PiperOrigin-RevId: 689809529
This ensures that media button preferences with slots for BACK,
FORWARD and OVERFLOW are converted to the legacy custom layout
according to the implicit placement rules. This has to happen
when populating the MediaSessionCompat and when generating the
notification for older APIs. Sending these preferences to older
Media3 controllers can filter them down to the custom layout the
session would have used previously, but there is no need to adjust
the reservation extras because the older Media3 custom layout has
no concept of these extras.
PiperOrigin-RevId: 689761637
This is equivalent to the current logic, but also allows to easily pick
up other buttons that use the BACK, CENTRAL or FORWARD slots for the
compact view by default.
Also fix the test to actually assert the output order.
PiperOrigin-RevId: 689747844
This ensures that the slots are set according to the implicit placement
rules for the legacy custom layouts. This has to be done when receiving
custom actions from a MediaControllerCompat and for Media3 sessions
setting the custom layout field.
PiperOrigin-RevId: 689737951
These methods are marked `default` on the `AnalyticsListener` interface
with an empty implementation, so there's no need to override them just
to re-define the empty implementation.
PiperOrigin-RevId: 689416584
* Use asset without audio for independent video time progress
* Use longer item duration to avoid ExoPlayer STATE_READY workaround
(see https://github.com/google/ExoPlayer/issues/1874)
PiperOrigin-RevId: 689409427
Add `DecoderAudioRenderer.getDurationToProgressUs()` so that `ExoPlayer`, if set with `experimentalSetDynamicSchedulingEnabled()`, will dynamically schedule its main work loop to when the `DecoderAudioRenderer` can make progress.
PiperOrigin-RevId: 689377247
Mp4Muxer caches the samples and then writes them in batches.
The new API allows disabling the batching and writing sample
immediately.
PiperOrigin-RevId: 689352771
- Create `LibiamfAudioRenderer` with `DefaultRenderersFactory` in `ExoPlayerModuleProguard`.
- Remove redundant library availability check from `IamfModuleProguard`.
- Move `proguard-rules.txt` to the root folder.
- Removed unused `cryptoType` parameter from `setLibraries()` method in `IamfLibrary`.
- Added log when `LibiamfAudioRenderer` is loaded in `DefaultRenderersFactory`.
- Annotated missing classes with `@UnstableApi`.
- Check for library availability and throw exception in `IamfDecoder` constructor.
#cherrypick
PiperOrigin-RevId: 689330016
This change:
1. Updates `DataSourceContractTest` to allow multiple "not found"
resources, and to include additional info (e.g. headers) on them.
2. Updates the contract test to assert that `DataSource.getUri()`
returns the expected (non-null) value for "not found" resources
between the failed `open()` call and a subsequent `close()` call.
The `DataSource` is 'open' at this point (since it needs to be
'closed' later), so `getUri()` must return non-null.
* This change also fixes some implementations to comply with this
contract. It also renames some imprecisely named `opened`
booleans that **don't** track whether the `DataSource` is open
or not.
3. Updates the contract test assertions to enforce that
`DataSource.getResponseHeaders()` returns any headers associated
with the 'not found' resource.
4. Configures `HttpDataSourceTestEnv` to provide both 404 and "server
not found" resources, with the former having expected headers
associated with it.
PiperOrigin-RevId: 689316121
The new `media3-ui-compose` module does not have any Material library dependencies, but will rely on androidx.compose + foundation/runtime/ui and other non-theming/opinionated libraries. Surface handling is one such usecase.
PiperOrigin-RevId: 689004504
Also add a test for this to avoid missing any others in future. Also
flesh out the existing test for the deprecated builder, to assert the
return type is correctly updated.
PiperOrigin-RevId: 688948768
The duration is now correctly calculated as the maximum of all track durations, instead of being overwritten by the last track's value. This aligns with how other Extractor implementations handle durations for multiple tracks.
PiperOrigin-RevId: 688896743
`RandomParameterizedSpeedChangingAudioProcessorTest` follows the
structure of `RandomParameterizedSonicAudioProcessorTest` and will help
improve coverage and confidence in the output length of
`SpeedChangingAudioProcessor`.
This CL is prework for removing the synchronization between the video
pipeline and the audio pipeline for speed changing effects.
PiperOrigin-RevId: 688578597
Currently most of the public APIs use `fullscreen` (apart from the deprecated `PlayerControlView.OnFullScreenModeChangedListener` which will have to remain as is). This code changes mostly private variable naming.
PiperOrigin-RevId: 688559509
Frame rate change is currently notified to the release control when the
video frame processor input frame rate changes, but it should be when
the video frame processor output frame rate changes.
PiperOrigin-RevId: 688512300
If not copied, the extras Bundle can be accidentally changed by the
app if it modifies the instance passed into MediaSession. On the flip
side, the Bundle should be modifiable once created so that the session
can amend the extras if needed without crashing.
PiperOrigin-RevId: 688485963
Added start and end time details to the error message for `REASON_START_EXCEEDS_END`, helping to debug cases where the start time exceeds the end time.
PiperOrigin-RevId: 688117440
The method allows extractors to set track duration when available. The `default` implementation does nothing, allowing implementers of `TrackOutput` to override it if they need to handle track duration.
Implemented it in `FakeExtractor` to print track duration in dump files.
PiperOrigin-RevId: 688110288
Treats the media duration as unknown (`C.TIME_UNSET`) when all bytes are `-1` to prevent exceptions during playback.
Issue: androidx/media#1819
#cherrypick
PiperOrigin-RevId: 688103949
Many of the Android TV platforms do not report accurate `SystemClock.elapsedRealtime()`
In addition this drift is not consistant accross multiple boxes, so the time offset
between any pair of boxes will vary over time.
This variance will lead to a drift in the Live Offset calculation.
Fix is simple, inValidate the NTP server query after a period of time (10 minutes)
and re-issue the call
If we handle the "codecs" in HlsPlaylistParser.java rather than in HlsMediaPeriod.java, since the "codecs" property includes both audio and video codec names here, we can't update it directly. Only video part should be updated by Dolby codec string.
It is possible for playback to be stuck when there is failure in loading further data, while the player is required to load more due to the buffered duration being under `DefaultLoadControl.bufferForPlayback`. Therefore, we check if there is any loading error in `isLoadingPossible`, so that the player will allow the playback of the existing data rather than waiting forever for the data that can never be loaded.
Issue: androidx/media#1571
PiperOrigin-RevId: 665801674
(cherry picked from commit 351593a2504c9185638637a69f8dd0caf4aa20db)
This method was added in API 31 (S) but it's non-functional
(incorrectly, silently, returns `false`) on the Widevine plugin version
(`16.0`) from R (API 30), which some devices up to at least API 34 are
still using.
This results in ExoPlayer incorrectly selecting an insecure decoder for
L1 secure content, and subsequently calling
`MediaCodec.queueInputBuffer` instead of `queueSecureInputBuffer`,
which is not supported and generates the following error:
> Operation not supported in this configuration: ERROR_DRM_CANNOT_HANDLE
Issue: androidx/media#1603
#cherrypick
PiperOrigin-RevId: 662852176
(cherry picked from commit ca455ee8583938669179b30a686a894b353820eb)
When there is an exception thrown from the `LoadTask`, the `Loader` will call `Loader.Callback.onLoadError`. Some implementations of `onLoadError` method may call `MediaPeriod.onContinueLoadingRequested`, and in the `PreloadMediaSource`, its `PreloadMediaPeriodCallback` will be triggered and then it can further call `continueLoading` if it finds needed. However the above process is currently done synchronously, which will cause problem. By calling `continueLoading`, the `Loader` is set with a `currentTask`, and when that long sync logic in `Loader.Callback.onLoadError` ends, the `Loader` will immediately retry, and then a non-null `currentTask` will cause the `IllegalStateException`.
Issue: androidx/media#1568
PiperOrigin-RevId: 662550622
(cherry picked from commit cd532c5fb290a6f02906a450b06b8bcff3253eb1)
If the length of the `ExtractorInput` is not known then the
`subtitleData` field is re-sized by 1kB each time
(`SubtitleExtractor.DEFAULT_BUFFER_SIZE`), so the end of the array is
often not populated. This change ensures that `length` is propagated to
`SubtitleParser`, so that implementations don't try and parse the
garbage/zero bytes at the end of the array.
Discovered while investigating Issue: androidx/media#1516
#cherrypick
PiperOrigin-RevId: 661195634
(cherry picked from commit f37f9690f489dbe83366c93c452faf70b272cae3)
Some RTSP servers may provide media descriptions for custom streams that are not supported. ExoPlayer should skip the invalid media description and continues parsing the following media descriptions.
To start, ExoPlayer will still error on malformed SDP lines for media descriptions, but will now skip media descriptions with "non-parsable" formats as described by [RFC 8866 Section 5.14](https://datatracker.ietf.org/doc/html/rfc8866#section-5.14).
Issue: androidx/media#1472
PiperOrigin-RevId: 660826116
(cherry picked from commit 8b33ad581140c8d667bf99c1ad754259be56be33)
This is caused when the requested "output start time" is equal to or
larger than the last event time in a `Subtitle` object.
This resolves the error in Issue: androidx/media#1516, but subtitles are still not
renderered (probably because the timestamps aren't what we expect
somewhere, but I need to investigate this part further).
#cherrypick
PiperOrigin-RevId: 660462720
(cherry picked from commit 3763e5bc1da5c5cdb458add2e95eb4e683da5b64)
Previously in MultiInputVideoGraph, each VFP would destroy the shared
eglContext, such that the same eglContext object is destroyed multiple times.
Adding a flag to disallow this.
The alternative being we could add a flag on the VFP constructor, but I think
that is too subscriptive (meaning if we later might want to add another boolean
to control another GL behaviour, multiple booleans would make the class less
reason-able), and would incur a lot of code changes at places.
PiperOrigin-RevId: 660354367
(cherry picked from commit 8f8e48731eeedea8636d4d31be4a0c0b9a574bec)
This is needed to correctly handle files with trailing non-MP3 data
(which is indicated by the length in the `Info` frame being shorter than
the overall length of the file).
The test file was generated by appending 150kB of `DEADBEEF` onto the
end of `test-cbr-info-header.mp3`, and the test asserts that the
extracted samples are identical.
Issue: androidx/media#1480
PiperOrigin-RevId: 658727595
(cherry picked from commit b09cea9e3a3f9a039b77c6e6db3ee5f450becc50)
Update esdsBox to support muxing of files encoded with Vorbis audio codec .
PiperOrigin-RevId: 655159074
(cherry picked from commit b77f1d0f99b3e287bc82883054b8ce54bab95fee)
eglDestroySurface only destroys the surface when it's made not current.
Pass the placeholder surface in FinalShaderProgramWrapper and use it
when destroying eglSurface.
PiperOrigin-RevId: 655139661
(cherry picked from commit 1797359950fbf1acceddd7f40058cbd003383544)
Add VideoFrameProcessingTaskExecutor.invoke() method that blocks until
Task has executed on GL thread.
Use that for FinalShaderProgramWrapper.setOutputSurfaceInfo
PiperOrigin-RevId: 655119768
(cherry picked from commit 9c075b692e9e76959e47e9ad3cb018d3071f9154)
This was used in media1 `MediaItemDescription` to indicate the download
status of a media item. When connected to a legacy
`MediaBrowserServiceCompat` the Media3 browsers converts the legacy
media item to a Media3 `MediaItem` and converts the extras of
`MediaDescriptionCompat.extras` to `MediaMetadata.extras`.
#cherrypick
PiperOrigin-RevId: 654625502
(cherry picked from commit 225ad482b13f2c9c661f2bf70300cdf948597fdf)
Implement dOpsBox to provide support for Opus audio codec
PiperOrigin-RevId: 653288049
(cherry picked from commit 01dda6d3e5fa1737d7587b08a94c01594ed9711e)
Implement d263Box to provide support for muxing video encoded with the h263 codec.
PiperOrigin-RevId: 653188633
(cherry picked from commit 951f2968519090bb2a1a1e3dcb9f5dab80958dfb)
To support AMR audio codec(audio/3gpp) add `0x81FF` mode to create damrBox.
Add unit test and an Android end to end test.
PiperOrigin-RevId: 652438693
(cherry picked from commit 11ca78761e268044abc85e591fb5a8c2be4d2fe1)
As reported in Issue: androidx/media#1493 we already use `HEADSETHOOK` to start
waiting for a double-tap, but we don't consider it for the second tap.
Similarly, we previously considered `PLAY` for the second tap, but not the first.
Only `HEADSETHOOK` and `PLAY_PAUSE` are
[documented](https://developer.android.com/reference/androidx/media3/session/MediaSession#media-key-events-mapping)
to transform double-tap to `seekToNext`. So this change removes the
`PLAY` detection from the second tap.
PiperOrigin-RevId: 651017522
(cherry picked from commit c64dacf3df9097dc2c4535674a31dac4f568d344)
Add support for MPEG4 codec to enable muxing video encoded with the mp4v-es codec. Use esdsBox method to generate esds box required for Mp4v box.
PiperOrigin-RevId: 651000744
(cherry picked from commit 34a802ef38e81389471d08c2574c6019d55d14fa)
Some external media files have CodecSpecificData greater than 128 bytes. Currently, that size
isn't fitting in one byte. Hence, added support to store large CodecSpecificDataSize, as per
ISO standard, by extending to more than one byte as required.
PiperOrigin-RevId: 650972472
(cherry picked from commit cf90d2624d114cdd3cbc8516565409dd8bd48cb7)
eglDestroySurface now unbinds surface from the GL
thread to ensure quick release of resources.
PiperOrigin-RevId: 650938712
(cherry picked from commit 70a6b5d50d359a6d8288a70758ee2a3c402167f9)
Implement damrBox to provide support for amr-wb audio codec.
Add unit test and an Android end to end test.
PiperOrigin-RevId: 650210732
(cherry picked from commit 6e18cb00533b9d66f75d36aa0a9b3c873e6f3b26)
Since the muxer supported only AAC audio codec, the esdsBox was unconditionally created within the audioSampleEntry. This CL refactors the box creation logic by moving it to the codecSpecificBox method. This is to make adding support for new audio codecs easier.
PiperOrigin-RevId: 650130935
(cherry picked from commit a2693553698bf75a6874f2a5bd7fc8b855232372)
The percentage should be interpreted as relative to the size of a parent
node.
This change makes this inheritance work correctly for percentages in
both the parent and child. It does not fix the case of a non-percentage
parent size with a percentage child size.
PiperOrigin-RevId: 649631055
(cherry picked from commit bb2fd002aef583b10eba9c497770c87a3be38839)
Lint somehow complains that the integer resulting from the bit-manipulation shouldn't be passed as an @IntDef parameter.
#cherrypick
PiperOrigin-RevId: 648687698
(cherry picked from commit afe3826d7c4b79acfe0fd165ac1940261a147040)
This change extends the error replication to a given set of
error codes (not only authentication error), but only
replicates an error if the caller of the service `Callback`
is a legacy controller. It also makes error replication
configurable so that apps can opt-out and report errors
manually instead, or define the error codes for which
replication is enabled.
The change also removes the restriction of `sendError` only
being available for Media3 controllers. Instead, sending an
error to a legacy controller updates the platform playback
state in the same way as sending the error to the media
notification controller.
#cherrypick
PiperOrigin-RevId: 648399237
(cherry picked from commit 70c063905c0831c072cb9e1fa90bfbc1fd70aa68)
Upon track transition of offloaded playback of gapless tracks, the framework will reset the audiotrack frame position. The `AudioTrackPositionTracker`'s `AudioTimestampPoller` must be made to expect the reset and cache accumulated sum of `AudioTimestamp.framePosition`.
#cherrypick
PiperOrigin-RevId: 647294360
(cherry picked from commit a58e77a5a63d51c8cb9419fc59a7f0c7459fcafe)
When handling a playback error that originates from a future item in
the playlist, we added support for jumping to that item first,
ensuring the errors 'happen' for the right 'current item'.
See 79b688ef30.
However, when we add this new position discontinuity to the
playback state, there may already be other position discontinuities
pending from other parts of the code that executed before the
error. As we can't control that in this case (because it's part
of a generic try/catch block), we need to send any pending
updates first before handling the new change.
Issue: androidx/media#1483
PiperOrigin-RevId: 646968309
(cherry picked from commit 727645179b3c26e495540f4445216fd035cc7654)
Setting a `null` value doesn't remove the key as expected per the `MediaFormat` API documentation, using the `removeKey` method instead which is only available starting API level 29.
PiperOrigin-RevId: 646462402
(cherry picked from commit 12c42585d25d4c51bc5d022aa282d4d36b8e1ff2)
ExoPlayer used to call `stop()` before `release()`. This was removed in
<unknown commit>.
A framework bug introduced in Android 11 (API 30) resulted in some
DRM -> clear transitions failing during `MediaCodec.configure()`. An
investigation in Issue: google/ExoPlayer#8696 and b/191966399 identified that this was
due to `release()` returning 'too early' and the subsequent
`configure()` call was then trying to re-use a `Surface` that hadn't
been fully detached from the previous codec. This was fixed in
Android 13 (API 33) with http://r.android.com/2094347.
ExoPlayer worked around the framework bug by adding an arbitrary 50ms
sleep after a failed codec initialization, followed by retrying. This
was enough to resolve the problem in the test scenario on a OnePlus
AC2003.
Issue: androidx/media#1497 points out that 50ms might not be the appropriate delay
for all devices, so it's an incomplete fix. They suggested re-adding the
`MediaCodec.stop()` call instead. This also reliably resolves the issue
on the OnePlus AC2003 (with neither workaround in place, the problem
repros almost immediately).
PiperOrigin-RevId: 646461943
(cherry picked from commit 5fcc7433a1f188c9644d4430a828a49d06c993cb)
Extractors should not report additional tracks once they called
ExtractorOutput.endTracks. This causes thread safety issues in
ProgressiveMediaPeriod where the array of sample queues is
extended while the playback thread accesses the arrays.
Detecting this problem early is beneficial to avoid unexplained
exceptions later one. In most cases where this may happen (namely
TS extractors finding new tracks), it's better to ignore the new
tracks instead of failing completely. So this change adds a
warning log message and assigns a placeholder output.
Note: The same workaround already exists in HlsSampleStreamWrapper
and MediaExtractorCompat.
Issue: androidx/media#1476
#cherrypick
PiperOrigin-RevId: 646427213
(cherry picked from commit 18e631ff790e0e9b3630ea8e36efb468474d0877)
The two arrays need to have the same length and the selection
must match in their nullness (unless for TYPE_NONE
renderers). Clarify this more clearly in the docs and add
new asssertions for it. This avoids that the player is failing
in obscure ways much later.
Issue: androidx/media#1473
#cherrypick
PiperOrigin-RevId: 646086833
(cherry picked from commit 71ef848ec3fa4409f3cdf797226c2a51ecd15da6)
HttpEngine does not support cookie storage.
#cherrypick
PiperOrigin-RevId: 646084702
(cherry picked from commit bb568b5150781457fe22c3d4a877e8c99bddc4a2)
The test is flaky because the decoding process in the renderer
depends on some timing from MediaCodec beyond our control and
the new keyframe added in the test is sometimes 'dropped' when
it arrives too late.
We can fix this by controlling the test progress a bit more
tightly: first rendering with the same current time until the
key frame is processed and then start increasing the time
until we've reached the end.
#cherrypick
PiperOrigin-RevId: 646064352
(cherry picked from commit ada4dc982fac32a57db069341f1f51c6a3bb6cc5)
HttpEngineDataSource is the recommended HttpDataSource when it is available. It uses the [HttpEngine](https://developer.android.com/reference/android/net/http/HttpEngine).
#cherrypick
PiperOrigin-RevId: 646051562
(cherry picked from commit e591c37b1e60d5138a612040efba752b7b7ab8e5)
Previously we assumed that `surfaceSyncGroupV34` was always non-null on
API 34, but this isn't true in edit mode. Instead we add an explicit
null-check before accessing it. We don't need to null-check it at the
other usage site because we are already null-checking `surfaceView` (via
`instanceof` check).
Issue: androidx/media#1237
#cherrypick
PiperOrigin-RevId: 645008049
(cherry picked from commit 99803066ea6d375f5527e0953aad4ecd91fbac3c)
This class is a lower-level UI component that isn't directly needed if
apps are using `PlayerView` to handle their video output (it is used as
an implementation detail of `PlayerView`).
Removing its unecessary usages from this demo avoids developers copying
this as an example when building their own apps.
#cherrypick
PiperOrigin-RevId: 644972454
(cherry picked from commit cb8f87e05e73d72ce7d2c405c4c5899dc31ade5e)
Some cases are not handled correctly at the moment:
- Pausing during suppressed playback should not clear the
suppression state.
- Transient focus loss while paused should be reported as
a playback suppression.
Issue: androidx/media#1436
#cherrypick
PiperOrigin-RevId: 644971218
(cherry picked from commit e84bb0d21cd114c5b726c6c3d799b194df068a14)
Sometimes the reason for the current state may change. If we don't
report this again, users have no way of knowing that the reason
changed.
Also adjust ExoPlayerImpl and MediaControllerImplBase accordingly.
SimpleBasePlayer already adheres to this logic.
#cherrypick
PiperOrigin-RevId: 644970236
(cherry picked from commit 1d26d1891e6e3cd49a4b479723b8aba7be746c1c)
This helps to keep the reason always together with the state it
is referring to, avoiding any side channels and making sure there
are no accidental inconsistencies.
#cherrypick
PiperOrigin-RevId: 644969317
(cherry picked from commit c0abd6f91ec62bc5347561c3f3174b3a660a7ba6)
This workaround is only applied on API 34, because the problem isn't
present on API 33 and it is fixed in the platform for API 35 onwards.
Issue: androidx/media#1237
#cherrypick
PiperOrigin-RevId: 644729909
(cherry picked from commit 968f72fec6d5452a34976824ac822782eeeb8f45)
In the case of a legacy session app providing an error
code different to `ERROR_UNKNOWN` without an error
message, a localized fallback message is provided
instead of ignoring the error.
#cherrypick
PiperOrigin-RevId: 644704680
(cherry picked from commit 6cc6444dd9be34ea3a40d2bb296247178ee86b1d)
The 'player commands' returned to ExoPlayerImpl instruct the
player on how to treat the current audio focus state.
The current return value when playWhenReady==false is misleading
because it implies we are definitely not allowed to play as if
we've lost focus. Instead, we should return the actual player
command corresponding to the focus state we are in.
This has no practical effect in ExoPlayerImpl as we already
ignore the 'player command' completely when playWhenReady=false.
To facilitate this change, we also introduce a new internal
state for FOCUS_NOT_REQUESTED to distinguish it from the state
in which we lost focus.
#cherrypick
PiperOrigin-RevId: 644416586
(cherry picked from commit 66c19390e2b31106a2a467366f7945c37a273fc6)
There are a lot of tests for AudioFocusManager in isolation,
but almost none for the handling in ExoPlayer.
Add test coverage for all the common cases, including some
currently broken behavior that is indicated by TODOs.
PiperOrigin-RevId: 644319251
(cherry picked from commit e20e94fde277a8e9e9a09e502a5760772e9eb006)
The workaround check is now part of CTS and we should be able
to rely on the PerformancePoints values (or at least can be sure
that they cover all CDD requirements)
#minor-release
PiperOrigin-RevId: 619201331
(cherry picked from commit 737bf08314a5d1c27762aa1c501d3e132a138e20)
Also remove an unused `androidxTestServicesStorageVersion` version.
Issue: androidx/media#1216
PiperOrigin-RevId: 618990983
(cherry picked from commit 6cb25119fb0b20e3fbc80158b9ebcea55d407780)
This ensures MediaMetadata with just non-null extras is not
considered equal to MediaMetadata.EMPTY. This makes sure the
contents are bundled when a controller sets the extras in a
new MediaItem
Issue: androidx/media#1176
PiperOrigin-RevId: 618876642
(cherry picked from commit ab0391167c867d2607183cda0b03c762dd5e5c0e)
These TODOs precede <unknown commit> when the group was set in the top-level
`build.gradle` file.
Issue: androidx/media#1215
PiperOrigin-RevId: 618835040
(cherry picked from commit fd268eed46baefa59901035470246d07e6048062)
The original change did not set the color info in the codec
for standard SDR infos. This was meant to help with consistency
to avoid a situation where the information is partially set and
later the bitstream provides slightly different values (all in
standard SDR though).
We can revert this part because the bitstream may change anyway
and the decoder needs to handle this internally. And more
importantly, it also avoids removing this information when encoding
the format again in Transformer.
PiperOrigin-RevId: 617582066
(cherry picked from commit ed505df2cac9a243a29f4d1e170860fb3c66d4aa)
Some media can read color info values from the bitstream
and may partially set some of the SDR default values in
Format.ColorInfo. Setting these default values for SDR can
confuse some codecs and may also prevent adaptive ABR
switches if not all ColorInfo values are set in exactly the
same way.
We can avoid any influence of HDR color info handling by
disabling setting the color info MediaFormat keys for SDR
video and also avoid codec reset at format changes if both
formats are SDR with slightly different ColorInfo settings.
To identify "SDR" ColorInfo instances, we need to do some
fuzzy matching as many of the default values are assumed to
match the SDR profile even if not set.
Issue: androidx/media#1158
PiperOrigin-RevId: 617473937
(cherry picked from commit 3a7d31a599fdb9716c95d5cbbb599259bb0464f4)
It's a bit arguable whether the `Subtitle` implementation supports
zero-duration events, since `getEventTimeCount` is documented as
effectively "the number of times the cues returns by `getCues(long)`
changes", and zero-duration events violate that. However, the current
`WebvttSubtitle` impl **does** produce zero-duration events, so it
seems safer to handle them gracefully here and then, as a possible
follow-up, fix the `WebvttSubtitle` impl (or remove it completely).
Issue: androidx/media#1177
PiperOrigin-RevId: 616095798
(cherry picked from commit e9ed874e51f20460c5a73f811a7cf2c61b7530ec)
This ensures these modules are only configured when directly working
on the library, rather than when depending on it locally. These modules
only contain tests, they shouldn't be depended on by any apps (and are
not published via Maven).
PiperOrigin-RevId: 615004801
(cherry picked from commit c41213c273cc526aaccde5fa99336f1fc623e8ef)
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. Currently, when a player is set to pause, it stops all renderers that are `STATE_STARTED`. When a player is set to play, it starts all renderers that are enabled. This would include renderers that were enabled early for the subsequent media item. The solution is to only start renderers that are enabled by the current playing period.
Issue: androidx/media#1017
PiperOrigin-RevId: 614734437
(cherry picked from commit 8b219b0ae69f80764183b680b44a8b0d6b03ed56)
This should already be the default, but some devices seem
to not adhere to this contract and assume the default is unset.
Issue: androidx/media#1169
PiperOrigin-RevId: 614697283
(cherry picked from commit cbed80ecf36d3ff49ec9d2806670f1fda3551aba)
Some devices just don't work very well with the synchronous
model, but are currently still excluded from our approximate
API 31 check. This change allows to include additional devices
or device groups by passing in the Context to the default
adapter.
It also adopts the workaround added in ebceee08c6
for Fire TV Smart devices that exhibit this issue.
PiperOrigin-RevId: 614642545
(cherry picked from commit e4a55844d0c99cdfefb37259a8c3bbe0fb9ddc74)
Some FireOS6 devices ask to force the external surround global
flag and ignore any signals from the HDMI connection.
This is the equivalent change of e341944d1e
PiperOrigin-RevId: 614634499
(cherry picked from commit 410c0492cc9c7888df7a5283c5ebf8d99bf9c0cc)
Using the more accurate check available on later API versions
first is likely better than falling back to a fallback solution
from older API versions.
PiperOrigin-RevId: 614612628
(cherry picked from commit 18cbbf3850df841f0396abcd2c7e5e8196e85bac)
Document that assoicated effects are ignored if these setters are set
PiperOrigin-RevId: 613518167
(cherry picked from commit 5b7774fcaf1498b7c72448fcd0497fcc44efd7cc)
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. When a renderer is being enabled and the player is 'playing', that renderer is also started. When playing a mixed playlist of images and content with audio & video, the player may skip some image items because the early-starting of the audio renderer causes a clock update.
A solution is to only start the "early-enabled" renderers at the point of media transition and add a condition on DefaultMediaClock to use the standalone clock when reading-ahead and the renderer clock source is not in a started state.
Issue: androidx/media#1017
PiperOrigin-RevId: 613231227
(cherry picked from commit 638b2a3c86f7362041b09faed7c3c09609e29118)
The removed check searched for a player command inside a list of
session commands, which is not allowed by the IntDef definition
and only worked because both types map to a Java int.
PiperOrigin-RevId: 612758442
(cherry picked from commit c79ac5ba218c685ea6cf284a634899c8327785c8)
When the controller replaces the current item, the masking position will be changed to the default position of the new item for a short while, before the correct position comes from the session. This will interrupt the current position fetched from the controller when the playback doesn't interrupted by the item replacing.
Issue: androidx/media#951
PiperOrigin-RevId: 611417539
(cherry picked from commit 1bdc58de0be73c14e1b5fdffab64d69da470ffb3)
This change aims to prioritise tracks that have a 'smooth enough for
video' frame rate, without always selecting the track with the highest
frame rate.
In particular MP4 files extracted from motion photos sometimes have two
HEVC tracks, with the higher-res one having a very low frame rate (not
intended for use in video playback). Before this change
`DefaultTrackSelector` would pick the low-fps, high-res track.
This change adds a somewhat arbitrary 10fps threshold for "smooth video
playback", meaning any tracks above this threshold are selected in
preference to tracks below it. Within the tracks above the threshold
other attributes are used to select the preferred track. We deliberately
don't pick the highest-fps track (over pixel count and bitrate), because
most users would prefer to see a 30fps 4k track over a 60fps 720p track.
This change also includes a test MP4 file, extracted from the existing
`jpeg/pixel-motion-photo-2-hevc-tracks.jpg` file by logging
`mp4StartPosition` in
[`MotionPhotoDescription.getMotionPhotoMetadata`](b930b40a16/libraries/extractor/src/main/java/androidx/media3/extractor/jpeg/MotionPhotoDescription.java (L123))
and then using `dd`:
```
mp4StartPosition=2603594
$ dd if=jpeg/pixel-motion-photo-2-hevc-tracks.jpg \
of=mp4/pixel-motion-photo-2-hevc-tracks.mp4 \
bs=1 \
skip=2603594
```
----
This solution is in addition to the `JpegMotionPhotoExtractor` change
made specifically for these two-track motion photos in
5266c71b3a.
We will keep both changes, even though that change is not strictly
needed after this one, because adding the role flags helps to
communicate more clearly the intended usage of these tracks. This
change to consider FPS seems like a generally useful improvement to
`DefaultTrackSelector`, since it seems unlikely we would prefer a 5fps
video track over a 30fps one.
Issue: androidx/media#1051
PiperOrigin-RevId: 611015459
(cherry picked from commit c7e00b12b4b3eff6c478d2f4afc7a48bb05d6e7d)
Some devices supporting Performance Points for decoder coverage are missing coverage over the CDD requirements for H264. For these cases ExoPlayer should fall back to legacy resolution and frame rate support checks. If there is a stream evaluated as a PerformancePointCoverageResult of COVERAGE_RESULT_NO, then ExoPlayer checks for coverage of the 720p H264 CDD requirement.
Issue: google/ExoPlayer#10898
Issue: androidx/media#693
Issue: androidx/media#966
PiperOrigin-RevId: 609740128
(cherry picked from commit 23a301fc5d3d14593f32c04634d7267c8a86a1cd)
This change makes ExoPlayerImplInternal.releaseInternal() unblock the
app thread if a runtime exception is thrown while releasing components
from the playback thread.
Before this change, if a runtime exception occurred during releasing
components in the playback thread, ExoPlayer.release() would wait for
`releaseTimeoutMs` and then raise a player error. With this change,
the player error is reported only when the playback thread is blocked
but if there is a runtime exception, the application thread is
unblocked.
The impact of this change is potentially fewer ANRs on
ExoPlayer.release() at the expense of less error reporting.
PiperOrigin-RevId: 609702549
(cherry picked from commit 0480eff6a15152ae965129e5357d70507c792658)
We forgot to add it when we added AudioSink.release(). The commit
includes a test that ensures ForwardingAudioSink overrides all the
methods defined in the AudioSink interface.
PiperOrigin-RevId: 609402258
(cherry picked from commit 440d2ab162604a5555ebdaa6d71b2f82120b1e09)
If the reading period has already advanced and a track reselection procs that only affects the reading period media, then ExoPlayer may try and apply the reading period's track selection incorrectly unto the playing period. ExoPlayer should apply the playing period's track selection to the playing period instead.
PiperOrigin-RevId: 609375077
(cherry picked from commit 41929246222e9fdb9aa552db526c1b41d26bdb90)
If render error occurs due to AudioTrack initialization failure in offload mode, then ExoPlayer should allow retry as subsequent attempt will be with DefaultAudioSink disabling offload.
PiperOrigin-RevId: 609304897
(cherry picked from commit 9046f2edb62f3dd9bc735405d2a58a98abd87064)
The `PreloadMediaPeriod.selectTracksForPreloading` can be called for multiple times at the preloading stage (before the period is being played). For example, when the period resumes preloading. This change fix the assertion failure in `ProgressiveMediaPeriod.selectTracks` caused by the wrong implementation of `PreloadMediaPeriod.selectTracksForPreloading` when it is trying to retain the previously preloaded streams.
Also the `TrackSelectorResult` parameter is changed to a list of `ExoTrackSelection`. We should compare the selections only rather than considering the `RendererConfiguration` in the `TrackSelectorResult` to decide whether to retain the streams, as for preloading case the renderers haven't consumed the samples yet.
PiperOrigin-RevId: 609126868
(cherry picked from commit d952a0621471308b0fb545ce7da5067cead0a0df)
Fixes an issue caused by no support for negative audio PTS and edit lists
in FrameworkMuxer, Android versions before 11
PiperOrigin-RevId: 607690507
(cherry picked from commit e43f96687c3c6d13907da1a5c53e90ffa57d624c)
The behaviour and docs of `playUntilPosition` were changed in
00c7a9bcbb.
This change also affects `playUntilStartOfMediaItem` (since it delegates
to `playUntilPosition`), so the same doc change should also be made
here.
#minor-release
PiperOrigin-RevId: 607364897
(cherry picked from commit fa3212e73e5b5f958e6b0aace459d50232e56de5)
The original change missed copying the newly added flag in `buildUpon()`, which
caused some test flakes.
PiperOrigin-RevId: 607232373
(cherry picked from commit ae0da442b1f29b9c8c2b64a99d640fa5b2ce5e0f)
VideoFrameProcessor requires every input frame to be registered before they are
rendered to its input Surface. This CL adds the option to register the input
frame only once. This is useful for camera inputs where not all input frames
come with changing FrameInfo.
PiperOrigin-RevId: 606294894
(cherry picked from commit 216f3fedb857d9a6e0bf846070784c1cc5b7e705)
Previously, we missed the BT2020->BT709 color-space conversion.
A user-visible impact of this is that red and green channels used to be
undersaturated, but now are more correctly saturated.
PiperOrigin-RevId: 605411926
(cherry picked from commit a5e47982f4d98e02469f0f0240b5ee1469bff015)
Change the file extension retrieval back to how it was before 5488d33da8 to reduce the change of false negatives in `isImage()`
PiperOrigin-RevId: 605281186
(cherry picked from commit 4d29d8f012410bdacd5fb3c45c5f082a328f4028)
If nullness should result in an exception, we should throw as soon as possible,
so that stack traces are easier to follow.
Did a quick scan of media3.effect+transformer and this covers all uses of
peek that immediately throw there.
PiperOrigin-RevId: 603393366
(cherry picked from commit dd7846ee1cbeb48ddb5495858a71517858df0554)
VideoFrameProcessor treats BT601 and BT709 as roughly equivalent now, so we
shouldn't be making checks that assume BT709 <-> requires tone-mapping.
Also, the color transfer is a better determinant for tone-mapping than color range, so use just the transfer to determine if tone-mapping is required.
PiperOrigin-RevId: 603083100
(cherry picked from commit cebe6d8ba573c2a636426b18c01837fbec6b00aa)
`Uri.appendQueryParameter` is documented to encode its arguments, so
calling `Uri.encode` beforehand results in double-encoding.
Issue: androidx/media#1075
#minor-release
PiperOrigin-RevId: 604995441
(cherry picked from commit 7ebfed505c5ac42cb6e614a3dd9b7755af3e92b2)
The track id must be the index in the list of published tracks
as it's used as such elsewhere. This is currently not true if we
skip an empty track as all subsequent tracks get a wrong or even
invalid id.
#minor-release
PiperOrigin-RevId: 604929178
(cherry picked from commit 5f9c96ab53c571af90457e9f22bac1fe32209bd5)
Relax the regex to only check for hyphen which is required by the specification.
Issue: androidx/media#1028
#minor-release
PiperOrigin-RevId: 604719300
(cherry picked from commit 138532e3fd158e60d50aa85cc1ac2effa388f4eb)
The current implementation of `JpegMotionPhotoExtractor.sniff` returns
`true` for any image with Exif data (not just motion photos). Improving
this is tracked by b/324033919. In the meantime, when we 'extract' a
non-motion photo with `JpegMotionPhotoExtractor`, the result is
currently a single empty image track and no video track (since there's
no video, since this isn't a motion photo). This 'empty' image track
is usually used to transmit metadata about the video parts of the
image file (in the form of `MotionPhotoMetadata`), but this metadata is
also (understandably) absent for non-motion photos. Therefore there's
no need to emit this image track at all, and it's clearer to emit no
tracks at all when extracting a non-motion photo using
`JpegMotionPhotoExtractor`.
This change also removes a `TODO` that is misplaced, since there's no
image bytes being emitted here (and never was).
PiperOrigin-RevId: 604688053
(cherry picked from commit 7ae3d69e001d0a138f3ebe406b050bc06bd24724)
These are often the same for image tracks, since we usually drop the
whole image file (both the container and actual encoded image bytes)
into a single sample, but there are cases where we emit a track with
`containerMimeType=image/jpeg` but **no** samples (from
`JpegMotionPhotoExtractor`, to carry some metadata about the image +
video byte offsets).
It's therefore more correct to implement the `supportsFormat` check
based on `sampleMimeType`, so that these 'empty' image tracks are not
considered 'supported' by `ImageRenderer`.
#minor-release
PiperOrigin-RevId: 604672331
(cherry picked from commit eabba49610b8f93ed92450baf55da01e5a8b23b2)
This was already done for the TrackGroup ids in <unknown commit>,
but in some scenarios only the Format instances are known and
it's helpful to be able to identify where they came from.
Issue: androidx/media#883
#minor-release
PiperOrigin-RevId: 604644039
(cherry picked from commit f8f6d80477241a1f2a65e548855f94eeb5389c96)
This ensures RequestMetadata with just non-null extras is not
considered equal to RequestMetadata.EMPTY. This makes sure the
contents are bundled when a controller sets the extras in a
new MediaItem.
PiperOrigin-RevId: 604632788
(cherry picked from commit 766a15a51e5e09e6e5f5df5d53bf603e167af3d3)
Add a test for this consistency in `CompositeSequenceableLoaderTest`,
and also make the
`CompositeSequenceableLoaderTest.FakeSequenceableLoader` implementation
more realistic.
#minor-release
PiperOrigin-RevId: 604604103
(cherry picked from commit db74bb9609a59b70a6a477f4abb2af61bba19aa2)
Since Kotlin 2.0 the compiler became better at detecting incorrect
annotation applications. The @OptIn annotation can't be applied to an
expression, so when compiling with Kotlin 2.0 it results in an error.
PiperOrigin-RevId: 604596657
(cherry picked from commit 718cf1299b805339b605bf268fce0ad9158c44f5)
This reverses 27caeb8038
Due to the re-ordering of packets done in `CeaDecoder`, there's no way
to use the current implementation to correctly parse these subtitle
formats during extraction (the `SubtitleParser` interface), so we have
to keep the `SubtitleDecoder` implementations.
#minor-release
PiperOrigin-RevId: 604594837
(cherry picked from commit 25498b151ba298ef359f245e2ed80718b4adf556)
This reverses 94e45eb4ad
Due to the re-ordering of packets done in `CeaDecoder`, there's no way
to use the current implementation to correctly parse these subtitle
formats during extraction (the `SubtitleParser` interface), so we have
to keep the `SubtitleDecoder` implementations.
#minor-release
PiperOrigin-RevId: 604350951
(cherry picked from commit 51b4fa2cc83b60fcb313fd0e6afd2d45fe64e535)
The new test introduced in 45bd5c6f0a is flaky because we only
wait until the media is fully buffered. However, we can't fully
control how much of this data is initially read by the Robolectric
codec and thus the output dump files (containing these codec
interactions) are flaky.
This can be fixed by fully playing the media once and then seeking
back instead.
#minor-release
PiperOrigin-RevId: 603324068
(cherry picked from commit e3e57c9b9943fd160105001b2e8e26782173843e)
If seeking between last image sample and end of the file where the current stream is not final, then EoS sample will not be provided to `ImageRenderer`. ImageRenderer must still produce the last image sample.
PiperOrigin-RevId: 603312090
(cherry picked from commit 62c7ee0fb0f4def17a18233c0fd40958d646c82b)
This happens when using `ExoPlayer.setVideoEffects()`.
This CL also fixes the first frame not rendered problem, originally solved in
7e65cce967, but rolled back in 5056dfaa2b because the solution introduces
the flash that is observed in b/292111083.
Before media3 1.1 release, the output size of `VideoFrameProcessor` is not
reported to the app. This was changed later after introducing
`CompositingVideoSinkProvider`, where the video size after processing **is**
reported to the app. After this CL, the size is again, not reported.
PiperOrigin-RevId: 602345087
(cherry picked from commit dcae49a561d3dd0a67a44a913c063b0232bbc445)
The updated algorithm has two main improvements:
- The silence padding is not constant but a ratio of the original
silence (up to a defined max) to more naturally represent the
original gaps.
- The silence is not instantly going to zero, but uses a ramp down
and up for a smooth volume transition and also retains a small
percentage of the original noise for more natural "silences" that
still contain some background noise.
#minor-release
Issue: google/ExoPlayer#7423
PiperOrigin-RevId: 602322442
(cherry picked from commit bb533332f4b6f46ac9d5ca17cb7943bd1bdb7dd2)
The return value of onConfigure must not be ignored as it specifies
the output format of the processor, which may be different from the
input format.
#minor-release
PiperOrigin-RevId: 601799440
(cherry picked from commit 2fc5590e7aa5890f22d020778f924e1586a3f3ba)
Many usages are needed to support other deprecations and some
can be replaced by the recommended direct alternative.
Also replace links to deprecated/redirected dev site
PiperOrigin-RevId: 601795998
(cherry picked from commit ed5b7004b435f71c5a37f5db12c3641fbba9be48)
It's likely that we will merge these back into their `XXXDecoder`
implementations, but this smaller change allows us to avoid including
these public symbols in the upcoming release.
#minor-release
PiperOrigin-RevId: 601432629
(cherry picked from commit 12157a6b1aba2c59c54e6b7d34bad396008b5f29)
This method works by reflectively loading classes from the `lib-effect`
module, in order to avoid a hard dependency on this module for ExoPlayer
users that don't want video effect functionality. This change ensures
that a failure to load the necessary classes fails immediately, instead
of on a later thread inside `MediaCodecVideoRenderer` when the
reflection currently happens.
Also update the javadoc to make the dependency requirement clear.
#minor-release
PiperOrigin-RevId: 601387957
(cherry picked from commit a6812156e6ea5ea2dc45d222f402065c0da46b62)
DASH: `DashMediaSource.Factory` would only propagate it to `DashChunkSource.Factory` -> `BundledChunkExtractor.Factory`
SS: `SSMediaSource.Factory` -> `SsChunkSource.Factory`
HLS: `HlsMediaSource.Factory` -> `HlsExtractorFactory`
Remove nullability of SubtitleParser.Factory across the stack
#minor-release
PiperOrigin-RevId: 601250013
(cherry picked from commit f103a2dcf565a311b94171e5714e4ee8ad8c5f65)
The `SubtitleParser.Factory` is no longer @Nullable and the experimenting toggle is used to enable/disable the use of this factory for subtitle parsing during extraction.
The three places that will hold the "truth" for the `SubtitleParser.Factory` are: BundledChunkExtractor.Factory, SsChunkSource.Factory, DefaultHlsExtractorFactory
DASH: `DashMediaSource.Factory` would only propagate it to `DashChunkSource.Factory` -> `BundledChunkExtractor.Factory`
SS: `SSMediaSource.Factory` -> `SsChunkSource.Factory`
HLS: `HlsMediaSource.Factory` -> `HlsExtractorFactory`
#minor-release
PiperOrigin-RevId: 601151615
(cherry picked from commit 4d7b23f0d117a67df33f5cab25d5971a72dc8017)
As per MP4 spec ISO 14496-12: 8.7.5 Chunk Offset Box, Both "stco" and
"co64" can be used to store chunk offsets. While "stco" supports 32-bit
offsets, "co64" supports 64-bit offsets.
In non fragmented MP4, the mdat box can be extremely large, hence muxer
uses "co64" box.
But for fragmented MP4, muxer does not write any data in this chunk offset
box (present in "moov" box) because all sample related info is present in
"moof" box.
Technically, "co64" box should also work in fragmented MP4because
its empty only but QuickTime player fails to play video if "co64"
box is present in fragmented MP4 output file.
Testing: Verified that QuickTime player does not play video when "co64"
box is present but is able to play when "stco" box is present.
#minor-release
PiperOrigin-RevId: 601147046
(cherry picked from commit 0acf6902e57678dc9e6ea8de3a4b3b88b9ec0519)
Those classes only needed to have access to a `SubtitleParser.Factory` to get a potentially updated `Format` for TrackGroups. The `SubtitleParser.Factory` was only used to check the support for the `mimeType` and getting some cue-related behaviour.
This introduced complexity in a way that both Periods and Extractors needed to have the same `SubtitleParser.Factory` in their individual stacks. To ensure that the sample queue would get the same transcoded/original format.
Instead, now we expose `getOutputTextFormat` methods on `ChunkExtractor.Factory`, `SsChunkSource.Factory` and `HlsExtractorFactory`. Those are the dependencies that Hls/Ss/DashMediaPeriod can make use of to delegate the format-updating logic to.
#minor-release
PiperOrigin-RevId: 601130714
(cherry picked from commit 966b7108976706c1b0a1a8a2b82ae8daa747bda3)
This fix makes output playable on VLC player.
The output does not play on QuickTime player which is being fixed in
a separate CL.
#minor-release
PiperOrigin-RevId: 601118813
(cherry picked from commit 806f90922b0d327f1f85e677ac2d9555415d60a4)
Fix modeled after OutputStreamInfo usage for stream offset in `MediaCodecRenderer`
PiperOrigin-RevId: 601109900
(cherry picked from commit 688622eb47ac707affa824d3d68f44755f947380)
Allow setAdditionalRotationDegrees to be called with same rotation after tracks added. This is needed for processes that mux files partially trim optimization so they don't error out after hitting the check state
Manually tested to ensure trim optimization succeeds, automated test added here as well
PiperOrigin-RevId: 601081778
(cherry picked from commit b94c7d08c13210d16725b774f2eda8b1b808e2ab)
These symbols in `lib-effect` are referenced via reflection from
`CompositingVideoSinkProvider` in `lib-exoplayer` in order to avoid
a hard dependency from `lib-exoplayer` to `lib-effect`. Without this
keep rule, the symbols can get renamed by R8 resulting in the
invocations failing.
#minor-release
PiperOrigin-RevId: 601074636
(cherry picked from commit e5621cc70960bf76c5651f6f368f78aeacac82b3)
Populate both `artworkUri` and `artworkData` in
`MediaMetadata.Builder.populate(MediaMetadata)` when at least one of them is non-null.
Issue: androidx/media#964
PiperOrigin-RevId: 600826103
(cherry picked from commit 35ac46b92e627c16245d8cdec6fd4260b4c0f8ac)
Earlier implementation processed each track (pending sample's buffer info)
individually when writing their corresponding "traf" box in a fragment.
The change involves processing all tracks before start writing "traf" boxes.
#minor-release
PiperOrigin-RevId: 600811093
(cherry picked from commit 4c1581a17542f56db9fd85e0c7a6894aef57be52)
This method is needed for some system apps to override the
output switcher when MediaRouter2 can't be used.
PiperOrigin-RevId: 600807119
(cherry picked from commit b64d75467010b727d3e201120643becab73fe491)
The default notification provider was still using the legacy
compat MediaStyle instead of our own Media3 one. They are fully
equivalent in their implementation and API and can be swapped out
easily.
PiperOrigin-RevId: 600797920
(cherry picked from commit 9448f939f432d17337e2ecba3a14caa0c322c4eb)
We keep the previous parsing-during-rendering tests, even though they
can be a bit flaky, because this is an important regression test. The
regression risk is lower for this instrumentation test compared to
robolectric tests with different `ShadowLooper` behaviour.
#minor-release
PiperOrigin-RevId: 600781035
(cherry picked from commit a53f3451ddef819c5b0fb5ff1e9952a98a56bfc3)
Due to poor isolation between the session tests, in particular the
static state in `MediaSession.SESSION_ID_TO_SESSION_MAP`, an unreleased
session at the end of one test can cause subsequent tests to fail with
obscure errors like `Session ID must be unique`.
#minor-release
PiperOrigin-RevId: 600737697
(cherry picked from commit ca61ac6ca35427a697a6645c90cc8e12889c78f7)
It's useful for development and debugging to select a local image
or audio (only) file as well as a video file in the transformer demo
app.
I tested manually that you can select a local video, audio and image
but not e.g. a pdf with the main "choose local file" picker and only
an image with the choose local image picker for the bitmap overlay
demo.
PiperOrigin-RevId: 600722622
(cherry picked from commit 94ce356bc1bea34edeba02181f3793ec7da7c2f4)
We can just continue to assume that we don't know the current device.
This case happens on the latest Robolectric release where this method
call isn't implemented yet. As we not generally assume that the
method can throw, this workaround can be removed once Robolectric
is updated again.
#minor-release
PiperOrigin-RevId: 600426851
(cherry picked from commit 81615dd5b56dddc008401a7a8513baf5336c01b6)
Add protected method in SimpleBasePlayer for thread verification to help
subclasses verify thread access for additional methods they define and
still report the same message to the user.
Also, remove the DAC link pointing to the ExoPlayer-specific
documentation from the exception message. Users who extend
SimpleBasePlayer have access to the class' javadoc.
PiperOrigin-RevId: 600426692
(cherry picked from commit 9e9c3cbe5e1576e89ef1f5492b2c14865bc1ddbe)
[Android best
practices](https://developer.android.com/media/optimize/sharing#android_8_81_and_9)
recommend disabling B-frames on API 27, but some devices output B-frames anyway
when H.264/AVC High profile is selected. Add a workaround to force these
devices not to use high profile, to prevent B-frames being output.
`MediaMuxer` likely handles B-frames on these specific devices, but this change
allows the migration to default to in-app muxing to take place without
introducing errors, and it's a temporary workaround until B-frames are properly
supported in the in-app muxer.
PiperOrigin-RevId: 600422238
(cherry picked from commit 60295218985952a627764e1c3a6fce919f52ed4c)
Some player method calls sent from MediaControllers accept int
or float values with a very clear API contract that disallows
some values. Filtering by these values early avoids calling a
Player implementation with invalid values.
PiperOrigin-RevId: 600413993
(cherry picked from commit c64b271f077939abcd33353efb50f1b0b2ca7588)
This optimization always reports buffers as 'skipped' (i.e. deliberately
not shown), which makes sense for the target case of high FPS content on
a lower refresh rate screen, when lots of the frames will **never** be
shown.
However the optimization also results in reporting buffers as 'skipped'
when decoding is a bit slow, resulting in a frame being released one
vsync late, which then means we have two frames to release in the same
vsync (when the previous vsync was empty). In this case, it would be
more correct to report this as a 'dropped' frame (since it was due to
slow decoding).
Until we can change the logic to distinguish these cases and report them
separately, this CL disables the optimization completely in GTS tests.
This is needed because we often assert there were zero skipped frames,
so slight decoding slowness can cause spurious/flaky test failures (our
threshold for dropped frames is non-zero).
#minor-release
PiperOrigin-RevId: 600406443
(cherry picked from commit 999e154b2aa8cd6845cdbad2a708280f0069dac7)
This device doesn't seem to be capable of simultaneous encode/decode at this
resolution. We don't have a good way to check the capability (we are already
checking separate decode/encode capability) so just skip this test to save time
triaging its failures.
PiperOrigin-RevId: 600399564
(cherry picked from commit e82393ed4108cb34e7b655bad8d098ddafd7652b)
From API 23, we may have a preferred device that is most likely used
as the output device.
From API 24, the AudioTrack tells us the actual routed device that is
used for output and we can listen to changes happening mid-playback.
From API 33, we can directly query the default device that will
be used for audio output for the current attributes.
If the routed device is known by any of the methods above, we can add
more targeted checks in methods like isBluetoothConnected to avoid
iterating over all devices that are not relevant.
The knowledge about the routed device will also be useful to check
advanced output capabilities in the future (e.g. for lossless
playback)
PiperOrigin-RevId: 600384923
(cherry picked from commit b1c954fa844e25f2c65f9f3865dbb62afaee592d)
This allows us to inject a videoFrameProcessorFactory into
MediaCodecVideoRenderer, without issues about creating the
VideoFrameReleaseControl in the MediaCodecVideoRenderer.
Unfortunately, this does result in more complex CVSP state, where
VideoFrameReleaseControl is no longer final, may be null, and may potentially
change. However, this tries to be careful with assertions to guarantee good
state, and is cleaner than modifying the long-standing MediaCodecVideoRenderer
interface.
Tested that this works on the ExoPlayer demo with setVideoEffects applied, and
using a playlist with SDR->HDR and HDR->SDR items.
PiperOrigin-RevId: 599823412
(cherry picked from commit cb0f5a7fffdf519f5888255be7a5f3aefe5680a7)
These methods sound similar, but have different behaviour. This change
tries to make the distinction clearer, and sign-post from one to the
other.
#minor-release
Issue: androidx/media#910
PiperOrigin-RevId: 595701540
(cherry picked from commit 95e742948ca0d7490cb016c1026827b8369fc8ab)
When the media notification controller is requested for a session
with `getConnectedControllerForSession` and the `Future` is not null
but not yet completed, the `Future` was returned either way. This was
reported as creating a race condition between the notification
being requested for update the very first time, and the media
notification controller having completed connecting to the session.
Returning null from `getConnectedControllerForSession` when the
`Future` is available but not yet done fixes the problem. This is
safe because for the case when a notification update is dropped,
the media notification controller will trigger the update as soon
as the connection completes.
Issue: androidx/media#917
#minor-release
PiperOrigin-RevId: 595699929
(cherry picked from commit 5c50b27e8fce878bc24852498ae42298613d5ad2)
When the 'when' timer of the notification is disabled
`DefaultMediaNotificationProvider` may set `C.TIME_UNSET`
as the time. Users reported problems on some devices with
this and the docs ask for an event time that probably
shouldn't be a negative number.
This change sets `0L` instead of `C.TIME_UNSET` when the
timer is disabled.
Issue: androidx/media#903
#minor-release
PiperOrigin-RevId: 594451074
(cherry picked from commit 426bc940905237accf902f42d63b3777c11ff72e)
While investigating Issue: androidx/media#887 I naively assumed the CEA-608
captions were in a TS file, but they're actually in an MP4 (which is
possibly obvious given DASH only supports MP4). This change includes
container info in the `EventLogger` `tracks` output.
PiperOrigin-RevId: 592192752
(cherry picked from commit 6853ffccae53b0f01c8a818d64ed8dc18d1c60b0)
When track is changed during playback, `playbackPositionUs` may be in middle of a chunk and `loadPositionUs` should be the start of that chunk. In this situation `loadPositionUs` can be less than the current `playbackPositionUs`, resulting into negative `bufferedDurationUs`. It translates to having no buffer and hence we should send `0` for `bufferedDurationUs` when creating new instances of `CmcdData.Factory`.
Issue: androidx/media#888
#minor-release
PiperOrigin-RevId: 591099785
(cherry picked from commit 7f6596bab217847617947b61ded64b7aba58a194)
The timestamp adjuster also estimates the number of wraparounds
of the 90Khz TS timestamp. It does that by assuming that a new
timestamp is always close to the previous one (in either direction).
This logic doesn't always work for duration estimates because the
timestamp at the end of the media is not close to the one at the
beginning and it may also never be less than the one at the beginning.
This can be fixed by introducing a new estimation model that assumes
the new timestamp is strictly greater than the previous one without
making the assumption that it has to be close to it.
Issue: androidx/media#855
#minor-release
PiperOrigin-RevId: 590936953
(cherry picked from commit 01578780a6bbd69d206f4f7e815c9f5e9d3c5fa4)
When broadcasting a notifyChildrenChanged event, the task for legacy
controllers was sent to the broadcasting callback. This would
technically work, but because the subscription list is maintained
with specific controllers, the broadcast controller isn't subscribed
and hence the call wasn't executed.
This change calls the overloaded method for a specific controller
for each connected controller. Making sure (only) subscribed
controllers are notified.
Issue: androidx/media#644
PiperOrigin-RevId: 590904037
(cherry picked from commit 4974f960e7b8a34a37c2206b87973339c0e81cef)
The MP4 data in JPEG motion photos can contain multiple `video/hevc` tracks, but only the first is at a playable frame rate while the others are low-fps, high-res tracks designed for specific use-cases (not direct video playback).
ExoPlayer currently selects the unplayable track by default, because it
has a higher resolution. This change introduces a flag to
`Mp4Extractor` that results in the first video track being marked as
`ROLE_FLAG_MAIN`, and all subsequent video tracks `ROLE_FLAG_ALTERNATE`
- this then results in the playable lower-res track being selected by
default.
PiperOrigin-RevId: 589832072
(cherry picked from commit 5266c71b3a01eda5f3f6ef9449e46887a7f9f4d6)
This image has two video tracks in the MP4 data, one is a 'real' video
which we want to play by default, and the other is a low-fps video track
which isn't intended to be directly played, it's encoded in HEVC for
compression and decoding efficiency.
This test demonstrates ExoPlayer's current behaviour default extraction
and playback, which results in selecting the high-res, low-fps track
(actually single sample in this example), instead of playing the actual
video.
PiperOrigin-RevId: 588068908
(cherry picked from commit 6360082b879e9cba394f169b7b50c8c500173027)
As Opus decoders skip some bytes prior to playback during a seek, the renderer for bypass playback should send samples to the decoder even if they would be decode-only. However, the renderer should not send samples with time preceding that range. This change adds that constraint.
#minor-release
PiperOrigin-RevId: 588014983
(cherry picked from commit d1e38abf93353af1bc3fb2d9a0dfbac01e387f3e)
Both the extension OPUS decoder and the OMX/C2 MediaCodec
implementations for OPUS and VORBIS decode into the channel
layout defined by VORBIS. See
https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-140001.2.3
While this is technically correct for a stand-alone OPUS or VORBIS
decoder, it doesn't match the channel layout expected by Android.
See https://developer.android.com/reference/android/media/AudioFormat#channelMask
The fix is to apply the channel mapping after decoding if needed.
Also add e2e tests with audio dumps for the extension renderer,
including a new 5.1 channel test file.
Issue: google/ExoPlayer#8396
PiperOrigin-RevId: 588004832
(cherry picked from commit b1541b096f9dc4d1f9ca71b6743c836f6bd4de89)
`mediaCrypto` is initialized before `codec` in
`maybeInitCodecOrBypass`. Before this change, it was possible for
`maybeInitCodecOrBypass` to complete with `mediaCrypto != null` and
`codec == null`, in particular if it was run as part of clearing the
player surface (since in that case, no video codec is initialized).
This inconsistent state then causes issues during a later invocation of
`maybeInitCodecOrBypass`, when `mediaCrypto` is still non-null, and
`mediaCryptoRequiresSecureDecoder = true`, but the
content has been changed to unencrypted with no associated DRM session.
This results in a playback error, because a secure decoder is
initialized but there's no DRM session available to work with it.
This change ensures that when `maybeInitCodecOrBypass` completes,
either both `mediaCrypto != null` and `codec != null` (i.e. codec
initialization was completed) or `mediaCrypto == null` and
`codec == null` (i.e. codec initialization was not completed). We also
ensure that when nulling out `mediaCrypto` we also set
`maybeInitCodecOrBypass = false`. A later change should be able to
demote `maybeInitCodecOrBypass` from a field to a local in order to
remove any risk of that part of state becoming out of sync. This
resolves the issue, because during the second invocation of
`maybeInitCodecOrBypass` an insecure decoder is now (correctly)
initialized and the unencrypted content is successfully played.
#minor-release
PiperOrigin-RevId: 587713911
(cherry picked from commit 913f6da08305b36798c84d5134d19b2d11affdd2)
`fromBundle` doesn't distinguish between `FIELD_BITMAP` and `FIELD_TEXT`
being present with a null value, or being absent, so we might as well
avoid including them when the value is null.
I've separated this from a later change to add
`Cue.toSerializableBundle` which will also skip setting a bitmap value
into the `Bundle` if `this.bitmap == null`. This is partly because it
results in changes to a lot of extractor test dump files, and it's
easier to review that as a separate change.
PiperOrigin-RevId: 586626141
(cherry picked from commit 28c210686f54d52610fe2f9560ad1dfa73753ccd)
Add an check when loading progressive media in case the load
is canceled. If the player is released very early, the progressive
media period may carry on with the initial loading unnecessarily.
PiperOrigin-RevId: 586288385
(cherry picked from commit 3d1d8f4439f194029d1522137b7f428e96bf61b3)
The decoder and encoder won't accept high values for frame rate, so avoid
setting the key when configuring the decoder, and set a default value for the
encoder (where the key is required).
Also skip SSIM calculation for 4k, where the device lacks concurrent decoding
support.
PiperOrigin-RevId: 585604976
(cherry picked from commit 8b38b34b9f02c3648d2988c4cdaca005fbf8f1cd)
Using `Integer.MAX_VALUE` risks causing arithmetic overflow in the codec
implementation.
Issue: androidx/media#810
PiperOrigin-RevId: 585104621
(cherry picked from commit ad40db448943fef579879c9c2a988f514b254109)
This change adds `MediaController.getSessionExtras()` through
which a controller can access the session extras.
The session extras can be set for the entire session when
building the session. This can be overridden for specific
controllers in `MediaSession.Callback.onConnect`.
PiperOrigin-RevId: 584430419
(cherry picked from commit a063d137b4307348a140ec6a2b6d254db294395e)
This change fixes a bug with seeking forward in MIDI. When seeking forward,
the progressive media period attempts to seek within the sample queue, if a
key-frame exists before the seeking position. With MIDI, however, we can
only skip Note-On and Note-Off samples and all other samples must be sent
to the MIDI decoder.
When seeking outside the sample queue, the MidiExtractor already
instructs the player to start from the beginning of the MIDI input. With
this change, only the first output sample is a key-frame, thus the
progressive media period can no longer seek within the sample queue and
is forced to seek from the MIDI input start always.
Issue: androidx/media#704
PiperOrigin-RevId: 584321443
(cherry picked from commit ec08db458e6cedcb79a42f10eaac7f8da7e7bcdb)
The live offset override is used to replace the media-defined
live offset after user seeks to ensure the live adjustment adjusts
to the new user-provided live offset and doesn't go back to the
original one.
However, the code currently clips the override to the min/max
live offsets defined in LiveConfiguration. This is useful to
clip the default value (in case of inconsistent values in the media),
but the clipping shouldn't be applied to user overrides as
the player will then adjust the position back to the min/max
and doesn't stay at the desired user position.
See 2416d99857 (r132871601)
PiperOrigin-RevId: 584311004
(cherry picked from commit af0282b9db62a8c5de1dbcc49794872d0157c1ab)
In some contexts (e.g. BottomSheetDialogFrament), Material Design
themes will override the default of singleLine=false to true. This
causes layout problems because the forward/rewind buttons are no
longer visible with singleLine=true.
This problem can be avoided by explicitly requesting the default
value of false in our layout files.
Issue: androidx/media#511
#minor-release
PiperOrigin-RevId: 582604131
(cherry picked from commit 310e2edccac75b1ed30eb69520224cb48d1cc190)
Based on on-device testing, this device seems to have the same issue as Moto G (20) where frames are dropped despite configuring the decoder not to drop frames.
PiperOrigin-RevId: 581943805
(cherry picked from commit 330713f687d4ebaec9ee8e9aaf39db503f299ce3)
The native code can now reallocate the buffer if it needs to grow
its size, so we have to reacquire a reference in the Java code to
avoid accessing a stale instance.
This fixes a bug introduced by 8750ed8de6.
PiperOrigin-RevId: 578799862
(cherry picked from commit ae6f83d298424bd405372803bb8b206fc95a2d0f)
Android Studio removed some nested imports, but I think the extra
qualification at the usage site is actually mostly helpful, so I'm
leaving it as-is.
PiperOrigin-RevId: 578518880
(cherry picked from commit 72b7019578f3051e1bec826cf0ac401a86d818dc)
Unfortunately we can't fail any more obviously at this point, because
manifests often contain config for multiple DRM schemes, and when
parsing the manifest we don't know which scheme is going to be used for
playback. It would be unreasonable to fail playback due to incomplete
ClearKey config if playback was otherwise going to succeed using e.g.
Widevine.
* Issue: androidx/media#777
* Issue: androidx/media#563
* Issue: google/ExoPlayer#9169
#minor-release
PiperOrigin-RevId: 578491484
(cherry picked from commit d42c23706b615d1987f988fe219ab0fe61d44ac6)
Some devices supporting Performance Points for decoder coverage are missing coverage over the CDD requirements for H264. For these cases ExoPlayer should fall back to legacy resolution and frame rate support checks. If there is an H264 stream evaluated as a `PerformancePointCoverageResult` of `COVERAGE_RESULT_NO`, then ExoPlayer checks for coverage of the [720p CDD requirement](https://source.android.com/docs/compatibility/10/android-10-cdd#5_3_4_h_264).
Issue: google/ExoPlayer#10898
Issue: androidx/media#693
PiperOrigin-RevId: 575768836
(cherry picked from commit 4515a0c3f24706a43b3247b558b14d98f2b0fce2)
* If we don't want any newlines in the result, it's better to use `>`
* If we want newlines (e.g. for markdown) then we should ensure the
string **only** contains the newlines we want, because GitHub (unlike
other markdown renderers) preserves single newlines in the output,
leading to ugly newlines dictated by the source.
Also remove a markdown-style link that isn't renderered as markdown.
PiperOrigin-RevId: 590309749
(cherry picked from commit 6aeaad26addee2d5793a624526d1811b8973c4ce)
This was intended to avoid bringing in a transitive dependency on the
Kotlin standard library, but Gradle no longer flags lint errors on
`@RequiresOptIn` violations with `annotation-experimental:1.2.0` (1.3.0
is needed), making this recommendation dangerous. See also
https://issuetracker.google.com/310651921.
PiperOrigin-RevId: 582276430
(cherry picked from commit aa1ec981a3eea59f8be9d44104d0573a60816436)
This is possible now we use `annotation-experimental:1.3.1`.
#minor-release
PiperOrigin-RevId: 582315579
(cherry picked from commit 8d83d491f198fbe3a21181df235dfff314252929)
This change moves the handling of any media button event into
`MediaSessionImpl.onMediaButtonEvent(intent)`. This includes
the double click handling from `MediaSessionLegacyStub`.
The advantage is that everything is in one place which allows
to offer `MediaSession.Callback.onMediaButtonEvent` with which
an app can override the default implementation and handle media
buttons in a custom way.
Media button events can originate from various places:
- Delivered to `MediaSessionService.onStartCommand(Intent)`
- A `PendingIntent` from the notification below API 33
- An `Intent` sent to the `MediaButtonReceiver` by the system dispatched
to the service
- Delivered to `MediaSessionCompat.Callback.onMediaButtonEvent(Intent)`
implemented by `MediaSessionLegacyStub` during the session is active
- Bluetooth (headset/remote control)
- Apps/system using `AudioManager.dispatchKeyEvent(KeyEvent)`
- Apps/system using `MediaControllerCompat.dispatchKeyEvent(keyEvent)`
Issue: androidx/media#12
Issue: androidx/media#159
Issue: androidx/media#216
Issue: androidx/media#249
#minor-release
PiperOrigin-RevId: 575231251
(cherry picked from commit a79d44edc5c7fdc81120dbc9b2c89b9799b14031)
The CompositionPlayer is not ready yet.
Issue: androidx/media#741
PiperOrigin-RevId: 574859927
(cherry picked from commit beb1711d4cfad51b88016bbb2b1e0f1a7945ed84)
Player methods shouldn't be called if they are not available and the
entry point to the playback resumption flow only checks
COMMAND_PLAY_PAUSE.
#minor-release
PiperOrigin-RevId: 574834148
(cherry picked from commit bfd1a2724c660de0df3c13f8394238ac6aa26e68)
If an app rejects the connection of the internal media notification manager
the session should behave like without the the media notification controller.
The legacy System UI controller should not be hidden or even rejected to
connect in such a case.
#minor-release
PiperOrigin-RevId: 574807901
(cherry picked from commit 54d5810fc353a9e7133ef929ab2f822d921070b1)
The current formatting makes the 'scheme' part of the list blend into
the definition, especially when the definition is multi-line.
https://developer.android.com/reference/androidx/media3/datasource/DefaultDataSource
I considered adding another level of nesting, but I think bold will
help distinguish the structure of the list without adding too much HTML
or visual whitespace.
#minor-release
PiperOrigin-RevId: 574514208
(cherry picked from commit aec6db77faba617dc2ab225b72c9bc3350c5b5c3)
As Opus decoders skip some bytes prior to playback during a seek, the renderer for bypass playback should send samples to the decoder even if they would be decode-only.
#minor-release
PiperOrigin-RevId: 574494666
(cherry picked from commit 00193e0304a5ea2c20012fabf77f82f29e218372)
This replaces the SimpleBitmapLoader that can now be deprecated
as it's fully unused and doesn't provide any additional functionality.
#minor-release
PiperOrigin-RevId: 574454636
(cherry picked from commit db86932781b4a5f377d1f4c1414c3d6a74ede174)
Media button event coming from the `MediaSessionService` are delegated
to the `MediaSessionImpl` and then sent to the session by using the
`MediaSessionStub` directly instead of using the `MediaController`
API.
Splitting the `MediaController.Listener` and `Player.Listener` in
`MediaNotificationManager` got reverted, and both listener are set to the
controller as before. This reverts the change that introduced a
different timing behaviour. It still holds, that a listener
registered on a `MediaController` that calls a method like `play()` is
called immediately and before the call has arrived at the player. This
change works around this behaviour from the library side by calling
`MediaSessionStub` directly with a `ControllerInfo`.
#minor-release
PiperOrigin-RevId: 573918850
(cherry picked from commit 64bd3bcad3fa4b0e433b16d583456920afad3ce2)
Android Auto shows a queue button when the queue is not empty.
Apps were able to remove this queue button with the legacy API
by not setting the queue of the session.
After this change, removing `COMMAND_GET_TIMELINE` from the commands
of the media notification controller or the session player sets the
queue in the platform session to null.
#minor-release
Issue: androidx/media#339
PiperOrigin-RevId: 573813558
(cherry picked from commit f53e1bc6f63caba7774c35aeb663b9178941faf5)
When MediaItems are added from the controller, we currently completely
replace the item with the one from our database, overriding any
potential additional information the controller may have set.
Also forward the onAddMediaItems/onSetMediaItems callbacks to common
helper methods instead of redirecting them through super methods
#minor-release
Issue: androidx/media#706
PiperOrigin-RevId: 573799351
(cherry picked from commit 00425dbe80dc9da38766f7235052c434d79724d1)
Previously, we calculated the next playlist reload time by adding the target duration (or half of it, depending on whether there is a real update in the new playlist snapshot) from the last load completion time, which makes the reload interval as long as `targetDuration(or half of it) + lastLoadDuration`. While still complying to the standard that "the client MUST wait for at least the target duration before attempting to reload the Playlist file again", this could cause buffering when the playback position is close to the end of live window. This change is to calculate the reload interval accurately by not adding the term `lastLoadDuration`.
Issue: androidx/media#663
#minor-release
PiperOrigin-RevId: 573300009
(cherry picked from commit 58a63c82aa0b59e86a656cf6644781a1c4690c82)
Use a non deprecated method that takes a `notMetRequirements` parameter
instead.
PiperOrigin-RevId: 573252909
(cherry picked from commit 8b7ebc70320e66b6360df37c36d4cfc2fb71aa98)
All production and test callers of the non-incremental methods are
already migrated, so we can remove them in this change too.
#minor-release
PiperOrigin-RevId: 573207318
(cherry picked from commit ecd24646cb1fd4b06a27cfe87ec0df47e9db87ed)
This content is no longer available, the manifest is returning a 404.
Issue: google/ExoPlayer#11309
#minor-release
PiperOrigin-RevId: 573202175
(cherry picked from commit a19f577976fc670c47e837d521c48170ab900ea0)
If the `Subtitle` has 'active' cues at `OutputOptions.startTimeUs`, this
change ensures these are emitted in a `CuesWithTiming` with
`CuesWithTiming.startTimeUs = OutputOptions.startTimeUs`. If
`OutputOptions.outputAllCues` is also set, then another `CuesWithTiming`
is emitted at the end that covers the 'first part' of the active cues,
and ends at `OutputOptions.startTimeUs`.
As well as adding some more tests to `LegacySubtitleUtilWebvttTest`,
this change also adds more tests for `TtmlParser` handling of
`OutputOptions`, which transitively tests the behaviour of
`LegacySubtitleUtil`.
#minor-release
PiperOrigin-RevId: 573151016
(cherry picked from commit f9ece88a25b449ab1e59ec0f6a67b71d7a2dc8ce)
All the production code is already calling these new incremental
methods, migrating the tests allows us to remove the old
`List`-returning methods in a follow-up change.
#minor-release
PiperOrigin-RevId: 572822828
(cherry picked from commit a12bde4f57002a9adf5da6c01b2f601a6edf92e9)
PlayerInfo bundling is costly and we can add a shortcut for
in-process binder calls where we store the direct object
reference in a live Binder object that can be written to the
Bundle instead of the individual data fields.
#minor-release
PiperOrigin-RevId: 572816784
(cherry picked from commit d1fc15f2075dd5c130a12420889fd83bd6517a08)
A few methods in PlayerInfo and related classes combine filtering
information with bundling in one method. This makes it impossible
to use just the filtering for example and it's also easier to reason
about than two dedicated methods. This change splits these methods
into two parts accordingly.
PiperOrigin-RevId: 572592458
(cherry picked from commit 4ebe630a80296cbb4437336a50abccb39da978f7)
When the controller of the `MediaNotificationManager` is disconnected,
the session is removed from the service without checking whether the
session hasn't already been removed. This caused flakiness in `MediaSessionServiceTest.addSession()`.
Because there is a public API `MediaSessionService.removeSession()`,
the controller can't make an assumption whether the session is still
contained in the service when being disconnected.
#minor-release
PiperOrigin-RevId: 572568350
(cherry picked from commit 7fdc5b22bac1af6fd074df38bb6b98c921e713a1)
This allows to disable periodic position updates when building
the session.
#minor-release
PiperOrigin-RevId: 572531837
(cherry picked from commit 4dc3db4da3da486b9c9ec1780aa595da8de5330c)
This currently only applies to subtitles muxed into mp4 segments, and
not standalone text files linked directly from the manifest.
Issue: androidx/media#288
#minor-release
PiperOrigin-RevId: 572263764
(cherry picked from commit 66fa5919590789b384506a4e604fe02a5a5e0877)
Interrupting the main thread in particular may be dangerous
as the flag is not cleared after handling the current message.
#minor-release
PiperOrigin-RevId: 572259422
(cherry picked from commit 846117399ff87dc025c355639444de2e54430b18)
This gives access to the replacement behavior for a particular subtitle
format without needing to instantiate a `SubtitleParser`.
#minor-release
PiperOrigin-RevId: 572226084
(cherry picked from commit e366c3d419f487beb567e360c21400c31add477f)
The value already exists as a class field.
#minor-release
PiperOrigin-RevId: 572200771
(cherry picked from commit e5fa0c2ce98930e4b679576290b5c0bebd37ad21)
In particular:
- Add allowAudioNonSeamlessAdaptiveness parameter (default true, same
as video and as already implemented by default)
- Forward mixedMimeTypeAdaptation support to AudioTrackScore
(as for VideoTrackScore) and adapt mixed MIME type adaptive
support accordingly
- Check adaptive support when deciding whether a track is allowed for
adaptation (also same check as for video). This takes the new
parameter into account.
PiperOrigin-RevId: 572191308
(cherry picked from commit f20d18e6cae136f8109380d69be76178008cdc17)
When used within the same process, we don't have to go via the
onTransact method (which includes marshalling and unmarhsalling
the data), but can directly return the list.
#minor-release
PiperOrigin-RevId: 572179846
(cherry picked from commit 0bddd06938fb5dc97a99a0cb3a444815a47be41c)
Future.isDone and getDone doesn't imply the Future was successful
and it may have been cancelled or failed.
In case where we handle failure, we should also handle cancellation
to avoid CancellationException to bubble up unchecked.
In demo app code where we use isDone for field initialization, we
want to crash in the failure case (usually security exception where
the connection is disallowed), but we want to gracefully handle
cancellation. Cancellation of these variables usually happens in
Activity.onDestroy/onStop, but methods may be called after this point.
#minor-release
PiperOrigin-RevId: 572178018
(cherry picked from commit fe7c62afe0b39f8d6617cf610dbdccc9e6adcfb4)
With this change the playback will resume as soon as the suitable device is connected and suppression reason is cleared (within set time out).
#minor-release
PiperOrigin-RevId: 572140309
(cherry picked from commit dc859eae82767598c43bbb182e81228be55f030b)
The current metadata updates are triggered by item transitions,
but depending on the speed of loading the playlist, the first
metadata may only be known later via metadata-change callbacks.
Slow playlist loading also means the UI stays empty and it's
beneficial to show a placeholder to avoid the impressions the
UI hangs.
Finally, clean-up by removing unused string constants and merging
all listeners into onEvents
#minor-release
PiperOrigin-RevId: 571951529
(cherry picked from commit fd81c904e11c47dcd7694e9b2f610914d4cf2596)
After 4fad529433, MediaCodecVideoRenderer does not report if frames
are dropped from the VideoSink. This commit fixes this.
#minor-release
PiperOrigin-RevId: 571905721
(cherry picked from commit 05b17b543060c1f32ae7af212e5e8b33203bdadd)
This belongs in the resolver, because it depends on the resolution
algorithm (and therefore the logic can't live in `TextRenderer`).
This also fixes a bug in `TextRenderer` where we were doing arithmetic
with `cues.durationUs` without checking if it was `TIME_UNSET` first.
#minor-release
PiperOrigin-RevId: 571332750
(cherry picked from commit 272428734b79ac6857a4333ede2b12563f8b78de)
The existing `Subtitle` handling code is left intact to support the
legacy post-`SampleQueue` decoding path for now.
This also includes full support for merging overlapping `CuesWithTiming`
instances, which explains the test dump file changes, and which should
resolve the following issues (if used with the
decoder-before-`SampleQueue` subtitle logic added in
5d453fcf37):
* Issue: google/ExoPlayer#10295
* Issue: google/ExoPlayer#4794
It should also help resolve Issue: androidx/media#288, but that will also require
some changes in the DASH module to enable pre-`SampleQueue` subtitle
parsing (which should happen soon).
PiperOrigin-RevId: 571021417
(cherry picked from commit 002ee0555dc35dce9570f1a991b33ec92743db10)
Alters RTSP KeepAlive monitor test to just make sure that keep-alive message is sent.
The test was added in 42c1846984
#minor-release
PiperOrigin-RevId: 571349013
(cherry picked from commit 417970f7132ab9fd539ba692309e29050b7001d5)
In some streaming scenarios, like offload, the sink may finish writing buffers a bit before playback reaches the end of the track. In this case a player may pause while in this 'stopping' state.
The AudioTrackPositionTracker needs to update the cached values it uses to calculate position in the `PLAYSTATE_STOPPED`/`PLAYSTATE_STOPPING` states if pause/play are called during this period.
PiperOrigin-RevId: 571345914
(cherry picked from commit a789db5b41d9d7a671e83a488b3dec372eaa8b3d)
In offload mode, `AudioTrack#stop()` will put the track in `PLAYSTATE_STOPPING` rather than `PLAYSTATE_STOPPED`. The difference in state means that `AudioTrack` can be paused and played during this 'stopping' period.
Currently, if `AudioTrackPositionTracker#handleEndOfStream()` has been called then `DefaultAudioSink` in `pause()` won't call `AudioTrack#pause()`. `AudioTrack#pause()` should be called in this case if in offload mode.
#minor-release
PiperOrigin-RevId: 571335108
(cherry picked from commit ab42d64d6d5f1859f1c45aebfe26060978b864bd)
This is required to make GMS send voice commands to the app.
#minor-release
PiperOrigin-RevId: 571326122
(cherry picked from commit 78f403aa7b795e0e3bcd2f4682bef171f545d4fa)
The flag is no longer used by our components and only set and checked
in a few places to guarantee compatiblity with existing renderers and
decoders that still use it.
The flag will be removed in the future due to its design limitations.
#minor-release
PiperOrigin-RevId: 571291168
(cherry picked from commit 89d01981bc4cf9218e73bcce1b52c7afe29fbecd)
The aim of this test is to make sure the image is onscreen for the right amount of time, so to drive down flakes from the decoder taking too long, change this to an atLeast check
#minor-release
PiperOrigin-RevId: 570988044
(cherry picked from commit 9cc75ca52e49792bed43e4d8fbf67b9a0576fdc0)
Set KeepAliveMonitor to send a keep-alive message at half the timeout value, if provided, by the RTSP Setup response.
Issue: androidx/media#662
PiperOrigin-RevId: 570946237
(cherry picked from commit 42c1846984fc8ebca5cdbdcf6df8d2dca44eea96)
In most cases this is more useful than `durationUs`.
We will keep `durationUs`, and the constructor will continue to take
`startTimeUs` and `durationUs`, to allow for use-cases where we don't
know the start time but still want to indicate a duration (this will be
used to implement CEA-608 timeout).
#minor-release
PiperOrigin-RevId: 570944449
(cherry picked from commit bf7b91e57e477f71644d5e585e0e999deadf7fa3)
This gets rid of the reliance on the decode only flag that is still
set on input buffers to the decoder if they are less than the start
time.
We still need to set and check the decode-only flag in SimpleDecoder
to ensure compatbility with custom decoders that use the flag while
it's not fully removed.
PiperOrigin-RevId: 570736692
(cherry picked from commit a03e20fe6c423389d54eb08d3b1f1d19499a0d9a)
The corresponding logic has been removed in 796781d4c3
#minor-release
PiperOrigin-RevId: 570729509
(cherry picked from commit 64fe863f315bbc870b347c4d9ea8009fb7713773)
This is useful for analytics and understanding player behavior
during transitions.
#minor-release
PiperOrigin-RevId: 570623227
(cherry picked from commit 8e2bf21011c63e2ca2fc58c4353cd66930b621e3)
Also fixed a bug where format queue was polled with wrong timestamp value.
#fixit
PiperOrigin-RevId: 570420304
(cherry picked from commit a879bae1ee2c684e8100f50bcff39655d46a2e8d)
The interface requires the implementation to return null if the
decode-only flag is set. So instead of setting the flag and returning
null, we can simply not call the method and assume it's null.
The only reason where this wouldn't work is if the metadata format
has keyframe-like logic and requires previous metadata to decode
the next one. This is not something we came across before and it seems
ignorable. If that feature is needed in the future, we should instead
add a method to MetadataDecoder to set the first output timestamp.
#minor-release
PiperOrigin-RevId: 570399838
(cherry picked from commit 796781d4c365e31a196c96e0588e4ff5ff0e3bf0)
While sleeping for offload, position is estimated based on time playing. If asleep and AudioTrack is reused, then the position will keep incrementing as the subsequent item plays. That is until wakeup when playing position is updated to the timestamp of the second item. Offload scheduling should be disabled until track transitions fully.
PiperOrigin-RevId: 570397140
(cherry picked from commit da06bf057a230293c8fb7f06cbfba71df8c4b5b1)
The test is hidden behind the Ignore annotation due to some flakiness just like `webvttInMp4`. However, it will be removed when the subtitle parsing is moved to a pre-sample-queue architecture.
#minor-release
PiperOrigin-RevId: 570376275
(cherry picked from commit bd5a3920b85423f1c1b625369fd606a9f36e1248)
In some cases, SimpleDecoder output needs to be skipped for rendering
because the decoder produces no data. This is one of the remaining
usages of BUFFER_FLAG_DECODE_ONLY at the moment and can be more
directly solved without using the flag. SimpleDecoder still needs to
check the flag though for backwards compatbility with custom decoders
while the flag is not completely removed.
PiperOrigin-RevId: 570345233
(cherry picked from commit c8aac24ffd8bfe708d68a251a9f28b3b48bed50c)
When seeking, we must first flush the video sink so it stops
using any SurfaceTextures before flushing MediaCodec.
#minor-release
PiperOrigin-RevId: 570015998
(cherry picked from commit 144bd7223626a2936368cbcb3bf3f7004ebe5e45)
When changing the playlist on Android Auto the UI of the
activity needs to be kept in sync.
PiperOrigin-RevId: 569528785
(cherry picked from commit 52d9fbff73cddd5c0881f6fd53a6ba35220d0ed1)
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 f7c31bd3ef525571f69065e836e350f06ff8d81a)
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 20d2ce7ce80c5e29c50438a6d581c1c36c1b0771)
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 dedccc596eb75f9d3fcf7114e8541f3119a88382)
Added this CMCD-Object field to Common Media Client Data (CMCD) logging.
PiperOrigin-RevId: 554843305
(cherry picked from commit 3ec462d1cf8c26c717236a4bb4a7bf9ab1fdc7cd)
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 6e91f0d4c5986af238cc77c1a9daa7f012d98a6c)
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 ddb0f8660489c06ce65d9f4b0256a8b60201920d)
The current code multiplies the value by 1000 twice,
effectively converting to nanoseconds.
#minor-release
PiperOrigin-RevId: 551129750
(cherry picked from commit f7669361407ad0b1fe536a8fb5d78e3f4e77026c)
This code is Widevine specific. `OfflineLicenseHelper.downloadLicense`
requires the passed `Format` to have a `DrmInitData.SchemeData` with
Widevine UUID and non-null `data` field. The demo app tries to check
this in advance (to avoid an exception later), but its checks are
looser than those made by `OfflineLicenseHelper`. This change tightens
the checks to match.
Issue: androidx/media#512
PiperOrigin-RevId: 549587506
(cherry picked from commit 1ccedf84142bec02ee52e76e714c7fc8dc394eea)
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 cdb174c91a0a9e5387f9773ac24f015199a7999e)
Added these CMCD-Object fields to Common Media Client Data (CMCD) logging.
PiperOrigin-RevId: 548950296
(cherry picked from commit 1b2a2fcde00c5bd05573e777c4e8a2bf60db7137)
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 c64d9fd6da90497547daf3deea536af2007784a5)
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 847f6f24d3770b6134a233b62a5fa9413c9bd26c)
Added these CMCD-Session fields to Common Media Client Data (CMCD) logging.
PiperOrigin-RevId: 547435498
(cherry picked from commit 0412a36564a09c0a237b91b4a78fed80336ea6b6)
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 ea21d27a6974822a970261f38964ec86c305796b)
Also update type names to match the current names for these types.
PiperOrigin-RevId: 546884049
(cherry picked from commit eed0e42ff805f54161125bbb6983f30ba0d39e8a)
This is only needed for instrumentation tests and should not
be included in regular builds.
Issue: androidx/media#499
PiperOrigin-RevId: 545913113
(cherry picked from commit 2250ffe6c8c5fa6b5bc728cd7a9fa075bcbb04d9)
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 07d4e5986b06ef6e362fe00fb97187469f42bc25)
This was helpful in investigating Issue: androidx/media#471
PiperOrigin-RevId: 545393217
(cherry picked from commit 3456382ae7116a8bb57b4212f449dfb50ea490d9)
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 e8fdd83558dcb0a4f886c52c8b32e2c1f3637a48)
These fields cannot be set and the logic to handle them can be removed.
PiperOrigin-RevId: 544646460
(cherry picked from commit 2f113c8b8234ca80fd0968f845dd195fcf956c6d)
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 d895a46b280f1f9764f63a5fc1ba16ab2727191e)
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 b324b8aa72db8853cf28429fa6462acdbf769f21)
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 232246240415443ff8d3a8cd5930273b4085ddaa)
`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 c2d80516628e4f62a4ec88ae1240002e6cc85aef)
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 b8ac5b42107b7d291162558378c2482bb84576f0)
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 4604f0cde691311d8a1104d66e6eb724766ce4b0)
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 e0191ddded1754cc31b025493970240aeb08a46e)
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 be9b057dda1a6a2da0e57b3b6f3620b371b7fd6e)
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 52878b2aca599d7aee3d87d76d602e81b1946d00)
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 501da109ced14c498eeafcd62d1fbe12e6ecc76e)
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 567890da9ed473b32b6e23c2b499e1e40d835487)
Previously `AsynchronousMediaCodecCallback.mediaCodecException` was
cleared when flushing completed. This behaviour was changed in
aeff51c507
so now the exception is not cleared.
The result after that commit was that we would **only** suppress/ignore
the expression if a flush was currently pending, and we would throw it
both before and after the flush. This doesn't really make sense, so this
commit changes the behaviour to also throw the exception during the
flush.
This commit also corrects the assertion in
`flush_withPendingError_resetsError` and deflakes it so that it
consistently passes. The previous version of this test, although the
assertion was incorrect, would often pass because the
`dequeueInputBuffer` call would happen while the `flush` was still
pending, so the exception was suppressed.
#minor-release
PiperOrigin-RevId: 540237228
(cherry picked from commit 248d1d99ecd1f3d57b1acc1cdc6f160b3b8aa495)
Currently, the implementation of `MediaControllerImplBase` differs from `ExoPlayerImpl`. The listeners of the former are notified of player error changes only in `onPlayerInfoChanged` and not `updatePlayerInfo` (masking method). Whereas `ExoPlayerImpl` has one unified method - `updatePlaybackInfo` - which sends the events to all the available listeners.
This change fixes the lack of 2 particular callbacks - `onPlayerErrorChanged` and `onPlayerError`, however, there might be more differences. Ideally, there should be a unified method for oldPlayerInfo/newPlayerInfo comparison-update-notify-listeners flow.
Issue: androidx/media#449
#minor-release
PiperOrigin-RevId: 539961618
(cherry picked from commit 4b5a4577905d86ec6e24a92a088a65689c7be901)
1. Not treating 0 as valid buffer index
2. Not handling the case the last frame is a comparison frame
PiperOrigin-RevId: 539607482
(cherry picked from commit 4b1ac2f17229a31754440693dc06ef583752070a)
This flag was introduced to fix links in javadoc search when generating
it with Java 11: <unknown commit>
The flag is no longer supported with Java 17 (which is required for
Gradle 8.0+), and seems to no longer be needed: I generated the javadoc
with it removed and the search links work OK.
PiperOrigin-RevId: 536738686
*** Original commit ***
Add a timer to end a video stream prematurely in ExtTexMgr
***
This has been submitting for more than 1.5hrs. "This presubmit is running slowly because you have been throttled by Build Queue due to using too much of your Product Area's quota."
adding NO_SQ as this is a pure rollback
PiperOrigin-RevId: 539135970
(cherry picked from commit 5c29abbbf4d2fb7c7770bcc79a1027c532f7b96e)
Add `HlsMediaSource.Factory.setTimestampAdjusterInitializationTimeoutMs(long)` to set the timeout for the loading thread to wait for the `TimestampAdjuster` to initialize. If the initialization doesn't complete before the timeout, a `PlaybackException` is thrown to avoid the playback endless stalling. The timeout is set to zero by default.
This can avoid HLS playback endlessly stalls when manifest has missing discontinuities. According to the HLS spec, all variants and renditions have discontinuities at the same points in time. If not, the one with discontinuities will have a new `TimestampAdjuster` not shared by the others. When the loading thread of that variant is waiting for the other threads to initialize the timestamp and hits the timeout, the playback will stall.
Issue: androidx/media#323
#minor-release
PiperOrigin-RevId: 539108886
(cherry picked from commit db3e662bdc17945acbe835120806b6aa597dee8a)
This change addresses the case when the user joins the live stream
on an ad period but the metadata for the ad period is not emitted.
This results in inserting a partial ad group.
In this case the ad group duration is longer than the partial ad
group. If now the partial ad group ends at the period before the
last period of the window (unknown duration), the splitting algorithm
didn't recognize that the ad group already ended and made the last
period wrongly an ad period.
This change handles this edge case by counting the mapped ads in
the partial ad group to detect this situation and stops splitting.
#minor-release
PiperOrigin-RevId: 539102785
(cherry picked from commit cd604e7ead3e4393dd6bf7b615df00b1b6da5d4a)
In case the player is reset while a live stream is playing, the current
period needs to be a placeholder. This makes sure that the default start
position is used when the first live timeline arrives after re-preparing.
#minor-release
PiperOrigin-RevId: 539044360
(cherry picked from commit 71153a43a8e55380076af97450414f9142dc636b)
When the source is prepared again after stop, the period uid
is calculated by subtracting the `firstPeriodId` from the
period uid that is passed in to `createPeriod`. When this
happens after stop, the uid from the old period uid that
is still stored and has the value of the last played uid.
Hence the `firstPeriodId` must not be reset when released.
Issue: google/ExoPlayer#10838
PiperOrigin-RevId: 539028570
(cherry picked from commit 319854d624a95d3f71a26c96ecb4e5827d4a7f4e)
Add support for including Common Media Client Data (CMCD) in the outgoing requests of adaptive streaming formats DASH, HLS, and SmoothStreaming.
API structure and API methods:
* CMCD logging is disabled by default, use `MediaSource.Factory.setCmcdConfigurationFactory(CmcdConfiguration.Factory cmcdConfigurationFactory)` to enable it.
* All keys are enabled by default, override `CmcdConfiguration.RequestConfig.isKeyAllowed(String key)` to filter out which keys are logged.
* Override `CmcdConfiguration.RequestConfig.getCustomData()` to enable custom key logging.
NOTE: Only the following fields have been implemented: `br`, `bl`, `cid`, `rtp`, and `sid`.
Issue: google/ExoPlayer#8699
#minor-release
PiperOrigin-RevId: 539021056
(cherry picked from commit b55ddf12b4536b457b8ad843047f559fa8ed5c33)
This change is for Android 12 and below, where the buttons are derived from the actions added with the notification. From Android 13 (https://developer.android.com/about/versions/13/behavior-changes-13#playback-controls), the system derives media controls from `PlaybackState` actions.
When adding the actions onto the notification, the logic will iterate all the command buttons. The `COMMAND_KEY_CONPACT_VIEW_INDEX` extra will be checked for each button. If that extra is set for the three buttons on the compact view, then the customized buttons and their order will be used. Otherwise, the compact view will be "seekPrev" (if any), "play/pause" (if any), "seekNext" (if any) buttons (in such order).
Issue: androidx/media#410
PiperOrigin-RevId: 538797874
(cherry picked from commit 2e2f19351f751a084889fc3b1d8dfbfa1eb757d7)
To ensure no regressions for the potentially confusing pipeline of:
* HDR electrical -> SDR linear EOTF+OOTF, and
* SDR linear -> SDR electrical OETF
PiperOrigin-RevId: 538741079
(cherry picked from commit 0c924fcb4072d7485e0e5b61097c2e7c37eb6b6a)
Also queue textures from a different thread in TextureAssetLoader, to
have a behaviour closer to reality.
PiperOrigin-RevId: 538473089
(cherry picked from commit 3ba8f6dd8fe57c2b1edde75630f568d374c1b69f)
Confirms that multiple textures can be output, and that timestamps and pixels
are as expected.
PiperOrigin-RevId: 538459296
(cherry picked from commit adf53b4d508320e8b60bcfd2d5366ff9a5065736)
The sample timestamp carried by the emsg box can have a significant delta when comparing to the earliest presentation timestamp of the segment. Using this timestamp to intialize the timestamp offset in TimestampAdjuster will cause the media sample to have a wrong adjusted timestamp. So we should defer adjusting the metadata sample timestamp until the TimestampAdjuster is initialized with a real media sample.
PiperOrigin-RevId: 538172841
(cherry picked from commit f4bf376e891bb0326b4c569cecec825e870aec92)
When initiated by MediaController, it should be possible for `MediaSession` to pass `MediaItems` to the `Player` if they have `LocalConfiguration`. In such case, it is not required to override `MediaSession.Callback.onAddMediaItems`, because the new current default implementation will handle it.
However, in other cases, MediaItem.toBundle() will continue to strip the LocalConfiguration information.
Issue: androidx/media#282
RELEASENOTES.md modified in cherrypick
PiperOrigin-RevId: 537993460
(cherry picked from commit d9764c18adbc8b1fe23d983f92c68a582394b33a)
`outputSurfaceInfoChanged` is not reset when `defaultShaderProgram` is null.
That is, on the first time `ensureConfigured()` is called with output size
changed, `outputSurfaceInfoChanged` is not set to false after creating the
`defaultShaderProgram`, and `defaultShaderProgram` will be created again on the
second time `ensureConfigured()` is called.
PiperOrigin-RevId: 537870404
(cherry picked from commit 133943a63520fbc872c3960647144fde8a918df8)
208eefc0fd introduced using `DefaultDecoderFactory.getDecoderInfo(format) != null` caused certain tests not to be skipped when they were expected to be, creating more mh failures.
PiperOrigin-RevId: 537820370
(cherry picked from commit 2af57527853beb7ee40e5b70efde74e72f8d60f1)
ExoPlayer extractors (backing `MetadataRetriever`) now parse the color format
from the bitstream so using `MetadataRetriever` should be an equivalent but
more lightweight way to verify the color info.
Also remove try/catch blocks in test code calling into these methods, and add
skipping based on decoder capabilities in the cases where it was missing.
PiperOrigin-RevId: 537789483
(cherry picked from commit 74478f2478b420f9264c33e74a4544a8cef60cb8)
Previously, we would apply a general effect to signal wanting to transcode.
PiperOrigin-RevId: 537034455
(cherry picked from commit c52130a2124b7dfcdff3eac02167795b772f3a6b)
In some cases the codec selected for decoding has a different MIME type than
the media. In thoses cases Transformer continued to use the media's MIME type
and that caused codec configuration failures.
Removed `EncoderUtil.findCodecForFormat()` as we stopped using the method it
uses for finding a codec. Plus, the method is only used in the test.
See also `MediaCodecUtil.getALternativeCodecMimeType()`.
PiperOrigin-RevId: 536683663
(cherry picked from commit 208eefc0fdf7b5320f5468aa9da864fefba3cfbe)
Otherwise, texture output errors out if video decoding decodes faster than audio,
hitting the end of the file, while audio is still in the middle of the file.
PiperOrigin-RevId: 536679568
(cherry picked from commit e2821f10f5ad9d88ab30c7ea50b815cb8854801f)
This future.get() duplicates the wait done in
singleThreadExecutorService.awaitTermination(). If awaitTermination times out, this future.get() would also result in unnecessary blocking.
PiperOrigin-RevId: 536442153
(cherry picked from commit 1c172e0bed7937282fca630efde497319f2ae82a)
Deprecated field `MediaItem.playbackProperties` remains for backwards compatibility, but its type is changed from `MediaItem.PlaybackProperties` to `MediaItem.LocalConfiguration`. The private `MediaItem` constructor will now also take in a `LocalConfiguration` argument instead.
PiperOrigin-RevId: 535648420
(cherry picked from commit 25bf0c6738b6bf58e153a1ddbb0cb29c40501e13)
With this change we will now support loading bitmaps from all the formats documented [here](https://developer.android.com/guide/topics/media/media-formats#image-formats) except for gifs (because they are animated). Java doc is added to express this.
PiperOrigin-RevId: 535610152
(cherry picked from commit 94d29f35fcae157b43ff43d89dcd4ff38fd88cb2)
*** Original commit ***
ExoPlayer: Add setVideoFrameProcessorFactory().
This allows apps to use a custom VideoFrameProcessor implementation for video
playback. This may be useful, for example, when outputting to a texture.
***
PiperOrigin-RevId: 536391597
(cherry picked from commit 06908e1a865c4c5ae9a9f52986255756bb20cd07)
This change moves the default logic into the actual Player
implementations, but does not introduce any behavior changes compared
to addMediaItems+removeMediaItems except to make the updates "atomic"
in ExoPlayerImpl, SimpleBasePlayer and MediaController. It also
provides backwards compatbility for cases where Players don't support
the operation.
Issue: google/ExoPlayer#8046
#minor-release
PiperOrigin-RevId: 534945089
(cherry picked from commit 2c07468908fdba9918d33d0f02c6ff872b87fefc)
Also, document that texture output disables manual frame release.
In the past, texture output would lead to surface output methods throwing. Now,
they're simply no-ops instead.
PiperOrigin-RevId: 534894168
(cherry picked from commit abf649cdfa367976517ee07f83ea805b60ed88a5)
When the video renderer is disabled, the video size is set to 0/0
and sent to listeners. The `PlayerView` potentially still has the last frame
displayed when the player is stopped or an error occurs. This may have the
effect that the frame is displayed distorted.
Not changing the aspect ratio when the video size arrives when the player is IDLE
avoids the problem. In the case when playback starts again and the renderes is
enabled, another video size is sent to the listener.
#minor-release
PiperOrigin-RevId: 534860889
(cherry picked from commit 6469fffd8fe4ffc404f4bc1e405c362ff7020827)
This helps to highlight that the replaced range doesn't need to have
the same size as before.
#minor-release
PiperOrigin-RevId: 534834917
(cherry picked from commit acb567d5a723102a82afff2eb36f953f203deddf)
I undid my last clean-up (b762ca993e) in 5a5c3ce3bd
#minor-release
PiperOrigin-RevId: 534763770
(cherry picked from commit 41492b6e299b4069324dd74ae03ad896992ae970)
This change removes it from `Player.Listener` and `AnalyticsListener`,
use `onPositionDiscontinuity` with `DISCONTINUITY_REASON_SEEK` instead.
#minor-release
PiperOrigin-RevId: 534757426
(cherry picked from commit 5c713feb60bafbf8534cc30c525572bc4c96222b)
Tentative/experimental value to reduce codec timeouts. We will reconsider using a larger limit after seeing whether this really does reduce error rate.
PiperOrigin-RevId: 534491615
(cherry picked from commit 66554b9b686843d4f503833d59717a7717dd4959)
- Number of frames from SurfaceTexture that is sent downstream
- Times ExtTexMgr signaled end of current input stream
PiperOrigin-RevId: 534487842
(cherry picked from commit d584a772e3dbc0ba6df7e4d7073e735e1918c6c4)
Mp4Muxer already supports writing Mp4LocationData so added that
as supported Metadata entry.
Support for more Metadata entries will be added in upcoming CLs.
PiperOrigin-RevId: 534473866
(cherry picked from commit 7c477589e5f25b1fffa51e8961ed26f4615066a5)
I moved this assignment in 0888dfbd05
in order to provide a single source-of-truth for `publish.gradle`,
but as pointed out in Issue: androidx/media#416 this breaks apps that are depending
on our project locally using the instructions we publish. Instead we can
remove the `rootProject.name` check from `publish.gradle`, and check an
explicit boolean value instead to indicate if the root project is 'ours'
(with this boolean only set from `settings.gradle`, so it doesn't get
picked up by apps depending on us locally).
#minor-release
PiperOrigin-RevId: 534459085
(cherry picked from commit 9a795712843aa8907a3087fc6003e000960db5ad)
And fix violation of this in AdsMediaSource.
#minor-release
PiperOrigin-RevId: 534441648
(cherry picked from commit c73955a4cd75a2b8b7393d5a44067d0eaeb3981a)
Use the audio or video specific variants instead.
#minor-release
PiperOrigin-RevId: 534436644
(cherry picked from commit 5a5c3ce3bd4a6b906e8ddc6cbdbfcf2d7f4ee71f)
Use the non-deprecated constructor instead.
#minor-release
PiperOrigin-RevId: 534426655
(cherry picked from commit 48348df58ad7ebbe13b842a3daa9db21a67c75ad)
Use the constructor that takes an `Executor` instead.
#minor-release
PiperOrigin-RevId: 534370613
(cherry picked from commit ff0f1c4e9c41ae9c0e087988f1e5d82cbe4c1324)
- Use artwork display mode `fill` to improve visual apperance
- Some minor cleanup
#minor-release
PiperOrigin-RevId: 534366246
(cherry picked from commit 230921e4ab999f3f9af40688cedaf02631052a95)
This change merges some duplicate sections, moves some items to more
appropriate sections and removes unnecessary items (deprecations are
self-documenting, so don't need to be included here).
#minor-release
PiperOrigin-RevId: 534363065
(cherry picked from commit b762ca993ef2c8afc2e840cebdf86bba2778b798)
This change deprecates `PlayerView.setUseArtwork(boolean)` and
introduces `setArtworkDisplayMode(mode)` and
`artworkDisplayMode="off|fit|fill"` instead.
- off: no artwork is displayed (like deprecated useArtwork=false)
- fit: letterbox like media (like deprecated useArtwork=true)
- fill: scales the artwork to fill the entire width/weight of the player view
#minor-release
PiperOrigin-RevId: 534167226
(cherry picked from commit 46fb454b3ffc4b2ad97ceccb4dc798e1c9a4c774)
Basically this change removes a bug that makes video playback stuck when
a video is playing and the user taps the UMO notification to get to
the player activity.
- Use `launchMode="singleTop"` for `PlayerActivity`
- Change session activity to a back stacked activity on service `onDestroy`.
Using a back stacked activity `onDestroy()` will be useful once this demo
app implements playback resumption.
The rest of the changes are aesthetic:
- clean up and optimize screen space usage in UI of `PlayerActivity`
- changed some colors, paddings and spacings
- adds a default artwork for the `PlayerView`
PiperOrigin-RevId: 534152052
(cherry picked from commit 96a4ae7e40732dccd2fdded4cb8d0cc7f25f8cdd)
Fix a bug when seeking in an opus container. The calculations inside
DefaultOggSeeker may overflow a long primitive.
Issue: androidx/media#391
#minor-release
PiperOrigin-RevId: 534128513
(cherry picked from commit b9a4e614f7cfe863e72dec779b7beb1a8c1e4e2d)
Earlier metadata was written multiple times as it came.
With new changes, all the distinct metadata entries will
get collected and will be written at once in the end.
PiperOrigin-RevId: 534088401
(cherry picked from commit a9e3f5def4fa17aa82f47a8d3a1f1452c2e6f245)
This allows apps to use a custom VideoFrameProcessor implementation for video
playback. This may be useful, for example, when outputting to a texture.
PiperOrigin-RevId: 534044831
(cherry picked from commit 438ae0ed6ac1059e8aaa9380f476c1403f24a986)
This is a follow-up to 99dac0be0f where we made the same change in
ExoPlayerImpl and SimpleBasePlayer, but for consistency it makes
sense to also update the masking code in MediaControllerImplBase to
assume the same logic.
Note: MediaControllerImplLegacy already handles this case via
setMediaItems and doesn't need to be updated further.
#minor-release
PiperOrigin-RevId: 534038759
(cherry picked from commit 33af245465ac9a8441a58a6fd6bf75c34e2efa26)
The methods in ExoPlayerImpl and MediaControllerImplBase that determine
the new PlayerInfo/PlaybackInfo currently have a hard-to-reason-about
setup where the method generating the new info accesses other methods
that rely on the existing class field instead of working with the
passed in PlayerInfo/PlaybackInfo. This prevents reuse of the util
methods (e.g. for replaceMediaItems) because they access potentially
stale state.
This change untangles these methods a bit by making the util methods
either static or at least ensure that they don't rely on existing
class fields of PlayerInfo/PlaybackInfo. Overall, the change is a
complete no-op.
#minor-release
PiperOrigin-RevId: 534036633
(cherry picked from commit 1fa790348e7e90c987d3385a79a2c7c150cd6824)
MediaControllerImplBase currently drops the pending initial seek
position when a user sets an empty playlist.
When seeking in empty playlists and setting new empty playlists,
the class also drops the the period index (and wrongly assigns zero
instead of the windowIndex).
#minor-release
PiperOrigin-RevId: 534035046
(cherry picked from commit caf1c77af1822d0268d7f028f358374bbe2ba1c8)
The main interface documentation hasn't been updated substantially
since 2017 and is missing notes for many of its current features and
requirements.
Also change the recommendation for implementors from BasePlayer to
SimpleBasePlayer to ensure new classes are more likely to cover all
of the interface requirements.
#minor-release
PiperOrigin-RevId: 534027117
(cherry picked from commit 6de6bd9c4f23b87427b7d2c4cb2c330aef5fba49)
This class is to be shared between extractor, transformer
and muxer module.
PiperOrigin-RevId: 533490888
(cherry picked from commit b382a7c2da1452e15d5829113fb39ebc98b87a17)
In terms of MCVR with a `VideoRendererEventListener`, the video size is set to
0/0 right after `onVideoDisabled()` is called and is set to the actual size as
soon as the video size is known after 'onVideoEnabled()`.
For ExoPlayer and in terms of the `Player` interface, `Player.getVideoSize()`
returns a video size of 0/0 when `Player.getCurrentTracks()` does not support
`C.TRACK_TYPE_VIDEO`. This is ensured by the masking behavior of
`ExoPlayerImpl` that sets an empty track selection result when the playing
period changes due to a seek or timeline removal.
When transitioning playback from a video media item to the next, or when
seeking within the same video media item, the renderer is not disabled.
#minor-release
PiperOrigin-RevId: 533479600
(cherry picked from commit 2a6f893fba763077cae85b0255d6bd05f0887709)
This may not be completely exhaustive, but it's better than before!
#minor-release
PiperOrigin-RevId: 533457167
(cherry picked from commit fe19dc421decccf283e503aab9375a04f5dcdeb7)
This is useful for cases where only certain types (e.g. only video)
from a source are needed and other tracks should be filtered out
completely to avoid later track selection issues.
#minor-release
PiperOrigin-RevId: 533394658
(cherry picked from commit c44b3828caed79351955b761a84db804da8691c5)
This allows us to avoid needing a reference to the VideoFrameProcessor, which
can be especially difficult if an App only has a reference to the
VideoFrameProcessor.Factory it passes into Transformer/ExoPlayer.
PiperOrigin-RevId: 533205983
(cherry picked from commit 25fa2df2dedf45e8a060ee28324460429b9bb279)
JaCoCo introduces private synthetic methods (even on interfaces) which
have to be skipped when checking that a 'forwarding' implementation does
forward everything. Instead we can use the existing `getPublicMethods()`
method which implicitly skips these (since they're private).
PiperOrigin-RevId: 533130932
(cherry picked from commit 620b9e15403b5138e7b3f44194b10e5ae7f72a8c)
Use `Format.buildUpon()` and `setXXX` instead.
#minor-release
PiperOrigin-RevId: 532840625
(cherry picked from commit 538524e579496aa75469ddd8fea76a963236da42)
This device failed on HdrEditingTest's exportAndTranscode_hlg10File_whenHdrEditingUnsupported_toneMapsOrThrows
before this CL, and succeeds on that test after this CL.
PiperOrigin-RevId: 532796897
(cherry picked from commit 83190a0fe9b7f0cd30398ecc6d1246412ec555d7)
This class will be shared between extractor and muxer module.
PiperOrigin-RevId: 532784415
(cherry picked from commit 7b62b33127a617cc3b7b23f21c385f2329e402a3)
Have the FinalShaderProgramWrapper / VideoFrameProcessor texture
output access textures provided through a texture pool, that
recycles used textures.
Also, add the TexturePool interface to generally re-use textures.
PiperOrigin-RevId: 532754377
(cherry picked from commit 94efcd7917ad5c175aac52280ee82f054d24a953)
Propagate the "end of current stream" signal directly after queueing the
last frame, instead of waiting for the next onReadyToAcceptInputFrame()
call.
PiperOrigin-RevId: 532739462
(cherry picked from commit 028b3a73120b755733f58f8c8d9764146c470437)
Use a non deprecated constructor that includes the option to provide a `Context` parameter instead.
#minor-release
PiperOrigin-RevId: 532535770
(cherry picked from commit df52864420da49e97405c905c7e218e4112573df)
Use Kotlin Charsets from the `kotlin.text` package, the `java.nio.charset.StandardCharsets` or the `com.google.common.base.Charsets` instead.
#minor-release
PiperOrigin-RevId: 532469103
(cherry picked from commit 1061135cfd68dec4d2e073c1ca9e08d57b5c6875)
Use a non deprecated constructor that includes the option to provide a `channelDescriptionResourceId` parameter.
#minor-release
PiperOrigin-RevId: 532450975
(cherry picked from commit 022a05c376918eec0628c0eed32251882fc6f767)
This change enables the IMA extension to play live DASH streams
with DAI support. Samples streams can be found and played in the
main demo app.
Issue: google/ExoPlayer#10912
#minor-release
PiperOrigin-RevId: 532407708
(cherry picked from commit dab1353aadd4a093d29e1d418f012d42964e9d50)
This is a failure only in SSIM, so it seems unlikely we'll prioritize this over
other work or bugs soon. Suppress test failures to reduce triage burden.
PiperOrigin-RevId: 532200729
(cherry picked from commit 62afbe87bb05890bbbb60ff4e3f0b2fd65aea433)
Use a non-deprecated constructor that accepts additional fields(`cause`, `responseBody`) to enhance error logging.
#minor-release
PiperOrigin-RevId: 532190896
(cherry picked from commit b120ef65ed6425c3193bb4d68a11ce9ac2372347)
This methods allows to replace single items or a range of items directly
without using separate operations for add and remove. The advantage is
more readable code for apps and the potential for player
implementations to optimize this process (e.g. only replace values
without interrupting playback).
The current change just introduces the API with its default behavior.
The default logic will be removed again in the future in favor of
better logic in the Player implementations.
Issue: google/ExoPlayer#8046
PiperOrigin-RevId: 532151471
(cherry picked from commit b1cfeb04a0e9a1e0f08917e621bd40968db68c01)
Allow the VideoFrameProcessor to output multiple textures at a time, so that
lifetime of textures is up to the consumer calling VFP.releaseOutputFrame.
The FinalShaderProgramWrapper also has a new maxCapacity limit added, to ensure
the a reasonable amount of textures is used and avoid using up memory.
PiperOrigin-RevId: 532094256
(cherry picked from commit 07ec1eaa480146942e8019a1db25661201a2f3e0)
The periodic updates are only meant to happen while we are in the
same period or ad. This was already guaranteed except for two cases:
1. The Player in a session has updated its state without yet calling
its listeners
2. The session scheduled a PlayerInfo update that hasn't been sent yet
... and in both cases, the following happened:
- The change updated the mediaItemIndex to an index that didn't exist
in a previous Timeline known to the Controller
- One of the period position updates happened to be sent at exactly
this time
This problem can be avoided by only scheduling the update if we are
still in the same period/ad and haven't scheduled a normal PlayerInfo
update already.
Since new MediaControllers may still connect to old sessons with this
bug, we need an equivalent change on the controller side to ignore such
buggy updates.
PiperOrigin-RevId: 532089328
(cherry picked from commit 96dd0ae5837a5fd82d7407623bedb5fd4d1e9252)
When exporting compositions with multiple images in a row, transformation could
get stuck if a shader was ready to accept input when end-of-stream was already
signaled and queued from upstream. Fix accounting for the downstream capacity.
Manually tested on concatenations with several images and several videos in a
row, by adding logging and verifying the capacity updates as expected across
edited media item transitions.
PiperOrigin-RevId: 532088793
(cherry picked from commit 6850391e45ed571f0190643189661b0920292084)
In the past, the SequenceAssetLoader was released in TransformerInternal
when the export ended.
fc539da061 was made to release the SequenceAssetLoader earlier, when
loading ended. This was causing player release timeouts because the last
AssetLoader in the sequence was released before the SamplePipelines (see
0b40bc37ab for more information).
The code that was releasing the SequenceAssetLoader was first commented
out because we didn't have an understanding of what was happening.
This change removes the early SequenceAssetLoader release all together.
It doesn't have any effect as this code was already commented out.
PiperOrigin-RevId: 532065673
(cherry picked from commit 6dfb387117b2a12d5141014dd49fe32afcec3886)
The output end-of-stream notification from the last shader could theoretically
arrive before the latch for detecting it is created, which might cause waiting
on the latch indefinitely. Create the latch before signaling end of stream so
that it's guaranteed to be set before the end-of-stream signal arrives.
PiperOrigin-RevId: 532056472
(cherry picked from commit 857e6ebee814cb1a92875dc055dd5aff0ef07453)
Use a non-deprecated constructor that takes a `DatabaseProvider`
instead for better performance.
#minor-release
PiperOrigin-RevId: 532046598
(cherry picked from commit 0a86790be25527c45b0070cd0d4a1089b2069108)
*** Original commit ***
Rollback of 221a56da38
*** Original commit ***
Rollback of 749d77b1d9
*** Original commit ***
PiperOrigin-RevId: 531530885
(cherry picked from commit 9366b4e50a0dbb1d8a59940944dd732b3f3c3f9b)
This can provide more information to help debug muxer errors
PiperOrigin-RevId: 531521974
(cherry picked from commit 2736b118458c1ead0cbac2457700c1333f7c86c7)
When a `MediaButtonReceiver` is found in the manifest, the library
can implement the contract of SystemUI to signal that the app wants
a playback resumption notification to be displayed.
And, vice versa, if no `MediaButtonReceiver` is in the manifest, the
library will signal to not show the notification after the app has been
terminated.
#minor-release
PiperOrigin-RevId: 531516023
(cherry picked from commit 9bf6b7ea2062435970cea132c295659b48508b4e)
This module will contain functionalities common to extractor and muxer.
PiperOrigin-RevId: 531501602
(cherry picked from commit eb8ec87a5cbf26998ee17d9d6b1d4979ee0c28f6)
Mp4Muxer supports adding Metadata track.
Added test file to cover this scenario.
PiperOrigin-RevId: 531496409
(cherry picked from commit b3fd202e113949146f6155984665a411164da9e3)
*** Original commit ***
Rollback of 65d5132f76
*** Original commit ***
Create InAppMuxer in transformer
To use the InAppMuxer, the client needs to pass InAppMuxer Factory.
***
***
PiperOrigin-RevId: 531470081
(cherry picked from commit 867355fdc55722a5fde9f22cd207c5fb57ba067d)
2023-05-17 16:59:54 +00:00
2293 changed files with 103067 additions and 18599 deletions
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredAudioMimeTypes(java.lang.String...);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredAudioMimeTypes(java.lang.String...);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredAudioRoleFlags(@androidx.media3.common.C.RoleFlags int);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredAudioRoleFlags(@androidx.media3.common.C.RoleFlags int);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextLanguage(@Nullable String);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextLanguage(@Nullable String);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(android.content.Context);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings();
method @Deprecated public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(android.content.Context);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextLanguages(java.lang.String...);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextLanguages(java.lang.String...);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextRoleFlags(@androidx.media3.common.C.RoleFlags int);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredTextRoleFlags(@androidx.media3.common.C.RoleFlags int);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredVideoMimeType(@Nullable String);
method public androidx.media3.common.TrackSelectionParameters.Builder setPreferredVideoMimeType(@Nullable String);
method public final androidx.media3.common.Player getPlayer();
method public final androidx.media3.common.Player getPlayer();
method @Nullable public final android.app.PendingIntent getSessionActivity();
method @Nullable public final android.app.PendingIntent getSessionActivity();
method public android.os.Bundle getSessionExtras();
method public final androidx.media3.session.SessionToken getToken();
method public final androidx.media3.session.SessionToken getToken();
method public final void release();
method public final void release();
method public final com.google.common.util.concurrent.ListenableFuture<androidx.media3.session.SessionResult> sendCustomCommand(androidx.media3.session.MediaSession.ControllerInfo, androidx.media3.session.SessionCommand, android.os.Bundle);
method public final com.google.common.util.concurrent.ListenableFuture<androidx.media3.session.SessionResult> sendCustomCommand(androidx.media3.session.MediaSession.ControllerInfo, androidx.media3.session.SessionCommand, android.os.Bundle);
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.