22910 Commits

Author SHA1 Message Date
michaelkatz
aea0637c95 Fix media period mismatch during recoverable renderer error processing
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
2025-04-14 09:55:23 +01:00
tonihei
f533f55cd6 Add missing type cast
(required due to not cherry-picking 6b1a2aff98)
2025-04-14 09:33:02 +01:00
tonihei
177092d935 Fix getChildPeriod logic if the child is a TimeOffsetMediaPeriod
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)
2025-04-12 21:12:31 +01:00
rohks
153974e06c Derive average bitrate from stsz sample size and mdhd duration
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)
2025-04-12 21:12:28 +01:00
tianyifeng
d7234a6a4e Fix issue where ProgressiveMediaPeriod fails assertPrepared
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)
2025-04-12 21:12:11 +01:00
tonihei
24a8185f4d Ensure media notification provider can be updated
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)
2025-04-12 21:10:54 +01:00
tonihei
d652ba6ae2 Bump version to 1.6.1
PiperOrigin-RevId: 746409221
(cherry picked from commit 45bcf3ff929f0023d4c982c2489214d91ffec29c)
2025-04-12 21:10:54 +01:00
bachinger
75e2522862 Always return empty timeline when wrapped player is empty
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)
2025-04-12 21:10:54 +01:00
tonihei
157fd8a260 Remember explicit notification dismissal
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)
2025-04-12 21:10:54 +01:00
bachinger
ce0c98c4d4 Make sure subtitle is used without display title being set
PiperOrigin-RevId: 745616511
(cherry picked from commit cb0ea7fc95ffb1160cfd7904ee5c548d8f0a68cb)
2025-04-12 21:10:51 +01:00
aquilescanta
b16f9fc4ec Add missing isDeviceMuted to EVENT_DEVICE_VOLUME_CHANGED docs
PiperOrigin-RevId: 745591130
(cherry picked from commit c5b6489d5d6eb206f34b2e11c32ecb34c4ca7d49)
2025-04-12 21:09:13 +01:00
bachinger
5b4ca08ca0 Adjust AGGREGATES_CALLBACKS_WITHIN_TIMEOUT_MS and make it configurable
PiperOrigin-RevId: 745585764
(cherry picked from commit 1b3658e357adad6f12fd7cc864f0b0d64f38fb3c)
2025-04-12 21:09:13 +01:00
tonihei
c0dd97e770 Clear surface from previous player when assigning a new player
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)
2025-04-12 21:09:13 +01:00
rohks
f35c59b176 Ensure chunk duration is set in CmcdData for HLS media
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)
2025-04-12 21:09:13 +01:00
dancho
82d7c628da Do not drop decoder input buffers close to a reset position
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)
2025-04-12 21:09:13 +01:00
michaelkatz
9cfaf78994 Do not enable offload scheduling while preparing next media
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)
2025-04-12 21:09:13 +01:00
bachinger
cb80fe4c7c Make AdPlaybackState.withAdDurationsUs work with removed ad groups
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)
2025-04-12 21:09:09 +01:00
michaelkatz
567ee030b3 Set static interval as default for dynamic scheduling with audio
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)
2025-04-12 21:08:54 +01:00
rohks
2bdf632369 Remove incorrect frame rate calculation using tkhd box duration
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)
2025-04-12 21:08:54 +01:00
tonihei
7c274caa1f Update PlayerSurface to directly use AndroidView
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)
2025-04-12 21:08:54 +01:00
tianyifeng
9d09840bad Add PlaybackParameters.withPitch() method
Issue: androidx/media#2257
PiperOrigin-RevId: 742693410
(cherry picked from commit ce3754a7409562724b5de399cfaab60b96d90da2)
2025-04-12 21:08:54 +01:00
Copybara-Service
9483cbfed4 Merge pull request #2253 from nirb999:main
PiperOrigin-RevId: 741092998
(cherry picked from commit f2fa0f7b2ac998db12722a6a46158474cccfcbc1)
2025-04-12 21:08:39 +01:00
ibaker
358e002076 MP4: Parse alternate_group and expose it in Format.metadata
Issue: androidx/media#2242
PiperOrigin-RevId: 740794206
(cherry picked from commit 0d60c5bf25a8725c21affa951409ba148394c526)
2025-04-12 21:08:36 +01:00
Copybara-Service
1ee030afb1 Merge pull request #2260 from MGaetan89:audiomanagercompat_log
PiperOrigin-RevId: 740752418
(cherry picked from commit 95fbecd0764851a857b7037d76277a9e0725475a)
2025-04-12 21:07:41 +01:00
michaelkatz
ef8f72d684 Set that any error during pre-warming disables and resets pre-warming
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)
2025-04-12 21:07:38 +01:00
michaelkatz
2939bfccbe Add support for RTSPT scheme in RtspMediaSource.Factory
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)
2025-04-12 21:02:40 +01:00
ibaker
1d2019b770 Add unsuitable audio output to to-string logic in EventLogger
PiperOrigin-RevId: 739875995
(cherry picked from commit 75a067a223330d869ecfc87bd170eaf00f55a866)
2025-04-12 21:02:40 +01:00
rohks
3c4410e967 Add language information for video tracks in BoxParser for Mp4 files
PiperOrigin-RevId: 738777635
(cherry picked from commit 2d4b37dc282dfde1aa8580c0adae45e7fe8d2a28)
2025-04-12 21:02:36 +01:00
rohks
d79d6b2b8b Fix KEY_TRACK_ID in MediaFormat returned by getTrackFormat()
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)
2025-04-12 21:02:20 +01:00
rohks
d920cf87a6 Fix parsing of language code in mdhd box
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)
2025-04-12 21:02:16 +01:00
Copybara-Service
963bae9dd8 Merge pull request #2235 from MGaetan89:add_CastPlayer_playlistMetadata
PiperOrigin-RevId: 738455260
(cherry picked from commit 2d1bcc77be3acd0a8297220f7564483c12db32b3)
2025-04-12 21:01:40 +01:00
rohks
dcb67102b9 Parse btrt box in BoxParser to get bitrate information for Mp4 files
PiperOrigin-RevId: 738370142
(cherry picked from commit 88da587b0a5742e31452d5b7609ef96c048095d0)
2025-04-12 21:00:30 +01:00
ibaker
75e28d82e3 Fix FLAC interactions with PBA 'remaining capacity'
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)
2025-04-12 21:00:30 +01:00
ibaker
673da97fde Update Format.pcmEncoding docs to include lossless compression
This field has been used for encoded FLAC data since ba8f55694a

