The output of CompositionPlayer should be considered as a single clip
(not a playlist) so we should only propagate the first stream change
event in that case.
PiperOrigin-RevId: 752661523
Previously a stream error from one playlist item was incorrectly
preserved when switching to the next one, resulting in playback hanging.
Issue: androidx/media#2328
PiperOrigin-RevId: 752624979
Before this CL, the buffer adjustment (which allows to convert from
ExoPlayer time to VideoGraph time) was added to the frame timestamps
before feeding them to the VideoGraph, and then subtracted at the
VideoGraph output. The playback position and stream start position used
for rendering were in ExoPlayer time.
This doesn't work for multi-sequence though because the adjustment might
be different depending on the player (after a seek for example).
To solve this problem, this CL handles rendering in VideoGraph time
instead of ExoPlayer time. More concretely, the VideoGraph output
timestamps are unchanged, and the playback position and stream start
position are converted to VideoGraph time.
PiperOrigin-RevId: 752260744
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
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
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
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
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
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
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
`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.
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
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
The current instanceof check accidentally unpacks the child,
returning the inner period instead of the one passed to the source.
PiperOrigin-RevId: 746556825
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
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
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
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
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
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