Skip to content

Conversation

@JaroslavHerber
Copy link
Contributor

The XS_DATE_TIME_PATTERN in Util.java was previously limited to parsing ISO 8601 date-times that use a literal 'T' or 't' as the separator between the date and time components.

However, some content providers and metadata sources use a space character as the separator (e.g., "2025-10-28 12:09:41.913000+00:00"). This caused Util.parseXsDateTime to fail when parsing these valid, albeit non-standard, date-time strings, leading to potential parsing errors for certain media streams.

This commit updates the regular expression by adding a space to the character class [Tt], making it [Tt ]. This change extends parsing support to include date-times with a space separator while maintaining full compatibility with the standard 'T'/'t' separators.

icbaker and others added 30 commits November 19, 2024 11:04
The content in Issue: androidx#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
androidx@39c7349).

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.

PiperOrigin-RevId: 696583702
(cherry picked from commit e6448f3)
PiperOrigin-RevId: 696879276
(cherry picked from commit c50867c)
From [ the last change in `DefaultPreloadManagerTest`](androidx@2b54b1e), 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
(cherry picked from commit 0143884)
PiperOrigin-RevId: 696912494
(cherry picked from commit cbb8e2f)
PiperOrigin-RevId: 698426838
(cherry picked from commit cf4488a)
PiperOrigin-RevId: 698713460
(cherry picked from commit e5110e6)
PiperOrigin-RevId: 698761734
(cherry picked from commit 73c4bb6)
The current code assumes that the first Table of Contents segment
includes the `VBRI` frame, but I don't think this is correct and it
should only include real/audible MP3 ata - so this change updates the
logic to assume the first ToC segment starts at the frame **after** the
`VBRI` frame.

Issue: androidx#1904

PiperOrigin-RevId: 700269811
(cherry picked from commit f257e55)
Also add an explicit warning about how fiddly `ForwardingPlayer` can be
to use correctly.

PiperOrigin-RevId: 700698032
(cherry picked from commit 60133b0)
…heck

PiperOrigin-RevId: 700706152
(cherry picked from commit bff5523)
PiperOrigin-RevId: 701898620
(cherry picked from commit 77d3364)
PiperOrigin-RevId: 702281314
(cherry picked from commit e499377)
The method previously discarded the cue that was active at `timeUs`,
meaning it had started before but had not ended by `timeUs`.

Issue: androidx#1939

PiperOrigin-RevId: 702707611
(cherry picked from commit e927d7b)
Only `TRACKNUMBER` and `GENRE` are listed here:
https://xiph.org/vorbis/doc/v-comment.html

The rest are derived from the example in Issue: androidx#1958.

It's possible that other formats exist in the wild:
https://hydrogenaud.io/index.php/topic,69292.msg613808.html#msg613808

Issue: androidx#1958
PiperOrigin-RevId: 704308788
(cherry picked from commit 1254607)
Currently as there is no formal support for MV-HEVC within Android framework, the profile is not correctly specified by the underlying codec; just assume the profile obtained from the MV-HEVC sample is supported.

PiperOrigin-RevId: 705164738
(cherry picked from commit 3936c27)
Custom actions are more naturally associated with a user intent
than commands (that are meant to be used for automated inter-app
communication without user interaction).

PiperOrigin-RevId: 705797057
(cherry picked from commit 3bce3af)
There are reproducible issues with codec timeouts when using
this API, so we disable it entirely until we know more about
potential fixes and where they are available.

Issue: androidx#1641
PiperOrigin-RevId: 707025950
(cherry picked from commit 71f82df)
Mp4Muxer caches the samples and then writes them in batches.
The new API allows disabling the batching and writing sample
immediately.

PiperOrigin-RevId: 689352771
(cherry picked from commit f181855)
PiperOrigin-RevId: 692920946
(cherry picked from commit c3e72a8)
PiperOrigin-RevId: 694095488
(cherry picked from commit 19d7126)
This CL also aligns supported color space in `media3 common` and `media3 muxer`.

Earlier `muxer` would take even those values which are considered invalid
in `media3` in general.

Earlier muxer would throw if a given `color standard` is not recognized
but with the new change, it will rather put default `unspecified` value.

#cherrypick

PiperOrigin-RevId: 698683312
(cherry picked from commit 407bc4f)
PiperOrigin-RevId: 698730105
(cherry picked from commit 5282fe3)
#cherrypick

