We currently start the timeout as soon as the player enters
the target ad, but that ad hasn't loaded yet (= at the point
where we actively start waiting for it). And then we try to
clear the timeout at various places that mean we are no longer
waiting for this ad. This is very error-prone though because
there are a lot of places in the AdTagLoader that change the
AdPlaybackState and could mark the ad as skipped, failed or
loaded.
A much less error-prone way of clearing the timeout is not
even try to find all places that may revert the wait condition
and instead just check if we are still waiting at the point
of executing the timeout message.
PiperOrigin-RevId: 748291720
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
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
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
MediaCodec decoders sometimes output frames in
the wrong order. Make our asserts more permissive to
reduce noise in tests.
PiperOrigin-RevId: 747414696
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
This is a step towards unifying ShadowMediaCodecConfig structure to accommodate having both ExoPlayer and Transcoding codecs configuration.
This includes:
* Adding ability to configure encoders by calling `addEncoders(CodecInfo...)`
* A new factory method that takes specific encoders and decoders CodecInfos
* A new method `addCodecs(boolean, CodecConfig, CodecInfo...) that configures codecs with specified behavior by passing a `CodecConfig`.
This CL also includes migrating Transformer tests to ShadowMediaCodecConfig.
PiperOrigin-RevId: 747390451
The current instanceof check accidentally unpacks the child,
returning the inner period instead of the one passed to the source.
PiperOrigin-RevId: 746556825
This makes sure that the asset list is loaded about the
same duration before the ad start as on other platforms.
Further, interstitials in live streams are taken into
account when 3 target durations before the live window.
This enables the ads loader to preload such ads in a
future change. This may be indicated for live streams
that should play as close to the live edge as possible.
In such a case the buffered position may reach the start
of the ad only late. Preloading could help here to
decrease the performance requirements of ad servers.
PiperOrigin-RevId: 746521261
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
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
The stub, mediaNotificationManager and actionFactory fields were
already only allowed to be accessed on the main thread, so need to
lock any access to them. Also add a corresponding note to methods
that were already meant to be called on the main thread only, but
didn't have the corresponding note in the Javadoc yet.
PiperOrigin-RevId: 746440272
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
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
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
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
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
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
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
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
The previous name sounds a bit like it refers to the action of
'playing', rather than which button is shown (which is kind of the
opposite!).
PiperOrigin-RevId: 743908736