1428 Commits

Author SHA1 Message Date
bachinger
83b5eb0040 Add HlsInterstitialsAdsLoader
Reads HLS interstitials information from the playlist and
populates the `AdPlaybackState` accordingly to play the ads.

An app can register a `Listener` to be informed about ad
related events.

Only VOD streams are supported and X-ASSET-LIST attibutes
are ignored with this change.

PiperOrigin-RevId: 705604201
2024-12-12 13:04:10 -08:00
rohks
4997ea82fa Refactor CmcdData to handle object type determination internally
Moved the `getObjectType` method from `CmcdData.Factory` to `CmcdData` and updated the logic to derive the object type directly within `CmcdData`. This change eliminates the need for chunk source classes to set this value explicitly.

PiperOrigin-RevId: 705457755
2024-12-12 04:36:16 -08:00
ibaker
0b0c198f59 Publish some internal tests now we depend on Robolectric 4.14.1
PiperOrigin-RevId: 705411400
2024-12-12 01:28:26 -08:00
sheenachhabra
f587ac2a67 Remove bundle-serialization methods from ExoPlaybackException
The `toBundle()` method is implemented incorrectly as it uses
`parcelable` implementation to bundle `Format.metadata`.
The `parcelable` is not compatible and is likely to cause crashes if
a new field is added or removed.

Moreover, the `fromBundle` method is likely unused as in session
module the exception is [unbundled](df887a9422/libraries/session/src/main/java/androidx/media3/session/PlayerInfo.java (L1021)) as `PlaybackException`.

This is a non breaking change as all the calls to `toBundle()` and
`fromBundle` will now go to the parent class `PlaybackException`.

If this specific bundling is required in future then `Format.Metadata`
and all the `Metadata.Entry` classes need to provide `toBundle()`
and `fromBundle()` method.

PiperOrigin-RevId: 705167002
2024-12-11 11:06:01 -08:00
Googler
3936c27b6d Don't check codec's profile for MV-HEVC video.
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
2024-12-11 10:59:26 -08:00
rohks
de31a3745c Make some no-op refactoring in CmcdData
- Moved static fields for object type, stream type, etc. from `CmcdData.Factory` to `CmcdData`.
- Removed redundant `CmcdData` prefix from `@ObjectType` and `@StreamingFormat` annotations.

#cleanup

PiperOrigin-RevId: 705159876
2024-12-11 10:46:22 -08:00
microkatz
2f880bf051 Added release note 2024-12-11 15:31:00 +00:00
microkatz
55d9626b5a Format with google-java-format 2024-12-11 14:56:25 +00:00
Gilles Khouzam
f149cb28a3 Add MediaCodecInfo to MediaCodecRenderer::onReadyToInitializeCodec 2024-12-11 14:56:25 +00:00
kimvde
424b43d2eb Fix CompositionPlayerSeekTest timeout
Playback was never ending in the case where the video graph rendered
the last frame to the output surface before the end-of-current-input
signal was received. This CL handles this specific case.

PiperOrigin-RevId: 705086366
2024-12-11 06:39:49 -08:00
rohks
8d2f531470 Enable sending CmcdData for manifest requests in DASH, HLS and SS
Issue: androidx/media#1951
PiperOrigin-RevId: 704875765
2024-12-10 15:59:39 -08:00
ibaker
c377a34a5a Don't call onAudioPositionAdvancing if AudioTrack is paused
`AudioTrackPositionTracker.pause` "re-arms" the event, to ensure it
fires again when playback resumes. However the `AudioTrack` position
advances by about 100ms **after** `AudioTrack.pause()`, which
consistently causes the event to fire immediately after pausing (and
then **not** after a subsequent resumption).

This change checks whether the `AudioTrack` is paused before firing
the event, to avoid this spurious trigger.

PiperOrigin-RevId: 704759929
2024-12-10 10:31:46 -08:00
michaelkatz
6689fee2b2 Implement error handling support for pre-warming renderers
PiperOrigin-RevId: 704408379
2024-12-09 14:04:00 -08:00
michaelkatz
be63e156bb Implement mediasource list update support for pre-warming renderers
PiperOrigin-RevId: 704381778
2024-12-09 12:41:37 -08:00
michaelkatz
bb62278627 Implement track reselection support for pre-warming renderers
PiperOrigin-RevId: 704371028
2024-12-09 12:07:58 -08:00
ibaker
ef19740c92 Remove Forwarding from assertForwardingClassOverridesAllMethods
And use it in a "non-forwarding" context in
`DefaultAnalyticsCollectorTest`.

