1127 Commits

Author SHA1 Message Date
tianyifeng
d97ec132b9 Suppress the lint "WrongConstant" error
Lint somehow complains that the integer resulting from the bit-manipulation shouldn't be passed as an @IntDef parameter.

#cherrypick

PiperOrigin-RevId: 648687698
(cherry picked from commit afe3826d7c4b79acfe0fd165ac1940261a147040)
2024-07-02 14:12:52 +00:00
michaelkatz
bd1704904e Cache audio timestamp frame position across track transition reset
Upon track transition of offloaded playback of gapless tracks, the framework will reset the audiotrack frame position. The `AudioTrackPositionTracker`'s `AudioTimestampPoller` must be made to expect the reset and cache accumulated sum of `AudioTimestamp.framePosition`.

#cherrypick

PiperOrigin-RevId: 647294360
(cherry picked from commit a58e77a5a63d51c8cb9419fc59a7f0c7459fcafe)
2024-07-02 14:12:52 +00:00
tonihei
adeef60c14 Send pending updates before adding discontinuity for error
When handling a playback error that originates from a future item in
the playlist, we added support for jumping to that item first,
ensuring the errors 'happen' for the right 'current item'.
See 79b688ef30.

However, when we add this new position discontinuity to the
playback state, there may already be other position discontinuities
pending from other parts of the code that executed before the
error. As we can't control that in this case (because it's part
of a generic try/catch block), we need to send any pending
updates first before handling the new change.

Issue: androidx/media#1483
PiperOrigin-RevId: 646968309
(cherry picked from commit 727645179b3c26e495540f4445216fd035cc7654)
2024-07-02 14:12:47 +00:00
Copybara-Service
708dc6cab9 Merge pull request #1487 from colinkho:main
PiperOrigin-RevId: 646917527
(cherry picked from commit 6244d8605f48d1b548201a8a964a9879961b3c68)
2024-07-02 14:11:38 +00:00
rohks
0b87e176fd Use removeKey method instead of setting null for KEY_CODECS_STRING
Setting a `null` value doesn't remove the key as expected per the `MediaFormat` API documentation, using the `removeKey` method instead which is only available starting API level 29.

PiperOrigin-RevId: 646462402
(cherry picked from commit 12c42585d25d4c51bc5d022aa282d4d36b8e1ff2)
2024-07-02 14:11:38 +00:00
ibaker
0f0a20bc1c Use MediaCodec.stop() before release() for surface switching bug
ExoPlayer used to call `stop()` before `release()`. This was removed in
<unknown commit>.

A framework bug introduced in Android 11 (API 30) resulted in some
DRM -> clear transitions failing during `MediaCodec.configure()`. An
investigation in Issue: google/ExoPlayer#8696 and b/191966399 identified that this was
due to `release()` returning 'too early' and the subsequent
`configure()` call was then trying to re-use a `Surface` that hadn't
been fully detached from the previous codec. This was fixed in
Android 13 (API 33) with http://r.android.com/2094347.

ExoPlayer worked around the framework bug by adding an arbitrary 50ms
sleep after a failed codec initialization, followed by retrying. This
was enough to resolve the problem in the test scenario on a OnePlus
AC2003.

Issue: androidx/media#1497 points out that 50ms might not be the appropriate delay
for all devices, so it's an incomplete fix. They suggested re-adding the
`MediaCodec.stop()` call instead. This also reliably resolves the issue
on the OnePlus AC2003 (with neither workaround in place, the problem
repros almost immediately).
PiperOrigin-RevId: 646461943

(cherry picked from commit 5fcc7433a1f188c9644d4430a828a49d06c993cb)
2024-07-02 14:11:38 +00:00
tonihei
a73d32a795 Rename DummyTrackOutput and DummyExtractorOutput
#cherrypick

PiperOrigin-RevId: 646434450
(cherry picked from commit 867410fece006122820e26be4e0bea87309a4f2e)
2024-07-02 14:11:38 +00:00
tonihei
0f18fd87ac Add guard against additional tracks reported by Extractors
Extractors should not report additional tracks once they called
ExtractorOutput.endTracks. This causes thread safety issues in
ProgressiveMediaPeriod where the array of sample queues is
extended while the playback thread accesses the arrays.

Detecting this problem early is beneficial to avoid unexplained
exceptions later one. In most cases where this may happen (namely
TS extractors finding new tracks), it's better to ignore the new
tracks instead of failing completely. So this change adds a
warning log message and assigns a placeholder output.

