1567 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
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
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
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
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
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
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
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
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
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
tonihei
fa71bf229e Wait for first frame when using placeholder surface
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)
2025-03-18 11:20:44 +00:00
tonihei
e2017e35db Move decode-only and no surface logic inside VideoFrameReleaseControl
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)
2025-03-18 11:16:38 +00:00
tonihei
0a284f4927 Refine logic of when to skip placeholder surface buffers
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)
2025-03-18 11:09:27 +00:00
tonihei
1512b5b622 Clip start time to window duration when clipping
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)
2025-03-18 11:04:17 +00:00
ibaker
5957daadee Indicate MediaCodec FLAC decoder doesn't support 32-bit below API 34
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)
2025-03-18 11:03:35 +00:00
ibaker
9a91b2774e Add support for 32-bit FLAC files in the built-in FLAC extractor
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)
2025-03-18 11:03:31 +00:00
tonihei
a3f4b3dd1f Add toString to TrackGroup(Array)
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)
2025-03-18 11:01:58 +00:00
ivanbuper
97606094ca Add float PCM support to TrimmingAudioProcessor
This was requested in Issue: androidx/media#2191.

PiperOrigin-RevId: 735375746
(cherry picked from commit 06163f3dfaf9eb13d84790273179157e762122ed)
2025-03-17 14:02:16 +00:00
ivanbuper
d2703a12cc Add support for FLOAT_PCM in ChannelMappingAudioProcessor
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)
2025-03-17 14:00:22 +00:00
tonihei
766dbd497e Add util to obtain AudioManager
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)
2025-03-03 16:27:28 +00:00
ibaker
595fd48cd7 Disable subtitlesRespectClipping_multiplePeriods test on API 21
PiperOrigin-RevId: 732065230
(cherry picked from commit f8c3af52e9091db3f683c4661b53e2f92de6fbb4)
2025-03-03 16:27:28 +00:00
Copybara-Service
c66c221b28 Merge pull request #2190 from nift4:main
PiperOrigin-RevId: 731316955
(cherry picked from commit 366e5eccf889be2d88f126846ebc4395f0e5cff7)
2025-03-03 16:27:28 +00:00
ibaker
fd2e874b5d Rewrite ClearKey UUID to Common PSSH UUID in PSSH box on API < 27
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)
2025-03-03 16:27:27 +00:00
Copybara-Service
4d3f71a0c6 Merge pull request #2180 from nift4:main
PiperOrigin-RevId: 731276598
(cherry picked from commit ac1cf206c89ea656b5a88b807a178f4d3f94d9f0)
2025-03-03 16:27:27 +00:00
ibaker
f739e2d68c Suppress some instrumentation tests on older API levels
PiperOrigin-RevId: 731257575
(cherry picked from commit 20ea05063bcccec8b83c9848fc5b3dbf4edc290c)
2025-03-03 16:26:31 +00:00
tonihei
fc4112beee Move audio focus management to ExoPlayerImplInternal
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)
2025-03-03 16:26:31 +00:00
Copybara-Service
9052313245 Merge pull request #2113 from colinkho:lastrebufferinssp
PiperOrigin-RevId: 730919539
(cherry picked from commit 2c866ce50be132858d9cb4c30c174790577f7560)
2025-03-03 16:26:31 +00:00
ibaker
8b9e9203a1 Add missing call to adjustUuid in FrameworkMediaDrm
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)
2025-03-03 16:26:31 +00:00
Copybara-Service
a578d43324 Merge pull request #2115 from MGaetan89:use_objects_equals
PiperOrigin-RevId: 730860597
(cherry picked from commit cc44de8757501cab7e4bb70fd0b090c6dc9799e1)
2025-03-03 16:26:31 +00:00
tonihei
50f6bdd1fd Do not change audio capabilities for error recovery without context
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)
2025-03-03 16:26:31 +00:00
dancho
62ef83b68e MCVR: limit the number of consecutive dropped input frame headers
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)
2025-03-03 16:26:30 +00:00
tianyifeng
8e5368a807 Mask ExoPlayer.isLoading when it transitions to IDLE or ENDED states
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)
2025-03-03 16:26:30 +00:00
tonihei
88e7636ae0 Use different authorities for AssetContentProvider
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)
2025-02-18 09:42:24 +00:00
tonihei
3b897241d2 Increase timeout for AudioPositionAdvancingTest
500ms may not be enough to start playback on a slow device

#cherrypick

PiperOrigin-RevId: 726940099
(cherry picked from commit 792a2ae05dbade27d9cd5a8923a1f3cebf083a91)
2025-02-14 18:41:15 +00:00
rohks
d14807c836 Add contract tests for DRM and logging to MediaExtractorContractTest
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)
2025-02-14 18:41:15 +00:00
tonihei
be76766f95 Add dedicated EPII method to set volume
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)
2025-02-14 18:41:15 +00:00
tonihei
8bd1db5f2c Move DefaultSuitableOutputChecker operations to playback thread
PiperOrigin-RevId: 726879236
(cherry picked from commit e0ef6e51829dd1627d952d2677f532230cb2dbc9)
2025-02-14 18:41:15 +00:00
tonihei
41af00f100 Move unsuitable output path logic <API31 into SuitableOutputChecker
This avoids distributing the logic between multiple classes and
keeps ExoPlayerImpl simpler.

PiperOrigin-RevId: 726874038
(cherry picked from commit 1015ef8b565ed04e88a9c596798d294327d05536)
2025-02-14 18:41:15 +00:00
tonihei
841e27ae5c Move MediaMetricsListener creation and reporting off main thread
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)
2025-02-14 18:41:15 +00:00
tonihei
cd6e61d856 Send renderer settings messages to secondary renderers in ExoPlayer
They are currently only sent to the primary renderer.

PiperOrigin-RevId: 726864595
2025-02-14 04:06:36 -08:00
tonihei
12afdfbaea Improve placeholder value in StreamVolumeManager for muting
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
2025-02-14 02:28:34 -08:00
tonihei
385498c24e Move audio session id generation to playback thread
PiperOrigin-RevId: 726556015
2025-02-13 10:57:19 -08:00
dancho
22853a5c4c MCVR: fix dropped input buffer count
updateDroppedBufferCountersWithInputBuffers should receive
buffer timestamps before adjusting offset

PiperOrigin-RevId: 726473967
2025-02-13 07:17:41 -08:00
ibaker
12072f7248 Rename TestPlayerRunHelper.run(...) to advance(...)
This avoids a clash with the `run` keyword in Kotlin.

PiperOrigin-RevId: 726461032
2025-02-13 06:37:31 -08:00
dancho
38cfd7dc36 Add dropped input buffers to DebugTextViewHelper
The field is more relevant with the
`experimentalSetLateThresholdToDropDecoderInputUs` API.

PiperOrigin-RevId: 726383978
2025-02-13 02:10:57 -08:00
rohks
75607ac1eb Add tests for setDataSource APIs to MediaExtractorContractTest
Added remaining tests to cover all `setDataSource` APIs in `MediaExtractor`.

PiperOrigin-RevId: 725616816
2025-02-11 07:11:06 -08:00