1666 Commits

Author SHA1 Message Date
dancho
910b6ab884 Do not flush c2.mtk decoders when outputting to a videoSink
Flushing a c2.mtk decoder that outputs to a SurfaceTexture often
fails and leaves the SurfaceTexture's BufferQueue in an unrecoverable
state. Release the codec instead.

PiperOrigin-RevId: 751006875
2025-04-24 08:39:46 -07:00
michaelkatz
2e20d35c3d 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 supporting AudioSink#getAudioTrackBufferSizeUs().

This CL specifically removes the bypass for the static default for if rendering to end of stream. For scenarios with an intermediary layer between MediaCodecAudioRenderer and DefaultAudioSink, there can be potential underruns even though at the MediaCodecAudioRenderer it has nothing else to write.

PiperOrigin-RevId: 750986145
2025-04-24 07:26:04 -07:00
tonihei
6ce9fdee8c Add test and formatting fixes 2025-04-24 12:52:22 +01:00
Colin Kho
25feac7664 Add ForwardingTrackSelection to allow access to the underlying instance 2025-04-24 12:26:31 +01:00
ibaker
4189a7c8bd Add ExoPlayer.isScrubbingModeEnabled
This helps integration with `PlayerControlView` in a follow-up change,
where we need to reliably know if scrubbing mode is still enabled (in
case someone else disables it after we enable it).

PiperOrigin-RevId: 750913644
2025-04-24 02:35:14 -07:00
kimvde
d9a92e2586 Remove references to defaultVideoSink from inputVideoSink
This makes the chain structure (InputVideoSinks, then VideoGraph, then
DefaultVideoSink) clearer.

PiperOrigin-RevId: 750910247
2025-04-24 02:22:25 -07:00
tonihei
50345b03aa Fix memory leak caused by removing wrong period from List
MergingMediaSource started keeping references to all MediaPeriods
it ever created since 191bc094a5 as the cleanup step attempted
to remove the outer merged period from the list instead of the
inner period of child source.

Issue: androidx/media#2338
PiperOrigin-RevId: 750566825
2025-04-23 06:21:48 -07:00
tonihei
a7c897003c Fix bug where a MaskingMediaSource never throws prepare error
We suppressed the direct error throwing ability in <unknown commit>
to avoid throwing errors later in the playlist too early. This
logic got moved to MaskingMediaSource in <unknown commit>, but its
original purpose was no longer needed when the player stopped
calling this method directly in <unknown commit>.

This left a pending bug that any other usage of MaskingMediaSource
(e.g. within AdsMediaSource) no longer forwards source prepare
errors.

Issue: androidx/media#2337
PiperOrigin-RevId: 750537823
2025-04-23 04:13:30 -07:00
kimvde
4d68243158 Only join video graph output in playlist mode.
DefaultVideoSink.join() was called when join() was called on the
InputVideoSink. This makes sense in playlist mode but we shouldn't
join if the VideoGraph output is considered as a single clip.

This change is no-op. Indeed, for CompositionPlayer, the
allowedJoiningTimeMs is set to 0, so that join doesn't have any effect.

PiperOrigin-RevId: 750238085
2025-04-22 10:15:18 -07:00
kimvde
fe10ca2c9a Start and stop video rendering from CompositionPlayer
Before, we were starting and stopping video rendering when the
renderers were started/stopped. This doesn't work for multi-video
sequences though because we shouldn't stop and start rendering at every
MediaItem transition in any of the input sequences.

PiperOrigin-RevId: 750206410
2025-04-22 08:43:21 -07:00
tonihei
1c855a8abf Remove unneeded SDK checks
PiperOrigin-RevId: 750172684
2025-04-22 06:48:41 -07:00
Copybara-Service
661effcddd Merge pull request #2323 from DolbyLaboratories:dlb/ac4-profile/dev
PiperOrigin-RevId: 750171380
2025-04-22 06:43:36 -07:00
Copybara-Service
4d9f47920a Merge pull request #2285 from MGaetan89:deprecate_util_sdkint
PiperOrigin-RevId: 750142132
2025-04-22 04:53:39 -07:00
tianyifeng
7f6ddef502 Enable DownloadHelper to create DownloadRequest with timeRange
PiperOrigin-RevId: 748722156
2025-04-17 10:14:04 -07:00
tonihei
c4c3e5e0c8 Move getMaximumEncodedRateBytesPerSecond to a shared public util
This makes it more easily reusable.