Note: The same workaround already exists in HlsSampleStreamWrapper
and MediaExtractorCompat.

Issue: androidx/media#1476
#cherrypick
PiperOrigin-RevId: 646427213
(cherry picked from commit 18e631ff790e0e9b3630ea8e36efb468474d0877)
2024-07-02 14:11:38 +00:00
Copybara-Service
aa508b1aaf Merge pull request #1479 from dryganets:sdryanets/fix-handler-usage
PiperOrigin-RevId: 646402268
(cherry picked from commit 04667284975e9fc71c137b4a8c133ca5cc626c19)
2024-07-02 14:11:38 +00:00
Copybara-Service
53bb87b7d6 Merge pull request #1416 from khouzam:customFormat
PiperOrigin-RevId: 646121082
(cherry picked from commit b026271c8438f227f4e15e0eaedd7223b4492037)
2024-07-02 14:11:38 +00:00
tonihei
f49fa99aab Add fail-early checks for TrackSelectorResult correctness
The two arrays need to have the same length and the selection
must match in their nullness (unless for TYPE_NONE
renderers). Clarify this more clearly in the docs and add
new asssertions for it. This avoids that the player is failing
in obscure ways much later.

Issue: androidx/media#1473
#cherrypick
PiperOrigin-RevId: 646086833
(cherry picked from commit 71ef848ec3fa4409f3cdf797226c2a51ecd15da6)
2024-07-02 14:11:38 +00:00
tonihei
3a5e367b93 Fix flakiness in MediaCodecVideoRendererTest
The test is flaky because the decoding process in the renderer
depends on some timing from MediaCodec beyond our control and
the new keyframe added in the test is sometimes 'dropped' when
it arrives too late.

We can fix this by controlling the test progress a bit more
tightly: first rendering with the same current time until the
key frame is processed and then start increasing the time
until we've reached the end.

#cherrypick

PiperOrigin-RevId: 646064352
(cherry picked from commit ada4dc982fac32a57db069341f1f51c6a3bb6cc5)
2024-07-02 14:11:38 +00:00
tonihei
c14110cdbf Fix audio focus handling in ExoPlayerImpl
Some cases are not handled correctly at the moment:
 - Pausing during suppressed playback should not clear the
   suppression state.
 - Transient focus loss while paused should be reported as
   a playback suppression.

Issue: androidx/media#1436
#cherrypick
PiperOrigin-RevId: 644971218
(cherry picked from commit e84bb0d21cd114c5b726c6c3d799b194df068a14)
2024-07-02 14:11:37 +00:00
tonihei
05571b3e0d Clarify that onPlayWhenReadyChanged can be called again with new reason
Sometimes the reason for the current state may change. If we don't
report this again, users have no way of knowing that the reason
changed.

Also adjust ExoPlayerImpl and MediaControllerImplBase accordingly.
SimpleBasePlayer already adheres to this logic.

#cherrypick

PiperOrigin-RevId: 644970236
(cherry picked from commit 1d26d1891e6e3cd49a4b479723b8aba7be746c1c)
2024-07-02 14:11:37 +00:00
tonihei
2fd6b60daa Move playWhenReadyChangeReason inside PlaybackInfo
This helps to keep the reason always together with the state it
is referring to, avoiding any side channels and making sure there
are no accidental inconsistencies.

#cherrypick

PiperOrigin-RevId: 644969317
(cherry picked from commit c0abd6f91ec62bc5347561c3f3174b3a660a7ba6)
2024-07-02 14:11:37 +00:00
tonihei
bd5f99cb09 Audio focus player command clean up
The 'player commands' returned to ExoPlayerImpl instruct the
player on how to treat the current audio focus state.

The current return value when playWhenReady==false is misleading
because it implies we are definitely not allowed to play as if
we've lost focus. Instead, we should return the actual player
command corresponding to the focus state we are in.

This has no practical effect in ExoPlayerImpl as we already
ignore the 'player command' completely  when playWhenReady=false.

To facilitate this change, we also introduce a new internal
state for FOCUS_NOT_REQUESTED to distinguish it from the state
in which we lost focus.

#cherrypick

