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
- 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
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
Earlier when gap is at the start of a sequence
it was automatically filled with silent audio.
Now setting forceAudioTrack flag is mandatory to
indicate that the gap at the start of a sequence
must be filled with silent audio.
PiperOrigin-RevId: 742625236
I could've add another test that seeks into the media before replying, but I
don't think fundamentally it's different from the one added.
I wish I could add one that replays while playing, but it'd be hard to match
the frames perfectly.
I'll add more timestamp based tests
PiperOrigin-RevId: 742229436
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
Previous assertion was incorrect. Per-frame initialization
vectors are written to the output stream in
`FragmentedMp4Extractor`
PiperOrigin-RevId: 742203717
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
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
This change also tightens `FakeVideoRenderer` to only 'handle' buffers
that are close to the current playback position.
This condition controls whether the renderer fires `onVideoSizeChanged`
and `onRenderedFirstFrame`, both of which should only be fired once the
frame has been 'released' to the screen, which in a real renderer
happens much closer to 'current position' than the existing 250ms of
`FakeRenderer.SOURCE_READAHEAD_US`.
A later change uses `VideoFrameMetadataListener` to test ExoPlayer
behaviour in scrubbing mode.
PiperOrigin-RevId: 740763283
For usage of instance of `DolbyVisionConfig` used in Muxer to support Dolby Vision codec, move `DolbyVisionConfig` file from extractor library to container library.
PiperOrigin-RevId: 740689000
It's unclear why the listeners would need access to the
PlaybackVideoGraphWrapper as there should always be only one. Also,
it's not common practice to pass the parent object to the listener in
media3 (see Player.Listener for example).
PiperOrigin-RevId: 740686007
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
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
We currently don't have audio sink dumps for non raw audio, but this
change will make it more clear if we do in future (e.g. for testing
audio offload).
PiperOrigin-RevId: 740330118
This is a step towards unifying ShadowMediaCodecConfig structure to accommodate both ExoPlayer and Transcoding codecs configuration.
This change abstracts the codec information to a separate `CodecInfo` class. This allows having codecs with the same information configured with different configurations (passthrough/frame-dropping, decoder/encoder). It also does the following:
* Replaces the map of default codecs with public static final CodecInfo constants for each codec.
* Modifies the ShadowMediaCodecConfig constructor to accept a set of CodecImpls instead of mime types.
* Updates factory methods to reflect the constructor change.
* Updates addSupportedMimeTypes to addDecoder, taking a CodecInfo instead of a mimeType.
This is a non-functional change.
PiperOrigin-RevId: 739857883
We currently assume SW codecs are capable of playing all resolutions
and frame rates up to their declared supported maximum values, even
though the are likely not able to keep up playback smoothly for higher
resolutions. For HW codecs we can check PerformancePoints to declare
them as EXCEEDS_CAPABILITIES if they technically support a format but
are not performant enough. We can do the same for SW codecs by
checking getAchievableFrameRatesFor.
PiperOrigin-RevId: 739253653