Issue: androidx/media#2339
PiperOrigin-RevId: 748713531
2025-04-17 09:52:18 -07:00
Gaëtan Muller
9b2e1cfca0 Deprecate Util.SDK_INT in favor of Build.VERSION.SDK_INT
`Util.SDK_INT` was introduced to be able to simulate any SDK version during tests.
This is possible by using Robolectric's `@Config(sdk)` annotation.
All usages of `Util.SDK_INT` have been replaced by `Build.VERSION.SDK_INT`.

This is a similar change to what was done in #2107.
2025-04-17 15:55:23 +01:00
bachinger
fd8547fc3a Ensure ad playback state and timeline are in sync
Before this change a timeline update of a live content
source has produced a timeline refresh before passing
the timeline to the ads loader. When in such a case
the ads loader updates the ad playback state, a
second timeline refresh is trigger that then
includes the updated ad data also. This can result
in a timeline being pulished with stale ad information.

This change prevents this by introducing a boolean
return value that requires the ads loader to signal
whether the ad playback state has been passed back
to the source. This ensures that an update of
timeline and ad playback state produces a single
timeline update and is published in sync.

PiperOrigin-RevId: 748288650
2025-04-16 07:38:23 -07:00
tonihei
70e7121a51 Make some audio processors public
ChannelMappingAudioProcessor, TrimmingAudioProcessor and
ToFloatPcmAudioProcessor are currently package-private even
though they might be useful in custom audio processing chains
or custom version of audio sinks.

Issue: androidx/media#2339
PiperOrigin-RevId: 747857815
2025-04-15 07:03:04 -07:00
tonihei
9cc7dd0dbe Ensure DefaultAudioSink doesn't store non-application Context
The Context is currently passed right down from ExoPlayer.Builder
without ever converting it to the application context. This may
cause memory leaks if a Player is kept across activities/service
lifecycles.

PiperOrigin-RevId: 747835487
2025-04-15 05:40:56 -07:00
tonihei
21514ba8e8 Add missing check for TRACK_TYPE_NONE before accessing selections
The track selections will be null if the track type is NONE even
if the renderer is enabled.

PiperOrigin-RevId: 747818128
2025-04-15 04:38:14 -07:00
bachinger
117db48907 Assert preload looper is not the main looper
Issue: androidx/media#2315
PiperOrigin-RevId: 747809915
2025-04-15 04:08:01 -07:00
shahddaghash
a2265f1dae Replace deprecated ShadowMediaCodecConfig factory methods
This is part of the efforts for adding encoder support for ShadowMediaCodecConfig to use it for ExoPlayer and Transcoding tests.
* Replaced `ShadowMediaCodecConfig#forAllSupportedMimeTypes()` calls with `ShadowMediaCodecConfig#withAllDefaultSupportedCodecs()`
* Replaced `ShadowMediaCodecConfig#withNoDefaultSupportedMimeTypes() calls with `ShadowMediaCodexConfig#withNoDefaultSupportedCodecs()`

PiperOrigin-RevId: 747413859
2025-04-14 07:46:13 -07:00
tonihei
68538029c9 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
2025-04-11 12:45:01 -07:00
tianyifeng
344f249511 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

#cherrypick

PiperOrigin-RevId: 746490375
2025-04-11 09:34:57 -07:00
ybai001
2500d91848 Add KEY_PROFILE, KEY_LEVEL support for AC-4 2025-04-10 09:39:23 +08:00
dancho
a78d0c3994 Rollback of 73fa820828
PiperOrigin-RevId: 745618560
2025-04-09 09:25:55 -07:00
claincly
4bfa154acd Allow replays with CompositionPlayer
PiperOrigin-RevId: 745536073
2025-04-09 04:54:48 -07:00
tianyifeng
71fb3ad5a5 Fix the parameter passed to AudioSink.InitializationException
We used to pass `audioTrackConfig.encoding` as the `bufferSize` parameter to `AudioSink.InitializationException`, for which this CL is supposed to correct. But `encoding` is a useful information for logging anyway, thus an `encoding` parameter is also added to `AudioSink.InitializationException` constructor, so now we pass both `encoding` and `bufferSize` parameters.

