1406 Commits

Author SHA1 Message Date
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
rohks
ecc5cd889f Add getMetrics() API to MediaExtractorCompat
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
2024-11-15 08:17:26 -08:00
bachinger
1af0b5b432 Add handleContentTimelineChanged to AdsLoader
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
2024-11-15 07:49:41 -08:00
Copybara-Service
74611bbdc0 Merge pull request #1265 from DolbyLaboratories:dlb/ac4-level4/dev_new2
PiperOrigin-RevId: 696157037
2024-11-13 09:08:22 -08:00
kimvde
9db66d6c6b Simplify bufferTimestampAdjustment handling
PiperOrigin-RevId: 696060496
2024-11-13 03:21:52 -08:00
kimvde
8393c2e445 Implement/document trivial methods in DefaultVideoSink
PiperOrigin-RevId: 696047835
2024-11-13 02:33:16 -08:00
kimvde
64e92cb8e1 Various refactorings in VideoFrameRenderControl
- 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
2024-11-13 01:15:58 -08:00
rohks
de0e08397e Add caching status APIs to MediaExtractorCompat
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
2024-11-12 05:34:42 -08:00
michaelkatz
0c982a7994 Fix error where non-enabled renderers were set to final
If the renderer has no stream, then it should not be called with `setCurrentStreamFinal` on it.

PiperOrigin-RevId: 695284225
2024-11-11 04:35:25 -08:00
michaelkatz
b329806859 Fix unit test that confirms AAC_LC passthrough is unsupported
PiperOrigin-RevId: 694494792
2024-11-08 07:49:11 -08:00
tianyifeng
2b54b1ebbe Release internal components on preload thread in DefaultPreloadManager
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
2024-11-07 10:50:22 -08:00
rohks
91dfaab93f Add getDrmInitData() API to MediaExtractorCompat
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
2024-11-07 06:33:43 -08:00
rohks
3d51b36e99 Fix wrong class name in error message of MediaExtractorCompatTest
PiperOrigin-RevId: 693685232
2024-11-06 05:08:57 -08:00
tonihei
5336d71c22 Add TestPlayerRunHelper run(player).untilFullyBuffered
This simplifies some common test setup steps that rely on
a fully buffered player before making further test progress.

PiperOrigin-RevId: 693651493
2024-11-06 02:45:51 -08:00
michaelkatz
28b75f7d29 Schedule doSomeWork after setVideoOutput
PiperOrigin-RevId: 693374521
2024-11-05 09:22:17 -08:00
ibaker
286273c10e Enable lint in tests for modules that require no fixes
PiperOrigin-RevId: 693313908
2024-11-05 05:40:03 -08:00
tonihei
76e4abe428 Reduce default values for DefaultLoadControl buffer for playback
PiperOrigin-RevId: 693284512
2024-11-05 03:39:16 -08:00
ibaker
212bd943f5 Fix lint violations in MediaExtractorCompatTest
I missed these as part of aebf822c3c

PiperOrigin-RevId: 692982120
2024-11-04 08:51:47 -08:00
rohks
278eaf47ad Add log session ID APIs to MediaExtractorCompat
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
2024-11-04 06:38:38 -08:00
rohks
261ca326c5 Move MediaExtractorCompatTest from test/ to androidTest/
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
2024-11-04 05:42:45 -08:00
ibaker
aebf822c3c Enable lint errors in exoplayer tests
Follow-up to 76db936d68

PiperOrigin-RevId: 692925617
2024-11-04 05:08:34 -08:00
dancho
bd90ef38b0 MCVR.hasSurfaceForCodec considers VideoSink
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
2024-11-04 03:17:54 -08:00
Copybara-Service
aebda58314 Merge pull request #1829 from colinkho:ssms-custom-exec-2
PiperOrigin-RevId: 692897382
2024-11-04 03:02:46 -08:00