It's much better to merge the windows at source level to reflect the
same state everywhere (e.g. notifications, player state, etc). This
can be done with ConcatenatingMediaSource2.
PiperOrigin-RevId: 563715718
There is no known use case left that needs to be solved by this
class. All other use cases are better solved by alternative
approaches (Player playlist methods or ConcatenatingMediaSource2).
PiperOrigin-RevId: 563713384
The class currently disallows offsets of periods in their windows
except for the very first window. This is not necessary because
we can use TimeOffsetMediaPeriod to eliminate the offset if needed.
This makes the class more useful for many use cases, in particular
for using it with ClippingMediaSource.
Issue: google/ExoPlayer#11226
PiperOrigin-RevId: 563702120
Modifying dumping to not required "released" to be called.
Track index is an arbitrary value based on the order of addTrack calls.
Samples are dumped by track (rather than as soon as they are written),
so it's preferable to use a value that provides more context.
By using the track type as a key, dump files will be more deterministic
and will have more similarities when branched.
PiperOrigin-RevId: 563700982
This callback asks to correct the media time in a composition, but doesn't
provide the MediaPeriodId as the necessary context to do this.
PiperOrigin-RevId: 563699344
That said, only SDR is supported for now, so this will always throw if
HDR is input. This will also throw if different ColorInfo values are input
because color SDR mixing (ex. between sRGB and BT709) is not yet supported.
PiperOrigin-RevId: 563457729
While investigating a different test failure on a pending change I
noticed that sometimes the "testAddSessions_removedWhenClose" session
was being released before it could be fully connected - and this
results in a failure like:
```
expected not to contain: androidx.media3.session.MediaSession@50a9ef1
but was : [androidx.media3.session.MediaSession@50a9ef1, androidx.media3.session.MediaSession@3a6bac]
at androidx.media3.session.MediaSessionServiceTest.addSessions_removedWhenReleased(MediaSessionServiceTest.java:376)
```
It also shows up in the logs like:
```
MediaController future failed (so we couldn't release it)
...
Caused by: java.lang.SecurityException: Session rejected the connection request.
```
Adding some debug logging revealed that the `session.release` call
posted to the test thread was happening before the call to
`MediaSessionStub.connect` on the main thread (this is triggered deep
in prod media3 session logic).
PiperOrigin-RevId: 563431265
Instead of invoking "undefined behavior" may occur when a class is used
incorrectly, which is clear but not very helpful to callers, specify what Apps
or users of a class should do when issues occur.
Apply this to Compositor as well, where this otherwise might seem unclear.
PiperOrigin-RevId: 563406219
For pause and resume feature we will need to build `ExportResult`
from multiple internal Exports. Keeping the `ExportResultBuider` in
`Transformer` class will allow using same builder across different
internal exports.
PiperOrigin-RevId: 563392443
This change ensures that a different package is used for
`test_session_current/src/main:support_app` and
`test_session_current/src/androidTest:test_app` - previously they used
the same package which was unusual (and possibly led to some confusing
behaviour).
PiperOrigin-RevId: 563051818
This change avoids using a framework API that is deprecated since
API 31 and works around difficulties with this deprecated API on
devices from some manufacturers on API 33/34.
Manually tested with BT headphone connected to:
- Samsung SM-G920F (API 24)
- Pixel (API 28)
- Samsung SM-A515W (API 33)
- Pixel 6 Pro (API 33)
(verified manually with devices and adb output of dumpsys)
Issue: androidx/media#167
PiperOrigin-RevId: 562890206
When checking the color transfer, there is no reason that the file should have
exactly two tracks, and this assertion means that this method can't be used
as-is for checking video-only files, for example.
PiperOrigin-RevId: 562813111
We have an existing logic for recovering the `AudioTrack` from the [ERROR_DEAD_OBJECT](https://developer.android.com/reference/android/media/AudioTrack#ERROR_DEAD_OBJECT)
throws. However, this only applies to the situation when the
`writtenEncodedFrames > 0`.
However, we have a case when `ERROR_DEAD_OBJECT` throws while writing
PCM data. When the `tunneling` is turned on, the `AudioTrack` is set the
flag `AUDIO_OUTPUT_FLAG_HW_AV_SYNC`, and further because of this flag,
it is forced the flag `AUDIO_OUTPUT_FLAG_DIRECT`. When the platform
invalidates the `AudioTrack`, the `AudioTrack` won't be restored by the
platform due to `AUDIO_OUTPUT_FLAG_DIRECT` flag, and `ERROR_DEAD_OBJECT`
is thrown.
Issue: androidx/media#431
PiperOrigin-RevId: 562582451
This is so CompositionPlayer can customize the Renderers and figure
out when a transition to a MediaItem is made hence it can configure the
effects pipeline with the effects that are specific to the MediaItem.
PiperOrigin-RevId: 562530774
Created new method `AudioSink#setOffloadDelayPadding` that will set delay and padding data onto an `AudioTrack` using `AudioTrack#setOffloadDelayPadding`. This feature adds support for offloaded, gapless Opus playback as the content requires the capability to set padding data post-`AudioSink#configure`.
PiperOrigin-RevId: 562518193
Overlays may be overlaid over:
* In VideoFrameProcessor, videos or images (or texture input).
* In Compositor, other videos.
In Compositor, Overlays may consist of video, so it could be confusing
for videoFrameAnchor to contrast with overlayAnchor.
Also, rename overlayAnchor to overlayFrameAnchor, since it's modifying
the anchor in the overlay's frame, so this name seems slightly more precise.
PiperOrigin-RevId: 562004292
This change makes capturing components in CapturingRenderersFactory
to dump data only they have previously captured any. This is so we can
extend the CapturingRenderersFactory with more renderers that do not
capture data in pre-existing tests and we don't have to change the
golden files.
PiperOrigin-RevId: 561973645
also improves tests to hash bitmap now that we know the bitmaps are decoded in roboelectic tests,
as well as some minor fixes in the DefaultImageDecoder
PiperOrigin-RevId: 561946073
Implement VideoCompositor support of:
* Different input and output sizes
* CompositorSettings, to customize output size based on input texture sizes
* OverlaySettings, to place an input frame in an arbitrary position on
the output frame.
Also, refactor Overlay's matrix logic to make it more reusable between
Compositor and Overlays
PiperOrigin-RevId: 561931854
This wasn't properly documented yet (unlike the longer setMediaItems
method that already includes this documentation).
Issue: androidx/media#607
PiperOrigin-RevId: 561910073
For pause and resume feature we will remux the previously processed
video in the first export and then in the second export we will resume
processing remaining video. For the second export we will have to
set initial timestamp offset so that video samples from the second
export are in continuation to the previously muxed samples.
PiperOrigin-RevId: 561689651
For pause and resume we need to perform multiple intermediate exports.
So moved start() logic into a separate so that it can be reused from
different places with different Compositions and MuxerWrapper.
PiperOrigin-RevId: 561675472
In most cases, the places that were trying to avoid a transitive
dependency on `lib-exoplayer` when this duplication was introduced [1]
are already depending on it again, except for `lib-container` where the
dep is added in this change.
In general it seems fine for the tests of module A to depend
(transitively or directly) on module B even where the prod code of
module A **does not** depend on module B.
[1] <unknown commit>
PiperOrigin-RevId: 561660371
Switch to SparseArray<List> rather than a Map<Integer, List>.
Track indices now determine sample list dumping, reducing flakiness.
PiperOrigin-RevId: 561658586
Currently, we only support sending Common Media Client Data (CMCD) data through custom HTTP request headers, added capability to configure and transmit it as HTTP query parameters.
PiperOrigin-RevId: 561591246
We're moving towards parsing subtitles before the `SampleQueue`, and we
already have subtitle playback assertions using `Player.Listener.onCues`
which is the most 'complete' place to assert subtitle output from. We
don't need to hook anything inside `TextRenderer`, so we can remove this
TODO.
PiperOrigin-RevId: 561418660
This will help with debugging subtitle sync issues as it will show up in
track selection details emitted to logcat by `EventLogger`.
PiperOrigin-RevId: 561355836
For pause/resume feature, same MuxerWrapper needs to be
used across intermediate exports. So pass the MuxerWrapper
from Transformer.java
More specifically, when resume() is called
1. Create a MuxerWrapper and remux the previous
video samples (Export 1).
2. User the same MuxerWrapper and start processing
remaining video samples (Export 2).
PiperOrigin-RevId: 561325867
If a RtspMediaSource is used within a combining source like MergingMediaSource, then it could become stuck in a loop of calling continueLoading when the source has not actually started loading yet.
Issue: androidx/media#577
PiperOrigin-RevId: 561322900
Also use `@linkplain` in more places: If I was already touching a javadoc
block, I switched to `@linkplain` throughout the whole block.
PiperOrigin-RevId: 561320273
At this stage, the image renderer is designed to be able to render one input stream containing one sample. The renderer supports seeking inside that stream, which is a no-op because the stream comprises for exactly one sample.
PiperOrigin-RevId: 561307859
Also re-jig some `checkNotNull` calls to satisfy the nullness checker
(remove an unneeded one, and add a new one).
Follow-up to discussion in bb214b19f9
PiperOrigin-RevId: 561295724
More specifically, this CL
- Defines a VideoGraph interface
- Adds a factory method, to hide the constructors
- Separate out an initialize method that does the real work (following that constructor should not do real work)
- The VideoGraph takes in a list of composition effects. For now, we only use the `Presentation`, if there is one in the list. This means we can take any number of Presentations now, but only the first one will be used.
- Moves the VideoFrameProcessingWrapper to its own file
PiperOrigin-RevId: 561059653
By doing so, the media notification sent from DefaultMediaNotificationProvider won't be auto-grouped (https://developer.android.com/develop/ui/views/notifications/group#automatic-grouping) with the regular notifications sent from the other places in the app. As the result, when the customer attempts to dismiss the regular notifications (by swiping away), the media notification won't be dismissed as being in the same group.
Issue: androidx/media#549
PiperOrigin-RevId: 561047571
The `controller.prepare()` call can trigger the callback `onPrepare()`, however, this will count down the latch by one before the callback `onStop()` is triggered.
PiperOrigin-RevId: 560988209
Split this logic out from `OverlayShaderProgram`, to share logic like
this with `VideoCompositor`.
Also, remove the unused `context` parameter from `OverlayShaderProgram`
`VideoCompositor` will reuse `OverlayMatrixProvider`'s storing of the matrices,
though it may generate the matrices differently, since `OverlayShaderProgram`
applies this in the fragment shader, whereas `VideoCompositor` applies this in the
vertex shader.
PiperOrigin-RevId: 560142164
The actual logic scales the alpha, instead of setting it, so rename
this to what it does.
We would also prefer alpha to be scaled here, to not lose alpha information
(for example for PNGs with transparent regions).
PiperOrigin-RevId: 560121708
For pause and resume feature we need to find the timestamp of
the last sync sample in an MP4 file. The Mp4ExtractorWrapper
provides an easy to use API on top of Mp4Extractor.
PiperOrigin-RevId: 560113112
If the loading thread of the second media item progresses slow, then when the playback of the first item approaches to the end before the second item is prepared, the stream will be set "final" and the renderers are disabled during such transition. In this case, `AudioSink.handleDiscontinuity` never gets called, which introduces the flakiness into the `test_bypassOffThenOn`.
Similarly for `test_subtitle`, if the loading thread of extracting the subtitle is slow, then when the renderer attempts to queue the input buffer, the data hasn't been available in the stream. And when the extracting finished, the renderer already advanced to the time after the subtitle end time.
To de-flake the tests, we have to make sure that the period of the second item has fully loaded before starting the playback.
PiperOrigin-RevId: 560080119
The period index was calculated relative to the contentTimeline
of the DAI stream, but then used with the full timeline of the
player. This means it currently only works when the stream is the
only or first item in the playlist.
Issue: androidx/media#571
PiperOrigin-RevId: 560023412
The first call to method `registerInputStream` doesn't block.
Later successive calls to the method blocks until the previous register call
finishes.
PiperOrigin-RevId: 559694490
This removes concurrent access from `rtspLoaderWrappers`. Previously
there was a race between the playback thread clearing & re-adding
entries to this list in `retryWithRtpTcp()`, and the loading thread
accessing the entries in `InternalListener.track()` (implemented from
`ExtractorOutput`).
This change means each `ExtractorOutputImpl` uses exactly one
`SampleQueue` for its one `TrackOutput`. When the `RtspLoaderWrapper`
instances are replaced in `retryWithRtpTcp()`, any stale instances will
only be able to access their own (also stale) `SampleQueue` instances
(vs before, where the stale `ExtractorOutput` could accidentally access
'new' `SampleQueue` instances via the `rtspLoaderWrappers` field).
As well as fixing a race condition in the prod code, this also de-flakes
`RtspPlaybackTest`.
#minor-release
PiperOrigin-RevId: 559130479
Replace Queue<Long> with LongArrayQueue which provides queue semantics
for long primitives. LongArrayQueue is forked from IntArrayQueue which
in turn was forked from Androidx CircularIntArray.
IntArrayQueue is deleted and we now use CircularIntArray directly from
Androidx Collection.
PiperOrigin-RevId: 559129744
There are multiple problems in the test:
1. The controller must run on the main thread due to the Player
interface requirement to add surfaces on the thread their
callbacks will be called on.
2. This test made assertions about an expected callback that
aren't true. Setting an anonymous surface will not result in
a size change callback because the size stays unknown.
But clearing a surface (even if never set) ensures the returned
size is guaranteed to be zero.
PiperOrigin-RevId: 559080905
In case BaseShaderProgram implementations have an expensive
configure() call, we can only call configure() when absolutely necessary,
aka when the input size changes.
To reduce scope, this doesn't reduce the amount of
configure() calls that may be made outside this class, in
DefaultFrameDroppingShaderProgram and
FinalShaderProgramWrapper.
PiperOrigin-RevId: 558754314
Covers all permutations&combinations of:
* AV asset.
* AV asset with effects.
* AV asset with silence.
* AV asset with silence and effects.
Note that the video is not relevant (therefore transmuxed), but is
needed for silence generation.
PiperOrigin-RevId: 558734593
Based on the Common Media Client Data (CMCD) specification key-value pairs should be sequenced in alphabetical order of the key name in order to reduce the fingerprinting surface exposed by the player.
PiperOrigin-RevId: 558296264
Added more comprehensive Javadoc around setting custom data and verification on key format.
Changed adding custom data as a `String` to `List<String>`. This would enable us to sort all keys to reduce the fingerprinting surface.
PiperOrigin-RevId: 558291240
We will need to build upon original composition
for pause and resume feature and will have to set modified sequences.
In the next CL, will add method to set sequences on builder and will
probably remove it from the constructor parameter (to avoid providing
two APIs for same thing).
PiperOrigin-RevId: 558127334
I wasn't able to reproduce the error in the bug by running videoTranscoding_withTextureInput_completesWithCorrectFrameCountAndDuration
100 times, but I figured this added debug info may help the next time the
issue is seen.
PiperOrigin-RevId: 558118443
This file decompresses to 3024*4032*4 bytes ~= 48
MB, which leads to OOM errors on some devices.
Use a lower resolution test image for tests, to
still test a portrait image but without hitting
OOM errors.
PiperOrigin-RevId: 557861063
In addition to this being how Alpha should be handled, tests do fail under
API 29 without this CL. Unfortunately while these tests do fail under API 29
without this CL, we currently only run this test on API 33 emulators, so we
didn't catch this failure earlier (until compositor tests on mh failed on all
devices under API 29 and succeeded on all at or over 29).
PiperOrigin-RevId: 557781757
When the foreground service type is set to `mediaPlayiback` this shouldn't
be required. However, some reports from users say that setting the
foreground service behavor fixes some problems on some devices. Setting
it explicitely with this change makes sure users don't have to do that
workaround themselves.
Issue: androidx/media#167
PiperOrigin-RevId: 557608577
In an upcoming change I'm going to mark SSA subtitles as 'merge
replacement behavior', which will mean that
`CuesWithTiming.durationUs=C.TIME_UNSET` will not be permitted. This CL
makes it clear that `SsaParser` obeys that invariant.
PiperOrigin-RevId: 557504633
This `DvbParser` was updated to implement the new `SubtitleParser`
interface in 2261756d3a.
This method used to return a `List<Cue>`, but now it returns a
`List<CuesWithTiming>`, which is closer to `List<List<Cue>>`. The
previous method returned an empty list, meaning a single 'event' with
no cues. After the change above the method still returns an empty list,
but that now means 'no events'. In order to maintain the old behaviour,
this change updates it to return a single-item list containing an empty
list of cues.
PiperOrigin-RevId: 557502261
This test uses an existing CBR test asset, and shows that (as expected)
`isSeekable = true` even in the `unknown_length` dump file.
PiperOrigin-RevId: 557455364
It was moved there temporarily to support another temporary move
of ExoPlaybackException. See <unknown commit>.
Since then, ExoPlaybackException has been moved back to ExoPlayer
and we can do the same with MediaPeriodId, which only makes sense
in the context of the ExoPlayer module.
PiperOrigin-RevId: 557159381
This changes the default logic of shouldShowPlayButton to show a play
button while the playback is temporarily suppressed. This helps to
provide better UI feedback to the fact that playback stopped and
provides a quick way for users to override the suppression and attempt
to restart playback.
Some apps may want to keep the legacy behavior depending on their app's
needs. Hence, we also add a config parameter to set this behavior both
in MediaSession and our default UI components.
Issue: google/ExoPlayer#11213
PiperOrigin-RevId: 557129171
This aligns the bypass code with the MediaCodec logic to not
use buffer.isDecodeOnly and instead rely on a timestamp
comparison with the last reset time. Overall, the change should
not introduce a functional difference and is covered by existing
end-to-end tests with bypass playbacks.
Splitting bypass batch buffers by decoder-only flag is
technically wrong for formats where not every buffer is a
keyframe, and this change also leaves a TODO to explain this
known shortcoming.
PiperOrigin-RevId: 556800038