To do this, refactor stream start position handling so that
VideoFrameRenderControl is only passed a start position when it should
be applied, and therefore doesn't need to take a timestamp associated
with each start position anymore
PiperOrigin-RevId: 697544416
From [ the last change in `DefaultPreloadManagerTest`](2b54b1ebbe), the preloadManager began to use a separate `preloadThread` in `release_returnZeroCount_sourcesAndRendererCapabilitiesListReleased`, which unveils a bug in `PreloadMediaSource`. When `PreloadMediaSource.releasePreloadMediaSource` is called, `preloadHandler` will post a `Runnable` on the preload looper to release the internal resources. Before this `Runnable` is executed, it is possible that the [`stopPreloading`](https://github.com/androidx/media/blob/main/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java#L442) method is executed just as the result of preloading has completed. This is expected to remove the posted `Runnable`s for further preloading, however, the posted `Runnable` for releasing will also be removed from the message queue.
Ideally we should use `postDelayed(runnable, token, delayMillis)` to post the runnables so that the token will be useful to identify which messages to remove in `removeCallbacksAndMessages(token)`, but that `postDelayed` method is only available from API 28. So in this change we are using a separate handler for releasing, and then the call of `preloadHandler.removeCallbacksAndMessages` won't impact the runnable for releasing.
#cherrypick
PiperOrigin-RevId: 696894483
This method returns a `PersistableBundle` containing metrics data for the current media container. The bundle includes attributes and values for the media container, as described in `MediaExtractor.MetricsConstants`.
PiperOrigin-RevId: 696893276
The new callback allows an app to read data from the content
timeline to populate the `AdPlaybackState`. To avoid a deadlock
between the `AdMediaSource` waiting for the `AdPlaybackState` and
the app waiting for the content `Timeline`, a boolean flag
`useLazyContentSourcePreparation` is introduced to tell the
`AdsMediaSource` to prepare the content source immediately
to make the `Timeline` available.
A unit test verifies that in none of the cases (lazy preparation or
immediate preparation) a `Timeline` without ad data is leaked to the
caller. This ensures that in the case of a preroll, the player won't
initially and accidentally read content media data before starting to
load the preroll ad. While the content source is prepared early, no
content media period must be created before the preroll starts.
PiperOrigin-RevId: 696885392
ISO/IEC 23001-8 has been withdrawn. The corresponding definition for channel configuration is available in ISO/IEC 23091-3. Update the comment to reflect this change.
The content in Issue: androidx/media#1863 has every sample incorrectly marked as a
sync sample in the MP4 metadata, which results in flushing the
re-ordering queue on every sample, so nothing gets re-ordered, so the
subtitles are garbled.
There are currently two "uses" for this call on every keyframe:
1. It offers a safety valve if we don't read a `maxNumReorderSamples`
value from the video. Without this, the queue will just keep growing
and end up swallowing all subtitle data (similar to the bug fixed by
39c734963f).
2. When we do read (or infer) a `maxNumReorderSamples` it means we can
emit samples from the queue slightly earlier - but this is pretty
marginal, given i think the max possible value for
`maxNumReorderSamples` is 16, so the most benefit we would get is 16
frames (~0.53s at 30fps) - in most cases we will have more than 0.5s
of buffer ahead of the playback position, so the subtitles will still
get shown at the right time with no problem.
(1) is resolved in this change by setting the queue size to zero (no
reordering) if we don't have a value for `maxNumReorderSamples`.
(2) has minimal impact, so we just accept it.
We may be able to inspect the NAL unit to determine IDR vs non-IDR
instead - we will consider this as a follow-up change, but given the
minimal impact of (2) we may not pursue this.
#cherrypick
PiperOrigin-RevId: 696583702
- Rename a few methods/variable to improve readability.
- Refactor how video size changes are tracked. This will simplify the
upcoming logic to refactor the timestamp logic in
VideoFrameRenderControl because we will use the same logic for
outputVideoSize and for outputStreamStartPositionUs.
PiperOrigin-RevId: 696026515
Earlier watchdog timer was started only after all the tracks are
added. For the cases where export is stuck before adding tracks,
the export would hang forever and will not timeout automatically.
With the changes, watchdog timer is started as soon as export is
started/resumed. Now if the pipeline is stuck before writing any samples,
it will timeout and report error to the caller.
Existing test case: c35a9d62ba/libraries/transformer/src/test/java/androidx/media3/transformer/MediaItemExportTest.java (L996)
PiperOrigin-RevId: 695781654
The behaviour was changed in 1.4.0 with 0f42dd4752,
so that the buffer timestamp is compared to `outputStartTimeUs` when
deciding whether to discard a "decode only" buffer before decoding
(instead of the deprecated/removed `isDecodeOnly` property). This breaks
when the buffer timestamp is `TIME_END_OF_SOURCE` (which is
`Long.MIN_VALUE`), because `TIME_END_OF_SOURCE < outputStartTimeUs` is
always true, so the end-of-stream buffer is never passed to the decoder
and on to `TextRenderer` where it is used to
[set `inputStreamEnded = true`](40f187e4b4/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/TextRenderer.java (L434-L436))
and so playback hangs.
#cherrypick
Issue: androidx/media#1863
PiperOrigin-RevId: 695767247
Implemented `getCachedDuration()` to provide an estimate of cached data in memory and `hasCacheReachedEndOfStream()` to indicate if the cache has reached the end of the stream.
Note: The Javadoc for the newly added methods closely follows that of the platform `MediaExtractor`. While the current implementation always uses a cache and therefore never returns `-1` from `getCachedDuration`, this leaves room for future changes should caching behavior or conditions evolve.
PiperOrigin-RevId: 695694460
A skeleton implementation that doesn't actually return decoded frames.
In the current state, we use ExoPlayer to seek to a position, and
ExoPlayer.setVideoEffects to record the presentation time selected.
Seeking and processing frames are synchronized via ListenableFuture
callbacks.
PiperOrigin-RevId: 695691183
In some cases, callers will need to pass in both BitmapLoader and Codec.DecoderFactory without specifying a custom MediaSource.Factory. Omitting the annotation will result in NULL_FOR_NONNULL_TYPE compilation errors in Kotlin.
PiperOrigin-RevId: 695481606
This is because the method is called for each media item, the current name
implies that the method is only called once for all videos in a sequence.
PiperOrigin-RevId: 695332916
This method will replace the current estimation mechanism in place on
`getSpeedAdjustedTimeAsync()`, which relies on heuristics from previous
output rates and depends on the state of the `AudioProcessor`. The new
static method should be considerably more accurate.
PiperOrigin-RevId: 694607264
This ensures it works correctly when there are multiple SEI messages per
sample and the max size is set from e.g. H.264's
`max_num_reorder_frames`.
PiperOrigin-RevId: 694526152
The `RendererCapabilities` and `TrackSelector` objects are accessed on the preload thread during the preloading, when releasing them, they need to be released on the same thread. Otherwise, it is possible that they have already released on the application thread, while the PreloadMediaSource still tries to access them on the preload thread before the source is released.
#cherrypick
PiperOrigin-RevId: 694173131
Note: `androidx.media3.common.DrmInitData` is returned instead of the platform `android.media.DrmInitData` because the platform class has a package-private constructor, making it impossible to implement the abstract class outside the platform.
PiperOrigin-RevId: 694096542
Changed the dependency of `lib-common` in `lib-ui` from an `implementation` dependency to an `api` dependency. This change ensures that classes and interfaces from `lib-common` used in the public API of `lib-ui` are correctly exposed to consumers of `lib-ui`.
For example, `PlayerView implements AdViewProvider` where the latter is from `androidx.media3.common.AdViewProvider`.
PiperOrigin-RevId: 693734349
Enable transformer to transmux into alternative sample MIME types.
For example, some Dolby Vision profiles have a backwards-compatible
AVC or HEVC layer. MV-HEVC is backwards compatible with HEVC.
This change enables Transformer to transmux into the backwards compatible
format to improve compatibility with legacy APIs such as
MediaMetadataRetriever.
PiperOrigin-RevId: 693667597
All instances of PlaybackVideoGraphWrapper use the same
VIDEO_FRAME_PROCESSOR_FACTORY_SUPPLIER which uses the same
DefaultGlObjectsProvider.
Each call to DefaultGlObjectsProvider.release() releases
all previously created EGLContexts.
Lazily create a new DefaultGlObjectsProvider for each
DefaultVideoFrameProcessor (not one per factory).
PiperOrigin-RevId: 693658458
The tests became more flaky after 76e4abe428, likely because playback
was able to start slightly earlier, exaggerating any existing race
conditions. Fix the flakiness by letting all tests with subtitle
parsing wait until all data is fully loaded before starting to play.
PiperOrigin-RevId: 693380656
When a new media session sets media button preferences, we need to
"translate" them back to a custom layout to ensure the user preferences
are represented as closely as possible when the controller uses the
old button placement rules.
PiperOrigin-RevId: 693306153
The method currently modifies the input Bundle, but it's easier to
reason about it if the method is side-effect free and the places
that need to modify a Bundle do this after calling the method.
PiperOrigin-RevId: 693288031
Implemented `setLogSessionId(LogSessionId)` and `getLogSessionId()` methods.
Note: The `LogSessionId` is currently **not** forwarded to `MediaParser`, but this will be addressed once `MediaParser` can be used to configure `MediaExtractorCompat`.
PiperOrigin-RevId: 692945255
* Provide a helper Composable for remembering the state instance and launching the listening coroutine that observes the changes in the Player
* Add an example to demo-compose of using Shuffle- and Repeat- ButtonStates inside a Shuffle- and RepeatButton Composable.
* Reformat the MainActivity usage of `Shuffle` and `Repeat` buttons to form extra Player Controls and combine Prev/Play-Pause/Next with Shuffle/Repeat (Minimal controls + Extra controls = `PlayerControls`)
PiperOrigin-RevId: 692939825
The test has been moved to an instrumentation test as it relies on APIs that vary by SDK version. Robolectric’s emulation lacks sufficient realism in some cases, which impacts test accuracy. By using an instrumentation test, we ensure that the tests run in a real Android environment, providing reliable results for SDK-dependent APIs.
PiperOrigin-RevId: 692933259
Also move the `lint.xml` config which disables the `NewApi` check from
`lib-session` to the existing top-level file, and limit it to cover all
Robolectric tests by path matching.
Follow-up to 76db936d68
PiperOrigin-RevId: 692913646
This change keeps getSurfaceForCodec and hasSurfaceForCodec in sync.
Before this change when ExoPlayer is configured with setVideoEffects
and no display surface, codecs that need Set Output Surface Workaround
would not be initialized because hasSurfaceForCodec always returns false
PiperOrigin-RevId: 692900899
Restructured sample metadata management in `MediaExtractorCompat` to maintain a queue of `SampleMetadata` objects, each containing `timeUs`, `flags`, `size`, and `trackIndex`, rather than storing only track indices.
Introduced a pooling mechanism for `SampleMetadata` to reduce object allocation and improve memory efficiency. The new `SampleMetaDataQueue` centralizes metadata for easier access and management, eliminating the need to allocate a buffer or peek into the `SampleQueue` to retrieve sample metadata.
This change does not change existing behavior, it optimizes the internal structure, and existing tests already verify the relevant APIs.
PiperOrigin-RevId: 692285581
This CL adds utility methods to obtain sample-aligned timestamps from a
`SpeedProvider` to solve in a unified way the issues arising from
conversions between sample positions and microseconds.
The new utility methods will also help with the implementation of a
static method like `getDurationAfterProcessorApplied()` that will remove
the need for thread synchronization between the video and audio pipeline
for speed changing effects.
PiperOrigin-RevId: 692233318
If audio processors report a drifting position, we currently update
the media position parameters to correct this drift. However, this
means we pass in the wrong value to
audioProcessorChain.getMediaDuration, which reuqires the time since
the last flush.
To fix this problem, we can instead save the drift seperately and
apply it where needed.
PiperOrigin-RevId: 692202219
Also makes muxer shift the first video timestamp to zero, if it's not.
The trim position should respect the media timeline.
For example in a video that is 10s long (without edit list), if an edit list
adds 1_000ms to each video sample, and trimming 100ms, here's the expected:
- The video duration is 10.9s (`10s + 1s edit - 0.1s trim`)
- The first video frame time would be at 0.9s (`1s edit - 0.1s trim`)
PiperOrigin-RevId: 692187399
* Provide a helper Composable for remembering the state instance and launching the listening coroutine that observes the changes in the Player
* Add an example to demo-compose of using Previous- and Next- ButtonStates inside a Previous- and NextButton Composable.
* Reformat the MainActivity usage of `Previous`, `PlayPause`, `Next` buttons to form Minimal Player Controls
PiperOrigin-RevId: 691943147
Provide a helper Composable for remembering the state instance and launching the listening coroutine that observes the changes in the Player
Add an example to demo-compose of using PlayPauseButtonState inside a PlayPauseButton Composable.
The smart State object has been deemed a preferred solution over collecting Flows due to queuing/timing/buffering limitations. Instead, it uses the new `Player.listen` suspending extension function to catch the relevant events.
PiperOrigin-RevId: 691879975
This affects both `AnalyticsListener` and `MediaSourceEventListener`
This was introduced by d051b4b993
Also fix a missing 'load started' event for HLS media playlists (this
was also introduced by d051b4b993).
PiperOrigin-RevId: 691580183
Replaced the custom `LibraryLoader` instance with `OpusLibrary.isAvailable()` to verify the library loading. This simplifies the code by leveraging the existing library loading mechanism.
#cherrypick
PiperOrigin-RevId: 691457871
Using frames instead of bytes helps simplify the processing logic for
the component and will help with the move towards sample-based
`SpeedProvider`s. By using frames, we also abstract away the complexity
related to sample encoding.
This is a non-functional refactor.
PiperOrigin-RevId: 691444106
The overload that takes a `Format` is preferred, because it can detect
SEI NAL units in Dolby Vision tracks too.
Submitting this in a separate change so we can avoid cherry-picking it
into `1.5.0-rc01`, otherwise it would naturally be part of
27371db225.
Issue: androidx/media#1820
PiperOrigin-RevId: 691408725
Previously, `getTrackFormat()` in `MediaExtractorCompat` returned a `MediaFormat` without setting `MediaFormat.KEY_DURATION`. With this change:
- `MediaFormat.KEY_DURATION` is set based on the track's duration, if available.
- If the track duration is unset, the duration from the seek map is used as a fallback.
- When neither duration is set, `MediaFormat.KEY_DURATION` remains unset.
This ensures that `MediaFormat.KEY_DURATION` is populated when possible, enhancing duration information availability.
PiperOrigin-RevId: 691395114
This method will likely be removed in the next release, and is currently
only needed from within the `source` package.
#cherrypick
PiperOrigin-RevId: 691351449
This change ensures that the test uses `assumeTrue` to avoid failures when the `libiamf` library is not pre-built.
#cherrypick
PiperOrigin-RevId: 691333564
The logic in assumeFormatsSupported assumes that portrait videos are
always rotated before encoding but that's not the case when portrait
encoding is enabled.
PiperOrigin-RevId: 691042881
In some cases, the streamOffsetUs was passed to
VideoFrameReleaseControl.getFrameReleaseAction() but it should be the
streamStartPositionUs.
PiperOrigin-RevId: 691040172
When transitioning to the next media position parameter checkpoint
we estimate the position because the audio processor chain no longer
provides access to the actual playout duration.
The estimate using the declared speed and the last checkpoint may
have drifted over time, so we currently estimate relative to the
next checkpoint, which is closer and presumably provides a better
estimate. However, this assumes that these checkpoint are perfectly
aligned without any position jumps.
The current approach has two issues:
- The next checkpoint may include a position jump by design, e.g.
if it was set for a new item in the playlist and the duration of
the current item wasn't perfectly accurate.
- The sudden switch between two estimation methods may cause a jump
in the output position, which is visible when we add new media
position checkpoints to the queue, not when we actually reach the
playback position of the checkpoint.
We can fix both issues by taking a slightly different approach:
- Continuously monitor the estimate using the current checkpoint. If
it starts drifting, we can adjust it directly. This way the estimate
is always aligned with the actual position.
- The change above means we can safely switch to using the estimate
based on the previous checkpoint. This way we don't have to make
assumptions about the next checkpoint and any position jumps will
only happen when we actually reach this checkpoint (which is more
what a user expects to see, e.g. at a playlist item transition).
Issue: androidx/media#1698
PiperOrigin-RevId: 690979859
Removed deprecated `Transformer.PROGRESS_STATE_NO_TRANSFORMATION`, `Transformer.setListener`, and `Transformer.startTransformation` from Transformer.
PiperOrigin-RevId: 690971992
Adjusted logic to accurately calculate sizes and durations for the last valid cue point when cue timestamps are greater than the total duration.
Fixes the issue where the reported duration of the MKV file was greater than the total duration specified by the duration element. Verified this using `mkvinfo` and `mediainfo` tools.
PiperOrigin-RevId: 690961276
A player that is being released may report an error with
null `player.getPlayerError()`. Do not try to read errors
of players that are released.
PiperOrigin-RevId: 690953083
This method allows `Sonic` to statically and accurately report the
expected number of output frames for any given parameter configuration.
This change is required prework for `SpeedChangingAudioProcessor` to
implement a similar static method and allow precise, non-blocking
timestamp adjustments for the experimental speed changing effect.
PiperOrigin-RevId: 690669627
Also, fix incorrectly stretched golden file that was not detected with previous, less sensitive, average pixel error comparison.
PiperOrigin-RevId: 690643520
GLSL 3.00 mediump doesn't require enough precision near zero
to correctly represent PQ colors where the [0, 1] GL range
represents [0, 10_000] nits.
This caused `noEffects_hlg10InputAndHdr10Output_matchesGoldenFile`
to fail on some devices.
PiperOrigin-RevId: 690627069
The old code that uses MediaCodec directly has a race condition
that causes the decoder to incorrectly crop the decoded picture.
PiperOrigin-RevId: 690620868
This is prework for `Sonic` to provide a precise calculation of output
sample counts, and thus allow `SpeedChangingAudioProcessor` to replace
`getSpeedAdjustedTimeAsync()` with an accurate synchronous calculation.
This is a non functional change.
PiperOrigin-RevId: 690608520
This method is already called below in the
`else if (sps.isCompleted())` block which applies when
`hasOutputFormat == true`, but this is only ever entered if we are
parsing SPS and PPS NAL units **after** we've emitted a format, which
is only the case if
`DefaultTsPayloadReaderFactory.FLAG_DETECT_ACCESS_UNITS` is set (which
it isn't by default).
The equivalent call in `H265Reader` is already inside the
`if (!hasOutputFormat)` block, so doesn't need a similar fix.
#cherrypick
PiperOrigin-RevId: 689809529
This ensures that media button preferences with slots for BACK,
FORWARD and OVERFLOW are converted to the legacy custom layout
according to the implicit placement rules. This has to happen
when populating the MediaSessionCompat and when generating the
notification for older APIs. Sending these preferences to older
Media3 controllers can filter them down to the custom layout the
session would have used previously, but there is no need to adjust
the reservation extras because the older Media3 custom layout has
no concept of these extras.
PiperOrigin-RevId: 689761637
This is equivalent to the current logic, but also allows to easily pick
up other buttons that use the BACK, CENTRAL or FORWARD slots for the
compact view by default.
Also fix the test to actually assert the output order.
PiperOrigin-RevId: 689747844
This ensures that the slots are set according to the implicit placement
rules for the legacy custom layouts. This has to be done when receiving
custom actions from a MediaControllerCompat and for Media3 sessions
setting the custom layout field.
PiperOrigin-RevId: 689737951
These methods are marked `default` on the `AnalyticsListener` interface
with an empty implementation, so there's no need to override them just
to re-define the empty implementation.
PiperOrigin-RevId: 689416584
* Use asset without audio for independent video time progress
* Use longer item duration to avoid ExoPlayer STATE_READY workaround
(see https://github.com/google/ExoPlayer/issues/1874)
PiperOrigin-RevId: 689409427
Add `DecoderAudioRenderer.getDurationToProgressUs()` so that `ExoPlayer`, if set with `experimentalSetDynamicSchedulingEnabled()`, will dynamically schedule its main work loop to when the `DecoderAudioRenderer` can make progress.
PiperOrigin-RevId: 689377247
Mp4Muxer caches the samples and then writes them in batches.
The new API allows disabling the batching and writing sample
immediately.
PiperOrigin-RevId: 689352771
- Create `LibiamfAudioRenderer` with `DefaultRenderersFactory` in `ExoPlayerModuleProguard`.
- Remove redundant library availability check from `IamfModuleProguard`.
- Move `proguard-rules.txt` to the root folder.
- Removed unused `cryptoType` parameter from `setLibraries()` method in `IamfLibrary`.
- Added log when `LibiamfAudioRenderer` is loaded in `DefaultRenderersFactory`.
- Annotated missing classes with `@UnstableApi`.
- Check for library availability and throw exception in `IamfDecoder` constructor.
#cherrypick
PiperOrigin-RevId: 689330016
This change:
1. Updates `DataSourceContractTest` to allow multiple "not found"
resources, and to include additional info (e.g. headers) on them.
2. Updates the contract test to assert that `DataSource.getUri()`
returns the expected (non-null) value for "not found" resources
between the failed `open()` call and a subsequent `close()` call.
The `DataSource` is 'open' at this point (since it needs to be
'closed' later), so `getUri()` must return non-null.
* This change also fixes some implementations to comply with this
contract. It also renames some imprecisely named `opened`
booleans that **don't** track whether the `DataSource` is open
or not.
3. Updates the contract test assertions to enforce that
`DataSource.getResponseHeaders()` returns any headers associated
with the 'not found' resource.
4. Configures `HttpDataSourceTestEnv` to provide both 404 and "server
not found" resources, with the former having expected headers
associated with it.
PiperOrigin-RevId: 689316121
The new `media3-ui-compose` module does not have any Material library dependencies, but will rely on androidx.compose + foundation/runtime/ui and other non-theming/opinionated libraries. Surface handling is one such usecase.
PiperOrigin-RevId: 689004504
Also add a test for this to avoid missing any others in future. Also
flesh out the existing test for the deprecated builder, to assert the
return type is correctly updated.
PiperOrigin-RevId: 688948768
The duration is now correctly calculated as the maximum of all track durations, instead of being overwritten by the last track's value. This aligns with how other Extractor implementations handle durations for multiple tracks.
PiperOrigin-RevId: 688896743
`RandomParameterizedSpeedChangingAudioProcessorTest` follows the
structure of `RandomParameterizedSonicAudioProcessorTest` and will help
improve coverage and confidence in the output length of
`SpeedChangingAudioProcessor`.
This CL is prework for removing the synchronization between the video
pipeline and the audio pipeline for speed changing effects.
PiperOrigin-RevId: 688578597
Currently most of the public APIs use `fullscreen` (apart from the deprecated `PlayerControlView.OnFullScreenModeChangedListener` which will have to remain as is). This code changes mostly private variable naming.
PiperOrigin-RevId: 688559509
Frame rate change is currently notified to the release control when the
video frame processor input frame rate changes, but it should be when
the video frame processor output frame rate changes.
PiperOrigin-RevId: 688512300
If not copied, the extras Bundle can be accidentally changed by the
app if it modifies the instance passed into MediaSession. On the flip
side, the Bundle should be modifiable once created so that the session
can amend the extras if needed without crashing.
PiperOrigin-RevId: 688485963
Added start and end time details to the error message for `REASON_START_EXCEEDS_END`, helping to debug cases where the start time exceeds the end time.
PiperOrigin-RevId: 688117440
The method allows extractors to set track duration when available. The `default` implementation does nothing, allowing implementers of `TrackOutput` to override it if they need to handle track duration.
Implemented it in `FakeExtractor` to print track duration in dump files.
PiperOrigin-RevId: 688110288
Treats the media duration as unknown (`C.TIME_UNSET`) when all bytes are `-1` to prevent exceptions during playback.
Issue: androidx/media#1819
#cherrypick
PiperOrigin-RevId: 688103949
This adds the API surface for media button preferences in MediaSession
and MediaController. It closely mimics the existing custom layout
infrastructure (which it will replace eventually).
Compat logic:
- Session:
- When converting to platform custom actions, prefer to use
media button preferences if both are set.
- When connecting to an older Media3 controller, send the
media button preferences as custom layout instead.
- Controller:
- Maintain a single resolved media button preferences field.
- For Media3 controller receiving both values, prefer media
button preferences over custom layouts.
Missing functionality:
- The conversion from/to custom layout and platform custom actions
does not take the slot preferences into account yet.
PiperOrigin-RevId: 686950100
Before this change:
* With legacy subtitle decoding (at render time), load errors (e.g. HTTP
404) would result playback completely failing, while parse errors
(e.g. invalid WebVTT data) would be silently ignored, so playback
would continue without subtitles.
* With new subtitle decoding (at extraction time), both load and parse
errors would result in playback completely failing.
This change means that now neither load nor parse errors in text or
metadata tracks stop playback from continuing. Instead the error'd track
is disabled until the end of the current period.
With new subtitle decoding, both load and parse errors happen during
loading/extraction, and so are emitted to the app via
`MediaSourceEventListener.onLoadError` and
`AnalyticsListener.onLoadError`. With legacy subtitle decoding, only
load errors are emitted via these listeners and parsing errors continue
to be silently ignored.
Issue: androidx/media#1722
PiperOrigin-RevId: 686902979
These events are always reported with the primary child period ID,
because this is the same ID used in the parent `MergingMediaSource`'s
Timeline.
This ensures that e.g. loading errors from sideloaded subtitles (which
uses `MergingMediaSource`) are now reported via
`AnalyticsListener.onLoadError`.
It results in non-error events being reported from these children too,
which will result in more `onLoadStarted` and `onLoadCompleted` events
being reported (one for each child).
Issue: androidx/media#1722
PiperOrigin-RevId: 686901439
Use this for sideloaded subtitles, so preparation can still complete
despite an error from e.g. `DataSource.open`. In this case, no subtitle
tracks will be emitted.
Issue: androidx/media#1722
PiperOrigin-RevId: 686888588
This is prework for implementing
`RandomParameterizedSpeedChangingAudioProcessorTest`, which depends on
Sonic's resampling algorithm's behaviour.
This is a non-functional refactor.
PiperOrigin-RevId: 686874593
When a `SampleQueue` is prepared prior to playback, the start position may be less than the timestamp of the first sample in the queue and still be valid. This scenario can come about with specific clipping values and if all samples are sync samples. Currently, with `ClippingMediaPeriods` around `ProgressiveMediaPeriods`, if the `SampleQueue` has already been reset through the seekTo operation in `onPrepared`, then in the aforementioned scenario the seekTo operation in `handleDiscontinuity` will remove all samples and reset the loading periods unnecessarily.
The solution is that if the `ProgressiveMediaPeriod` has already handled a seekTo operation for the same position and the sample queue has not been read yet, then loading does not need to be reset.
The tests in `MergingPlaylistPlaybackTest` were specifically causing this behavior through its setup of `MergingMediaSources` around clipped `FilteringMediaSources`. Since the video content was not 'all sync samples', there would always be a discontinuity to handle and the audio content being 'all sync samples' would start with samples post start time.
These changes also remove the flakiness from the `MergingPlaylistPlaybackTest`.
PiperOrigin-RevId: 686858444
Currently every test in the library passes `null` here, which seems to
end up being passed into non-null places in the library. This change
removes the parameter and instead initializes the field to a
`DefaultAllocator` instance in the same way that `DefaultLoadControl`
creates one.
PiperOrigin-RevId: 686823273