PiperOrigin-RevId: 644416586
(cherry picked from commit 66c19390e2b31106a2a467366f7945c37a273fc6)
2024-07-02 14:10:12 +00:00
tonihei
d76316a1f7 Improve audio focus handling tests with ExoPlayer
There are a lot of tests for AudioFocusManager in isolation,
but almost none for the handling in ExoPlayer.

Add test coverage for all the common cases, including some
currently broken behavior that is indicated by TODOs.

PiperOrigin-RevId: 644319251
(cherry picked from commit e20e94fde277a8e9e9a09e502a5760772e9eb006)
2024-07-02 14:10:12 +00:00
Copybara-Service
f36395ae66 Merge pull request #1437 from MGaetan89:add_exoplayer_setMaxSeekToPreviousPosition
PiperOrigin-RevId: 643987403
(cherry picked from commit 67a7b41fa7453ac4fa06d4d9c7df68e72fbc58ea)
2024-06-17 14:57:01 +00:00
kimvde
eedfb9960e Reset release control from video sink when enabled
PiperOrigin-RevId: 643950097
2024-06-17 03:58:13 -07:00
bachinger
872d8f078b Rollback of cd9b914c42
PiperOrigin-RevId: 643329324
2024-06-14 06:42:31 -07:00
bachinger
cd9b914c42 Remove PreloadConfiguration from public API
This feature isn't completed, so we should remove
the public facing API to avoid confusion.

#minor-release

PiperOrigin-RevId: 643318692
2024-06-14 05:23:53 -07:00
rohks
df5352752f Add a drop-in replacement for MediaExtractor in Media3
This change introduces a new class in Media3 `MediaExtractorCompat`, designed to be a drop-in replacement for platform `MediaExtractor`. While not all APIs are currently supported, the core functionality for the most common use cases of `MediaExtractor` is now available. Full API compatibility will be achieved in the future.

PiperOrigin-RevId: 643045429
2024-06-13 10:33:38 -07:00
tonihei
ca51ed649b Fix single sample handling ProgressiveMediaPeriod when disabling tracks
When deselecting the single sample track and later re-selecting this
track, the current shortcuts in ProgressiveMediaPeriod don't handle
this case correctly and cause assertion failures.

In particular, this change fixes 3 issues:
 1. When re-selecting the single sample track, we have cleared the
    SampleQueue and need to reload the sample. The existing shortcut
    should only be applied to avoid the reload when starting from a
    non-zero position.
 2. When de-selecting the track, ProgressiveMediaPeriod is left in
    an inconsistent state where the sample queues are empty but
    loadingFinished is still true. Fix this by resetting
    loadingFinished to false.
 3. When seeking, we avoid reloading the stream if we can keep
    inside the existing samples. This logic assumes that all
    remaining samples will continue to be loaded in the queue.
    This condition isn't true though for single sample tracks
    that have been de-selected. They appear to support the seek
    inside the queue (=no seek necessary, always supported), but
    still require a new load if there is no ongoing one to load
    the sample. Fix this by checking this implicit assumption
    (still loading, or loading finished).

PiperOrigin-RevId: 642650248
2024-06-12 10:08:10 -07:00
tonihei
54f58cafed Clarify semantics of MSG_SET_IMAGE_OUTPUT
The value can be null, which isn't mentioned in the docs yet

PiperOrigin-RevId: 642622583
2024-06-12 08:30:31 -07:00
kimvde
6234a8bede Move usages of allowReleaseFirstFrameBeforeStarted inside sink
PiperOrigin-RevId: 642611061
2024-06-12 07:39:53 -07:00
bachinger
011ed909c0 Sync and map fatal and non-fatal errors from and to the legacy session
A fatal `PlaybackException` is mapped to a legacy playback state
in state `STATE_ERROR` with error code, message and extras. A
non-fatal error sent to controllers with `MediaSession.sendError`
is synced to the legacy session by setting error code and message
and merging the extras while preserving the rest of the state in
sync with the session player.

Vice versa, a `MediaController` connected to a legacy session receives
fatal errors through `Player.onPlayerErrorChanged()` and non-fatal errors
through `MediaController.Listener.onError()`.

Error codes are mapped in `LegacyConversions`. Values of error codes
in `@SessionError.ErrorCode` come from `@PlaybackExceptino.ErrorCode`
with the exception of `@SessionError.ERROR_IO` and
`@SessionError.ERROR_UNKNOWN`. These already exist in
`@PlaybackException.ErrorCode` and are mapped accordingly to avoid
semantic duplicates.