PiperOrigin-RevId: 704331859
2024-12-09 10:22:06 -08:00
michaelkatz
459162c692 Implement seeking support for pre-warming renderer feature
PiperOrigin-RevId: 704328162
2024-12-09 10:12:11 -08:00
michaelkatz
987869e456 Implement secondary renderer feature for pre-warming
`RenderersFactory#createSecondaryRenderer` can be implemented to provide secondary renderers for pre-warming. These renderers must match their primaries in terms of reported track type support and `RendererCapabilities`.

If a secondary renderer is provided, ExoPlayer will enable it for a subsequent media item as soon as its `MediaPeriod` is prepared. This will cause the renderer to start decoding and processing content so that it is ready to play as soon as playback transitions to that media item.

PiperOrigin-RevId: 704326302
2024-12-09 10:07:33 -08:00
ibaker
38d12f25e1 Consistently ignore non-fatal errors in subtitle loading error tests
It's expected that the subtitle load errors are emitted as a non-fatal
error, but it's not defined exactly when they will be emitted. By
consistently ignoring these every time we 'advance' the player, this
de-flakes the test (currently it fails when `untilFullyBuffered()`
triggers a non-fatal error).

PiperOrigin-RevId: 704219317
2024-12-09 03:39:57 -08:00
dancho
1d2ffcb165 Frame extraction support changing MediaItem
Add FrameExtraction.setMediaItem() method
Prefer non-vendor software codecs by default because
vendor codecs sometimes fail when we attempt reuse.

PiperOrigin-RevId: 703486235
2024-12-06 06:57:21 -08:00
ibaker
b5a1efdbce ForwardingTimeline: Implement & finalize some methods
`equals`, `hashCode`, and `getPeriodByUid` are correctly implemented on
`Timeline`. Overriding these in a way that maintains correctness is
fiddly, so this CL prevents that for the 'simple' case of subclasses of
`ForwardingTimeline`. Implementations of `Timeline` that need to
override these methods for performance should extend `Timeline` or
`AbstractConcatenatedTimeline` instead of `ForwardingTimeline`.

PiperOrigin-RevId: 703035721
2024-12-05 02:24:19 -08:00
ibaker
92e0b5978f Add ForwardingTimelineTest
PiperOrigin-RevId: 703029260
2024-12-05 01:59:07 -08:00
rohks
e927d7b986 Fix ReplacingCuesResolver.discardCuesBeforeTimeUs to retain active cue
The method previously discarded the cue that was active at `timeUs`,
meaning it had started before but had not ended by `timeUs`.

Issue: androidx/media#1939

#cherrypick

PiperOrigin-RevId: 702707611
2024-12-04 06:51:12 -08:00
kimvde
06b94f5448 DefaultVideoSink: implement handleInputFrame() and listeners
With this CL, PlaybackVideoGraphWrapper doesn't call the
VideoFrameRenderControl directly anymore (which is one of the goals of
DefaultVideoSink).

PiperOrigin-RevId: 702673821
2024-12-04 04:29:03 -08:00
ibaker
876abe315b Increase library target SDK to 31
This only affects the default SDK level that Robolectric tests run at.
Also upgrade the Robolectric version to 4.14.1 to pick up
4f32042afe
which is needed for async `ShadowMediaCodec` support (the default in
ExoPlayer from API 31+).

Some tests fail on Robolectric at API 31. This change configures them to
continue running on API 30, so the failures can be investigated and
fixed in follow-up changes.

PiperOrigin-RevId: 702357124
2024-12-03 08:57:53 -08:00
tianyifeng
148641f049 Move BasePreloadManager.Listener to a top level PreloadManagerListener
PiperOrigin-RevId: 702351887
2024-12-03 08:38:35 -08:00
ibaker
18d156fe3c Configure ProgressiveMediaSource with a Format for subtitles
This means we can complete preparation (and trigger track selection)
before opening a `DataSource`, which then means we only end up loading
the data for a selected subtitle track (instead of all tracks as
currently happens).

