By using this setter, the duration of the background audio doesn't need
to be computed anymore. It will also repeat the audio track if the video
track is longer.
PiperOrigin-RevId: 737621668
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
Previously we only enable `SeekParameter.*_SYNC` for HLS when `EXT-X-INDEPENDENT-SEGMENTS` is set in the playlist. However, this condition can actually be loosened. To seek in HLS, we need to download the segment in which the resolved seek position locates under any circumstance. If `SeekParameter.PREVIOUS_SYNC` or `SeekParameter.CLOSEST_SYNC` is passed, and that segment happens to start with sync samples, then the seek can be done quicker with that adjusted seek position. And if that segment doesn't start with sync samples, then the behaviour will be the same as we set the adjusted seek position to the exact original position. But we still cannot safely enable `SeekParameter.NEXT_SYNC` as it will potentially cause the seeking to miss more content than seeking to the exact position.
Issue: androidx/media#2209
PiperOrigin-RevId: 737580861
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
Before this change, exporting a Composition with all looping sequences
would result in a runtime exception due to a divide-by-zero exception
in TransformerInternal.
PiperOrigin-RevId: 737568877
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
These are common in robolectric playback tests, because our
`ShadowMediaCodecConfig` always returns empty buffers when 'decoding'
audio.
PiperOrigin-RevId: 736836767
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
The spec technically allows to mark adaptation sets with the switching
property if they allow seamless switching with non-overlapping
segments. This is typically only used for compatible content (e.g.
different codecs), but the spec allows it to be used for other
content as well (e.g. different languages, roles). ExoPlayer's concept
of a TrackGroup only allows formats with the same language and role
flags to be merged, so we should check that before merging.
Issue: androidx/media#2222
#cherrypick
PiperOrigin-RevId: 736564055
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
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
This listener is used by apps to associate render timestamp and presentation
timestamp when using a SurfaceTexture, so this timestamp must match up with
what's set in `eglPresentationTimeANDROID`.
PiperOrigin-RevId: 736494784
This timeout can be very low in these tests because we are always
trying to connect to an in-process `MockWebServer`. With the default
timeout value any 'resource not found' tests which use a domain that
can't be connected to take the max timeout (between 8s and 16s depending
on the HTTP stack).
PiperOrigin-RevId: 736466854
This change uses the duration and byte count of the Xing frame, if
they're present, to estimate the bitrate of the stream. The seeking
will still be inaccurate (because we're doing CBR seeking in a VBR
stream), but it will be more accurate than basing the bitrate on the
first MP3 frame we read. It will also mean the duration reported is
accurate.
This change also ensures that if the Xing frame contains the number of
audio bytes but no ToC, the audio data length is still propagated into
the `XingSeeker` (and therefore into the `ConstantBitrateSeeker` too).
Issue: androidx/media#2194
PiperOrigin-RevId: 736100104
A problem was discovered in Composition demo app where after playing a composition using CompositionPlayer, pressing the "play" button again would not restart the playback. This issue has been resolved, just adding a test to make sure we're not missing any regressions.
PiperOrigin-RevId: 735793488
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
After this change, updates of the live HLS playlists are reflected
in the ad playback state. Interstitials are inserted into new
or existing ad groups according to the current ad playback state.
PiperOrigin-RevId: 735733207
Before this CL:
- MediaCodecVideoRenderer.onProcessedStreamChanged was called for the
first stream in CompositionPlayer.
- MediaCodecVideoRenderer.onProcessedStreamChanged was NOT called for
the first stream in ExoPlayer.setVideoEffects.
This discrepancy was adding some complexity to the code, making it less robust.
PiperOrigin-RevId: 735439320
This improves consistency by grouping it with other test builders and resolves a missing build rule, ensuring developers can properly use it for testing.
PiperOrigin-RevId: 735396181
This is a step towards merging setStreamStartPositionUs with
onInputStreamChanged, which makes sense as the start position can only
change on stream change.
PiperOrigin-RevId: 735309009
This is part of an effort to remove VideoSink.onRendererEnabled,
which is a step towards making the VideoSink interface renderer
agnostic. The plan is to merge onRendererEnabled, setStreamTimestampInfo
and onInputStreamChanged into a single method in VideoSink.
This change is a no-op refactoring
PiperOrigin-RevId: 735293983
We currently combine stopping the FGS and optionally removing the
notification in one method, which unnecessarily gates its logic on
checking the desired foreground state again. This causes a bug where
the notification should be removed (because shouldShowNotification
returns false), but stays visible because the service is allowed
to stay in the foreground and the notification removal code is not
triggered.
#cherrypick
Issue: androidx/media#2211
PiperOrigin-RevId: 735126704
Removed test that attempted to verify behavior when the lib-effect dependency is missing. This is because it fails when adding lib-transformer to test-util dependency. The introduction of lib-transformer brought in lib-effect as a transitive dependency, which conflicted with the test's expectation of the class not being present.
PiperOrigin-RevId: 734547629
This is a step towards unifying ShadowMediaCodecConfig for ExoPlayer and Transcoding tests.
The buffer size for ExoPlayer's CodecConfig is set to 150_000. This is because some test media has samples larger than 100kB. We can increase the buffer size for Transcoding-related codec configurations.
PiperOrigin-RevId: 734297632
When `forceTransformerToFail` is set to true, the builder will use a `FailingMuxerFactory` which creates a `FailingMuxer` that throws a `MuxerException` when attempting to write sample data. This ensures Transformer will fail as muxers are used for all cases (transmuxing and transcoding).
PiperOrigin-RevId: 734281681
These tests show the current behaviour:
1. Without customization: not seekable
2. With 'enable CBR' flag:
* File length known: seekable but duration very incorrect
* File length unknown: not seekable (even though the Xing frame
contains the number of bytes in the mp3 stream).
Follow-up test changes will:
1. Add a test for the cbr-always case for this file (branched from the
files submitted in this change).
2. Add a new similar test asset with no ToC but with trailing garbage
bytes, to verify that the length from the Xing frame is used.
Then follow-up implementation changes will update Mp3Extractor to use
duration and byte length from a Xing frame when falling back to CBR
seeking.
Issue: androidx/media#2194
PiperOrigin-RevId: 734164879
If feature is enabled, MediaCodecVideoRenderer will include the `MediaCodec.BUFFER_FLAG_DECODE_ONLY` flag when queuing decode-only input buffers. This flag will signal the decoder to skip the decode-only buffers thereby resulting in faster seeking.
PiperOrigin-RevId: 734152464
This is a step towards unifying ShadowMediaCodecConfig for ExoPlayer and Transcoding tests.
This change includes extracting encoder/decoder configurtion logic to a static method that can be called by `ShadowMediaCodecConfig.CodecImpl#configure()` and `TestUtil#addCodec()`.
This is a non-functional refactor.
PiperOrigin-RevId: 734137675