PiperOrigin-RevId: 642595517
2024-06-12 06:26:00 -07:00
claincly
f2bdc08b24 Fix minor timestamp handling issue
- Video release should check for buffer timestamp (which is renderer-offsetted), rather than the frame timestamp
- ImageRenderer should report ended after all of it's outputs are released, rather than when finished consuming its input.

Add tests for timestamp handling

PiperOrigin-RevId: 642587290
2024-06-12 05:43:22 -07:00
tonihei
8bd6e5d10a Suppress warning about unused return value
The return value is intentionally unused because the check
is only done to see if the reflection operation succeeds.

PiperOrigin-RevId: 642579373
2024-06-12 05:01:23 -07:00
tonihei
27e6395dbc Make ImageOutput clearable
It's currently not possible to remove a previously set image output
on ExoPlayer, although the underlying renderer already supports
receiving null to clear the output. Marking the parameter as
nullable allows apps to clear it as well.

PiperOrigin-RevId: 642569081
2024-06-12 04:03:32 -07:00
kimvde
5a24f40a66 Pass clock to release control from sink provider
In order to do that, make the VideoSink nullable in MCVR.

We want to avoid calling VideoFrameReleaseControl.setClock directly
from MCVR when the sink is enabled. The goal is to handle all the
communication with the release control from the sink/sink provider.

PiperOrigin-RevId: 642542063
2024-06-12 01:51:27 -07:00
ibaker
b145a96c79 Clean up unecessary zero-arg toBundle() methods
These are no longer needed now that the `Bundleable` interface has been
removed. Public methods are deprecated, package-private ones are
removed. Callers are migrated in both cases (except where tests
explicitly exist for the deprecated method).

PiperOrigin-RevId: 642294451
2024-06-11 09:28:23 -07:00
ibaker
f554c12099 Remove Bundleable type & Bundleable.Creator<Foo> CREATOR fields
This interface is not used in the library. Callers can use the
`Bundle toBundle()` and `static Foo fromBundle(Bundle)` methods
defined directly on each type instead.

PiperOrigin-RevId: 642271609
2024-06-11 08:05:32 -07:00
ibaker
253fcb1fd1 Clarify docs on ExoPlayer.setVideoEffects() re calling prepare()
The previous wording suggested that `setVideoEffects()` may **only** be
called before `prepare()`, i.e. the effect cannot be changed during
playback. The intent is instead that `setVideoEffects()` must be called
once before playback in order to configure the effects pipeline, but
the effect can then be changed during playback by further calls to
`setVideoEffects()`.

Issue: androidx/media#1393
PiperOrigin-RevId: 641853629
2024-06-10 04:12:50 -07:00
kimvde
ec49d19384 Call VideoFrameReleaseControl.setPlaybackSpeed from sink when enabled
Do not call VideoFrameReleaseControl.setPlaybackSpeed directly from
MCVR when the video sink is enabled.

PiperOrigin-RevId: 641840894
2024-06-10 03:15:05 -07:00
kimvde
2c71150f2b Set VideoSink listener when enabling MCVR
Before, the listener was set in onReadyToInitializeCodec, which means
that it was reset every time a new codec was used.

We need to set the listener every time MCVR is enabled (not only the
first time), because it might have been set by another renderer.

PiperOrigin-RevId: 641825717
2024-06-10 02:01:00 -07:00
claincly
38a7229d96 Unify timestamp handling
Before this change, the timestamps output from composition playback is offset
with the renderer offset. After this change, the offset is removed and the
timestamp behaviour converges with Transformer, that is, the timestamps of
video/images frames will follow that of the composition. For example, with a
composition of two 10-s items, clipping the first with 2s at the start, the
timestamp of the first frame in the second item, will be 8s.

PiperOrigin-RevId: 641121358
2024-06-06 21:36:15 -07:00
tonihei
f238db8208 Exit early if buffer becomes invalid
When the frame release control invalidates a buffer and returns that
the buffer must be ignored, we need to exit early before performing
additional checks that may result in method calls using the invalid
buffer.

PiperOrigin-RevId: 640555688
2024-06-05 09:48:30 -07:00
kimvde
f54380f9d8 Remove direct usages of release control when video sink is used
Usages removed in this CL are:
- onProcessedStreamChange, which was already called from the VideoSink
  (via VideoFrameRenderControl)