PiperOrigin-RevId: 698770714
(cherry picked from commit 827966b)
This was hand-crafted with a 4-entry ToC by modifying
`bear-vbr-xing-header.mp3` in a hex editor.

The output difference from 117 samples to 116 samples is due to the
calculation in `VbriSeeker` assuming that the ToC includes the VBRI
frame itself, which I don't think is correct (fix is in a follow-up
change).

Issue: androidx#1904

#cherrypick

PiperOrigin-RevId: 700254516
(cherry picked from commit 3eb36d6)
The previous code assumed that the `VBRI` Table of Contents (ToC)
covers all the MP3 data in the file. In a file with an invalid VBRI ToC
where this isn't the case, this results in playback silently stopping
mid-playback (and either advancing to the next item, or continuing to
count up the playback clock forever). This change considers the `bytes`
field to determine the end of the MP3 data, in addition to deriving it
from the ToC. If they disagree we log a warning and take the max value.
This is because we handle accidentally reading non-MP3 data at the end
(or hitting EoF) better than stopping reading valid MP3 data partway
through.

Issue: androidx#1904

#cherrypick

PiperOrigin-RevId: 700319250
(cherry picked from commit 46578ee)
The previous version (3.33.0) is known to have some bugs, and the latest
version (3.36.0) is also known to be buggy.

PiperOrigin-RevId: 700657484
(cherry picked from commit 6cf3004)
PiperOrigin-RevId: 707558817
(cherry picked from commit 896bd0d)
PiperOrigin-RevId: 707576152
(cherry picked from commit c3b58f2)
The creation can be moved to the playback thread (to guarantee it
happens in sync other initialization after playback start) and the
potentially blocking calls to the reporting methods can be moved
to the generic shared BackgroundExecutor (it can't use the playback
thread because it no longer exists when the session is ended after
the player is released).

PiperOrigin-RevId: 726872818
(cherry picked from commit d386e00)
tonihei and others added 21 commits July 22, 2025 05:28
In cases where we intentionally ignore a connection request, we
don't currently attempt to call onDisconnected on the controller
in all cases. This means such controllers may not be aware they
are ignored. Even if some cases only happen with malformed or
malicious connection attempts, it's still useful to try and
disconnect the connection officially.

PiperOrigin-RevId: 785814501
(cherry picked from commit 74872d1)
It's currently not triggered at all if the advancing state is not
detected before stopping the AudioTrack. This can be fixed by
also triggering the callback once stopped, but with fewer checks,
as the position is simulated anyway at this point.

PiperOrigin-RevId: 785817439
(cherry picked from commit c3e8fc5)
PiperOrigin-RevId: 786259343
(cherry picked from commit c2a09a0)
All three util methods currently check if the controller is of
a legacy/platform type, which may not be true in all future cases.

Removing these checks allows to identify these controllers even
if they are implemented in Media3. The SysUI controller needs
some additional adjustments for all the cases where it's replaced
to and from the media notification controller. These translations
have to account for the fact the the original SysUI controller
may be part of the Media3 or platform controller list.

PiperOrigin-RevId: 780018652
(cherry picked from commit 10d7c65)
This change removes the check for available commands in `sendCustomCommand` of `MediaBrowserImplLegacy.java`. This is in parity with the behavior of legacy controllers/browsers when connected to a legacy app.

The test `sendCustomCommandWithMediaItem_commandButtonNotAvailable_permissionDenied` was updated to reflect this change.

PiperOrigin-RevId: 780580897
(cherry picked from commit 3174a48)
AudioFormat.ENCODING_PCM_24BIT_PACKED was introduced in API 31
https://developer.android.com/reference/android/media/AudioFormat#ENCODING_PCM_24BIT_PACKED

PiperOrigin-RevId: 780996481
(cherry picked from commit 25bbb96)
Ensures asynchronous cleanup messages are processed before each test ends, preventing state leakage between tests. Catches `IllegalStateException` in case a `looper` is already quitting when `idle()` is called.

#cherrypick

PiperOrigin-RevId: 781060600
(cherry picked from commit c14c060)
PiperOrigin-RevId: 781077925
(cherry picked from commit 70d6221)
This may happen if apps call Renderer.getFormatSupport on the
main thread outside the player for example. Using the DefaultAudioSink
on multiple threads is just not safe though as non of the internal
values are synchronized.