By making preparation trivial in this case (with no reasonable cause
of error), we can also remove the `suppressPrepareError` option added in
b3290eff10.

This change also fixes the implementation of
`ProgressiveMediaPeriod.maybeStartDeferredRetry` to only short-circuit
return `false` if the chosen track is not audio or video **and** there
is at least one audio or video track in this period.

Issue: androidx/media#1721
PiperOrigin-RevId: 702275968
2024-12-03 03:40:49 -08:00
kimvde
0037388660 Simplify VideoSink.handleInputFrame
This method was taking positionUs and elapsedRealtimeUs parameters and
throwing a VideoSinkException because it was calling render() to make
room for a new input frame. Instead of doing that, this CL makes sure
render() is called before  handleInputFrame() in the renderer (even
though it may not make a significant difference).

PiperOrigin-RevId: 702273587
2024-12-03 03:29:30 -08:00
claincly
8908d82cac Signal end of stream to VideoFrameProcessor in previewing
This will be used by VideoCompositor

PiperOrigin-RevId: 702031907
2024-12-02 11:30:20 -08:00
ibaker
25c927e9f3 Standardize ForwardingXXX tests
Add missing ones for `ForwardingExtractorInput` and `ForwardingSeekMap`.
`ForwardingTimeline` is a bit more fiddly, so it's left for a follow-up
change.

PiperOrigin-RevId: 701988492
2024-12-02 09:12:53 -08:00
Colin Kho
24ea6c4c14 Relax PlaybackStuck criteria to only when playWhenReady is true 2024-11-28 14:06:44 +00:00
kimvde
4d925bde81 Remove stale TODO
Handling (very) late buffers is already supported.

PiperOrigin-RevId: 700965581
2024-11-28 03:02:59 -08:00
kimvde
852091f2d9 Implement DefaultVideoSink.isEnded
To do that, I had to add VideoFrameRenderControl.signalEndOfInput() and
isEnded() to match the VideoSink interface.

PiperOrigin-RevId: 700957098
2024-11-28 02:27:50 -08:00
kimvde
f3f4646296 Add VideoSink.signalEndOfCurrentInputStream()
The isLastBuffer flag passed to MediaCodecRenderer.processOutputBuffer()
is unreliable. It is true for the last frames (plural) of a video
stream, which makes it possible for the video renderer to end before all
the frames have been rendered to the output surface.