- setOutputSurface, which was also already called from the VideoSink
- setFrameRate, which this CL now sets in the VideoSink

PiperOrigin-RevId: 640530903
2024-06-05 08:19:17 -07:00
kimvde
9716985272 Move renderer state methods from release control to sink
PiperOrigin-RevId: 640515298
2024-06-05 07:16:36 -07:00
kimvde
d5e9f3b224 MCVR: use shouldUseVideoSink where possible
Before this CL, we were checking whether the video sink was initialized
to determine whether it should be used. In the meantime,
shouldUseVideoSink has been introduced. Use this boolean to check
whether to use the video sink as it's a clearer signal.

PiperOrigin-RevId: 640499147
2024-06-05 06:05:03 -07:00
kimvde
3334f0afee Decide whether to use the VideoSink when enabling renderer
This will simplify moving the release control inside the video sink

PiperOrigin-RevId: 640416128
2024-06-04 23:59:10 -07:00
jbibik
35b8ab411d Add isReleased() to the Exoplayer
This avoids having to add AnalyticsListener and catching the `onPlayerReleased` callback.

The `Exoplayer.release()` method is blocking and one can be sure that the player is released if the call returned. However, the method is useful for UI testing and asserting that the player is released after a certain UI action, e.g. closing the activity or detaching a window.

PiperOrigin-RevId: 640114416
2024-06-04 05:11:15 -07:00
rohks
387153fcf2 Fix CMCD data assignment for init segment
The CMCD data was incorrectly added to the `dataSpec` of the media segment instead of the init segment.

Also relaxed the condition for playbackRate to be C.RATE_UNSET when creating an instance of CmcdData.Factory as there was nothing enforcing this check.

#minor-release

PiperOrigin-RevId: 639046080
2024-05-31 08:42:53 -07:00
michaelkatz
ac34798344 Schedule doSomeWork when MediaCodec signals available buffers
When running in asynchronous mode, MediaCodec will be running the CPU to signal input and output buffers being made available for use by the player. With ExoPlayer.experimentalSetDynamicSchedulingEnabled set to true, ExoPlayer will wakeup to make rendering progress when MediaCodec raises these signals. In this way, ExoPlayer work will align more closely with CPU wake-cycles.

PiperOrigin-RevId: 638962108
2024-05-31 02:22:16 -07:00
jbibik
a652c5b3f5 Add references in javadocs to relevant listeners for Player fields
PiperOrigin-RevId: 638688864
2024-05-30 10:02:01 -07:00
michaelkatz
43f719fbb2 Schedule exoplayer work to when MediaCodecAudioRenderer can progress
Currently ExoPlayer schedules its main work loop on a 10 ms interval. When renderers cannot make any more progress (ex: hardware buffers are fully written with audio data), ExoPlayer should be able to schedule the next work task further than 10ms out into the future.

Through `experimentalSetDynamicSchedulingEnabled` and these changes to `MediaCodecAudioRenderer`, ExoPlayer can use the data provided by the audio renderer to dynamically schedule its work tasks based on when it is expected that progress can be made.

PiperOrigin-RevId: 638677454
2024-05-30 09:25:11 -07:00
tianyifeng
e879c4ac43 Call PreloadControl.onSourcePrepared only once for each preload request
PiperOrigin-RevId: 638677090
2024-05-30 09:21:59 -07:00
michaelkatz
9e0f533a11 Schedule exoplayer work task to when renderers can make progress
Currently ExoPlayer schedules its main work loop on a 10 ms interval. When renderers cannot make any more progress(ex: hardware buffers are fully written with audio data), ExoPlayer should be able to schedule the next work task further than 10Ms out.

Through `experimentalSetDynamicSchedulingEnabled`, ExoPlayer will dynamically schedule its work tasks based on when renderers are expected to be able to make progress.

PiperOrigin-RevId: 638676318
2024-05-30 09:19:28 -07:00
tianyifeng
1f1897709f Rename PreloadMediaSource.PreloadControl methods
The IntDefs in `DefaultPreloadManager.Stage` are also renamed accordingly.

PiperOrigin-RevId: 638631357
2024-05-30 06:32:33 -07:00
ibaker
3d8b5811b4 Remove deprecated RendererSupport.FormatSupport IntDef & constants
Use `C.FormatSupport` and associated constants instead.

PiperOrigin-RevId: 637890304
2024-05-28 07:21:48 -07:00