Issue: androidx#1191
PiperOrigin-RevId: 781895924
(cherry picked from commit 8d37db5)
PiperOrigin-RevId: 781950733
(cherry picked from commit af6fa9e)
The delay is currently simulated by a free-running Handler, which means
its order is not fully deterministic. This can be fixed by injecting
the test clock into this delay setup.

As a result, we also get more realistic updates for individual changes
coming from multiple sources.

PiperOrigin-RevId: 782002184
(cherry picked from commit 578ec5b)
PiperOrigin-RevId: 782841122
(cherry picked from commit 9459cd4)
Prevents a `NumberFormatException` when `Format.id` contains a non-integer string (e.g., "1/256"). Since `MediaFormat.KEY_TRACK_ID` requires an integer and is an optional key, this change now safely catches the exception and avoids setting the key if parsing fails.

Fixes: Issue: androidx#2645

#cherrypick

PiperOrigin-RevId: 786657146
(cherry picked from commit abb6db1)
PiperOrigin-RevId: 786657570
(cherry picked from commit efc0f25)
PiperOrigin-RevId: 786706980
(cherry picked from commit 619890e)
#cherrypick

PiperOrigin-RevId: 788411907
(cherry picked from commit 1700c70)
#cherrypick

PiperOrigin-RevId: 788490308
(cherry picked from commit 9574ffa)
This file is copied from
https://github.com/android/snippets/blob/main/misc/src/main/java/com/example/snippets/PreloadManagerKotlinSnippets.kt

I had to make the following changes to make it compile against the tip
of the `main` branch (and these will need to be undone when
cherrypicking this change to the `release` branch):

1. Rename `DefaultPreloadManager.PreloadStatus.TRACKS_SELECTED/SOURCE_PREPARED`
   to `PRELOAD_STATUS_TRACKS_SELECTED/_SOURCE_PREPARED`.
2. Change `getTargetPreloadStatus` to return a non-null `PreloadStatus`
   and `PRELOAD_STATUS_NOT_PRELOADED` instead of `null`.

PiperOrigin-RevId: 797259358
(cherry picked from commit 46d4066)
Also remove some unused dependencies.

Follow-up to androidx@46d4066

PiperOrigin-RevId: 797302191
(cherry picked from commit 079e891)
The `XS_DATE_TIME_PATTERN` in `Util.java` was previously limited to parsing ISO 8601 date-times that use a literal 'T' or 't' as the separator between the date and time components.

However, some content providers and metadata sources use a space character as the separator (e.g., "2025-10-28 12:09:41.913000+00:00"). This caused `Util.parseXsDateTime` to fail when parsing these valid, albeit non-standard, date-time strings, leading to potential parsing errors for certain media streams.

This commit updates the regular expression by adding a space to the character class `[Tt]`, making it `[Tt ]`. This change extends parsing support to include date-times with a space separator while maintaining full compatibility with the standard 'T'/'t' separators.
@JaroslavHerber
Copy link
Contributor Author

@icbaker icbaker self-assigned this Oct 28, 2025
@icbaker
Copy link
Collaborator

icbaker commented Nov 4, 2025

The HLS spec defines date-time-msec as

date-time-msec is an ISO/IEC 8601:2004 [ISO_8601] date/time representation, such as YYYY-MM-DDThh:mm:ss.SSSZ.

https://en.wikipedia.org/wiki/ISO_8601 claims the space separator is permitted in RFC 3339 but not ISO 8601:

Separating date and time parts with other characters such as space is not allowed in ISO 8601, but allowed in its profile RFC 3339.

That said, it seems likely that other content producers will make the same mistake and use an RFC 3339 space-separated date-time instead of the T-separated format mandated by the HLS spec (via ISO 8601). So although I'd argue these streams are invalid per the HLS spec, we can accept this PR to parse them without too much risk of unexpected consequences.

@icbaker
Copy link
Collaborator

icbaker commented Nov 4, 2025

Please can you re-send this PR against the main branch - we cannot merge it into the release branch.

@JaroslavHerber JaroslavHerber changed the base branch from release to main November 4, 2025 12:11
@JaroslavHerber
Copy link
Contributor Author

Will resend in main branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.