PiperOrigin-RevId: 700941685
2024-11-28 01:23:55 -08:00
rohks
08619bf6fa Add KEY_TRACK_ID to MediaFormat returned by getTrackFormat(int)
This aligns the behavior with `MediaExtractor`, which sets this key in its [`MediaFormat`](https://developer.android.com/reference/android/media/MediaExtractor#getTrackFormat(int)) output.

Additionally, unnecessary `selectTrack` calls have been removed from the existing `getTrackFormat_...` tests, as they are not required to fetch the track format.

PiperOrigin-RevId: 700741326
2024-11-27 10:26:30 -08:00
rohks
270543555d Add getSampleCryptoInfo API to MediaExtractorCompat
This method enables handling encrypted samples by providing the necessary decryption details.

PiperOrigin-RevId: 700729949
2024-11-27 09:48:11 -08:00
rohks
52e45e0864 Prepare for CryptoInfo support by removing cached size
Currently, `size` is cached in `SampleMetadata` when samples are committed in `SampleQueue`, which worked because we didn't support reading files with `CryptoInfo`. This change prepares for future `CryptoInfo` support, as the size changes when reading samples with encrypted data. Caching the size at commit time could lead to incorrect buffer `size` calculations.

Existing tests verify the correctness of the `getSampleSize()` API.

PiperOrigin-RevId: 700714178
2024-11-27 08:47:37 -08:00
rohks
a371824dbc Remove unnecessary @SuppressLint("Override")
The Android SKD version 30 is stable, allowing us to remove the `@SuppressLint("Override")` annotations from `InputReaderAdapterV30` and `OutputConsumerAdapterV30`.

PiperOrigin-RevId: 700681115
2024-11-27 06:32:24 -08:00
ibaker
46578ee0a6 MP3: Use bytes field from VBRI frame instead of deriving from ToC
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/media#1904

#cherrypick

PiperOrigin-RevId: 700319250
2024-11-26 06:18:29 -08:00
dancho
0d8f1d5ab9 Add Frame Extractor configuration for mediacodecselector
Adds a configuration option to Frame Extractor to choose MediaCodecSelector.
Add a MediaCodecSelector that lists software decoders first

PiperOrigin-RevId: 699962365
2024-11-25 06:40:28 -08:00
claincly
7ef1a7ab8b Support renderer joining in CompositionPlayer
Renderers join when they can start processing but not produce output.

In CompositionPlayer before this change, the VideoSink will be flushed when
position is reset regardless. This is useful for seeking, as seeking triggers position reset. But with pre-warming, a video renderer can be joining -  it is
enabled (which also triggers position reset) before the previous image renderer
is disabled. At this moment, as the image renderer is still producing frames,
we should not flush the video sink just now.

PiperOrigin-RevId: 699943882
2024-11-25 05:22:22 -08:00
kimvde
25a782e10a Stop delaying registering input stream on VideoFrameProcessor
We are currently waiting until stream 1 is completely rendered on screen
before registering stream 2 but that is not necessary anymore because
VideoFrameProcessor supports registering stream 2 before stream 1 is
fully processed.

PiperOrigin-RevId: 699929943
2024-11-25 04:17:32 -08:00
kimvde
79effe7b60 Remove call to getFrameReleaseAction prior to applying effects
This call does 2 things:
1. It's used to estimate the frame rate early but this is incorrect as
   the frame rate can be changed by effects. I have tested playback on
   my device and I don't see any difference.
2. For ExoPlayer.setVideoEffects() only: it allows dropping all the
   frames until the next key frame in case the input frame is "very
   late". This doesn't seem really necessary though because because we
   do the same thing after applying effects.

This change is also a step towards moving all the calls to
VideoFrameRelease/RenderControl to DefaultVideoSink.

PiperOrigin-RevId: 698732161
2024-11-21 04:38:54 -08:00
michaelkatz
5282fe3125 Rollback of 854566dbfe
PiperOrigin-RevId: 698730105
2024-11-21 04:29:19 -08:00
claincly
3c01500a4e Use dynamic scheduling to speed up rendering the first image frame
3P app reported it's slow to see the first image frame on the screen, when
`playWhenReady` is false. This is because the player would wake up less
frequently when `playWhenReady` is false. This CL adds a runnable to wake up
the player any time a new frame is made available.

PiperOrigin-RevId: 698066887
2024-11-19 10:33:59 -08:00
rohks
d702e1d496 Add getPsshInfo() API to MediaExtractorCompat
This method retrieves PSSH (Protection System Specific Header) data from the media as a map of UUID-to-bytes.

PiperOrigin-RevId: 697974134
2024-11-19 05:14:55 -08:00
kimvde
b782cdff52 Don't drop frames to ignore in RenderControl
The following was happening:
- VideoFrameRenderControl.render() was calling
VideoFrameReleaseAction.getFrameReleaseAction().
- VideoFrameReleaseAction.getFrameReleaseAction() was calling
FrameTimingEvaluator.shouldIgnoreFrame(), which is implemented in
MediaCodecVideoRenderer.
- MediaCodecVideoRenderer.shouldIgnoreFrame(), when returning true,
was also flushing the VideoSink, which was flushing the
VideoFrameRenderControl.
- VideoFrameRenderControl.render() was removing the frame from the
presentationTimestampsUs queue, but the frame had already been removed
by the flush operation, causing an exception to be thrown.

This fix removes the last step.

PiperOrigin-RevId: 697915692
2024-11-19 01:15:17 -08:00
kimvde
8be2556efd Implement DefaultVideoSink.setStreamTimestampInfo
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
2024-11-18 02:01:52 -08:00
kimvde
2568ff73cb Remove unnecessary checkStateNotNull checks
LongArrayQueue.remove() throws a NoSuchElementException if the queue is
empty.

PiperOrigin-RevId: 697531458
2024-11-18 01:05:34 -08:00
tianyifeng
0143884cd7 Deflake the DefaultPreloadManagerTest
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
2024-11-15 08:22:54 -08:00