PiperOrigin-RevId: 736811640
(cherry picked from commit fe8163838ed4adead705e2a537973d3c741f5d8e)
2025-04-12 21:00:30 +01:00
michaelkatz
57c82710ea Limit dynamic scheduling interval by the audio track buffer size
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)
2025-04-12 21:00:30 +01:00
tonihei
51efcad672 Merge branch 'release' into release-1.6.0 1.6.0 2025-03-27 12:55:05 +00:00
tonihei
fdbf2a48f7 Add missing 1.6.0 entry to GH bug template
PiperOrigin-RevId: 741120336
(cherry picked from commit f74abed9843dcfc75fe81ac88452e9eef5196f01)
2025-03-27 12:53:29 +00:00
tonihei
df3b138391 Update release notes for 1.6.0
PiperOrigin-RevId: 738443368
(cherry picked from commit a37e906a0a44e166a75a1d75b12c39685b0a5806)
2025-03-19 17:29:46 +00:00
tonihei
7c0fb628ac Version bump to Media3 1.6.0
PiperOrigin-RevId: 738421167
(cherry picked from commit ecad8a53577dc9c843a939e5528b2b41dec23cc4)
2025-03-19 17:29:46 +00:00
tonihei
05827ea5ed Avoid unsupported mock operation
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)
1.6.0-rc02
2025-03-19 13:53:29 +00:00
Googler
c558ae43c5 Fix a race condition in HttpEngineDataSource
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)
2025-03-18 18:01:40 +00:00
tonihei
8212b964d1 Exclude Xiaomi and OPPO devices from detached surface mode
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)
2025-03-18 18:01:40 +00:00
tianyifeng
bd104b1cc4 Consider audio output latency when source has ended
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)
2025-03-18 18:01:40 +00:00
tonihei
efb109dd88 Update release notes for 1.6.0-rc02
PiperOrigin-RevId: 737986781
(cherry picked from commit 0991dbcd7dfacc97a191c9053b8bdc59234447bd)
2025-03-18 18:01:37 +00:00
tonihei
dadd970f6e Version bump to Media3 1.6.0-rc02
PiperOrigin-RevId: 737948053
(cherry picked from commit b1068e47d35ac479f111a88fed870d1fdef52376)
2025-03-18 18:00:56 +00:00
Googler
25dc53551d Add CookieHandler support to HttpEngineDataSource.
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)
2025-03-18 18:00:56 +00:00
ibaker
53a3144f96 Rollback of 3b38a7a43b
PiperOrigin-RevId: 731248658
(cherry picked from commit a6debf49048f59544757df880b30a23ed88c277a)
2025-03-18 18:00:56 +00:00
Googler
89cfee6e31 Add CookieHandler support to HttpEngineDataSource.
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)
2025-03-18 18:00:56 +00:00
tonihei
8fa785fc27 Adjust dump files to different dumping logic
In particular, 796df136 and df489e2f are not part of the release branch
2025-03-18 12:27:04 +00:00
ibaker
5c1e0d964a Add 32-bit FLAC test files, and use them in some tests
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)
2025-03-18 11:39:46 +00:00