PiperOrigin-RevId: 745534997
2025-04-09 04:50:10 -07:00
tianyifeng
eae886fe28 Add Factory for SegmentDownloader implementations
PiperOrigin-RevId: 745530254
2025-04-09 04:33:27 -07:00
claincly
e11a8a1b19 Fix playback not transition into next mediaItem
This is because the replay cache needs to clear the cache after one mediaItem is fully played.

That is, if the last two frames are cached, we need to wait until they are both rendered before
receiving inputs from the next input stream because the texture size might change. And when the
texture size changes, we teardown all previous used textures, and this causes a state confusion
in the shader program in that, the cache thinks one texture id is in-use (because it's not released)
but the baseGlShaderProgram texturePool thinks it's already free (as a result of size change)

Also fixes an issue that, if replaying a frame after EOS is signalled, the EOS
signal is lost because we flush the pipeline.

PiperOrigin-RevId: 745191032
2025-04-08 10:08:34 -07:00
ibaker
83efd8eb66 Add ScrubbingModeParameters
This adds the option to disable certain track types during scrubbing,
with audio and metadata disabled by default.

The tracks are disabled by modifying the `TrackSelectionParameters`,
but in a way that is invisible to
`Player.getTrackSelectionParameters()` and
`Player.Listener.onTrackSelectionParametersChanged`. This allows us to
clearly reason about what should happen if
`Player.setTrackSelectionParameters(...)` is called during scrubbing
mode. The **side effects** of disabling the tracks are all visible
through `Player.Listener` and `AnalyticsListener` (renderer disabled,
decoder released, `onTracksChanged`, etc.).

PiperOrigin-RevId: 743961632
2025-04-04 08:58:44 -07:00
Googler
feae2dadeb Adds getChannelOutputConfig() to AudioTrackProvider.
PiperOrigin-RevId: 743577038
2025-04-03 08:42:07 -07:00
dancho
036bed3632 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
2025-04-03 06:31:32 -07:00
michaelkatz
8327a2a52d 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
2025-04-03 04:15:15 -07:00
kimvde
18e9a3fe36 Rename VideoSink.onStarted/Stopped
start/stopRendering better reflects what the method does.

PiperOrigin-RevId: 743493973
2025-04-03 03:42:57 -07:00
tonihei
989e9f9e84 Remove remaining synchronized keywords from EPII
These are needed for the `waitUninterruptibly` handling, which is
really just waiting for a condition to become true on another thread
with a timeout, as well as Clock and interrupt handling.

We already have ConditionVariable that serves this purpose, which
has methods with a timeout and with interrupt handling. Adding
another version of the call with both timeout and interrupt handling
allows to replace the EPII manual code. The ConditionVariable methods
were also missing the clock calls to signal a wait operation.

PiperOrigin-RevId: 743214709
2025-04-02 11:30:04 -07:00
ibaker
a9c0349214 Standardize percentage calculations
This is a follow-up to 72f5df582a

PiperOrigin-RevId: 743173295
2025-04-02 09:46:15 -07:00
tonihei
0dd43b0183 Reduce 'synchronized' usage in EPII by making variable single thread
EPII currently uses 'synchronized' for two purposes:
 1. `waitUninteruptably` to ensure the condition checks and
    `wait` calls are atomic + the calls on the playback thread
    that update these conditions to `notifyAll`.
 2. Access to the `released` field that is used a condition
    for `waitUninterruptibly` but otherwise only accessed on the
    app thread.

We can remove the second usage by making the `released` variable
more clearly single thread on the app thread (including renaming to
make it obvious as this is the only variable in this class accessed
on that thread). The `waitUninterruptly` call for `release` can use
an `AtomicBoolean` like the other two calls to this method.

This also fixes a potential bug where a release timeout would leave
the `released` field as `false`, meaning future calls to these other
methods wouldn't be blocked early.

PiperOrigin-RevId: 743156035
2025-04-02 08:54:29 -07:00
ibaker
0517cea4d2 Add new EPI method for when only the suppression reason has changed
This also fixes the 'unsuitable output' logic incorrectly overriding
the `@PlayWhenReadyChangeReason` when only the playback **suppression**
state has changed.

PiperOrigin-RevId: 743148739
2025-04-02 08:32:08 -07:00
michaelkatz
9e80d6d263 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
2025-04-02 04:47:32 -07:00
ibaker
d315d90f7a Add scrubbing mode API to ExoPlayer
This initial version prevents incoming seeks from pre-empting
in-progress seeks, allowing more seeks to complete when the scrubber
bar is dragged quickly back and forth.

More scrubbing optimizations will be added in follow-up changes.

PiperOrigin-RevId: 743052527
2025-04-02 03:00:05 -07:00
bachinger
c95544156d Clip live periods that get a duration and end position
When an ad is inserted into a live period with an unset
duration, the live period needs to be wrapped with a
`ClippingMediaPeriod` and then actually be clipped to
the end position when the duration gets known. Without
this the renderers will never see an EOS which prevents
the reading/playing period from advancing.

In the case of a server side inserted ad on the other
hand, the actual clipping needs to be prevented to
keep the current behavior for SSAI streams. In an SSAI
stream, an ad inserted before the current position should
not produce a snap back to the newly inserted ad. This is
currently prevented in both places, when the updated
timeline is handled to not disable the renderers, and when
the `mediaPeriodQueue` updates the queued periods. This
behaviour is preserved to not create side effects of this
change.

PiperOrigin-RevId: 742642715
2025-04-01 04:46:31 -07:00
kimvde
f2d644b7b4 PlaybackVideoGraphWrapper: update listener logic for multi sequence
- Only have the primary sequence renderers listen to
PlaybackVideoGraphWrapper events. These events only need to be
forwarded to a single ExoPlayer instance.
- Set the DefaultVideoSinkListener only once.

PiperOrigin-RevId: 742636455
2025-04-01 04:18:39 -07:00
kimvde
595b75b7d3 Deduplicate some of the calls to DefaultVideoSink methods
Some DefaultVideoSink methods are called once per sequence, but this
doesn't make sense as the DefaultVideoSink is connected to the
VideoGraph output. This CL calls the DefaultVideoSink method only for
the primary sequence.

The other problematic DefaultVideoSink method calls will be moved in
follow-up CLs.

This is part of the effort to prepare PlaybackVideoGraphWrapper for
multi-sequence.

PiperOrigin-RevId: 742625589
2025-04-01 03:42:22 -07:00
kimvde
f8b1dcc33b Move VideoSink config to dedicated method
This is  to improve readability of MediaCodecVideoRenderer.onEnabled

PiperOrigin-RevId: 742246092
2025-03-31 06:40:12 -07:00
claincly
ff6537d69b Fix a bug that video effects are added twice
The tests passed because of an issue in chaining. The chaining listener allows
self-looping, i.e. the producer and the consumer of a frame could be the same
instance. Like an effect chain of `a -> a -> b` This didn't fail any test
before, because the chaining is rectified when connecting a to b, but it should
have failed when connecting a to a.

PiperOrigin-RevId: 742215700
2025-03-31 04:22:18 -07:00
dancho
73fa820828 Skip decoder input buffers for encrypted content
Previous assertion was incorrect. Per-frame initialization
vectors are written to the output stream in
`FragmentedMp4Extractor`

PiperOrigin-RevId: 742203717
2025-03-31 03:34:09 -07:00
kimvde
427daef350 Remove VideoSink.setWakeUpListener
This is the last Renderer reference in VideoSink

PiperOrigin-RevId: 742189332
2025-03-31 02:26:56 -07:00
tianyifeng
72f5df582a Improve the precision of percentDownloaded in Downloaders
We don't require high precision in the calculation of `percentDownloaded` for `Downloader.ProgressListener.onProgress` though, when `byteCached == contentLength`, we hope the `percentDownloaded` to be `100f` (rather than `99.99999f`). The result of `byteCached * 100f` can be less precise as the floating-point numbers are sparser when the value is far from zero. For example, if `byteCached == 812345L`, then the `byteCached * 100f` will become `81234496` (value checked by `BigDecimal`).

PiperOrigin-RevId: 741895445
2025-03-29 16:47:31 -07:00
michaelkatz
a4f5f67d7e 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-03-27 11:03:49 -07:00