21873 Commits

Author SHA1 Message Date
ibaker
d0b757886e Fix handling of length-delimited NAL units with 1 or 2 byte length
ExoPlayer assumed 4-bytes for length in two places (by assuming the
length is the same as the 4-byte NAL start code):

1. In `AvcConfig` we transform length-delimited to start-delimited
   before writing into `initializationData`, and then skip
   'nal unit length field' bytes when parsing from `initializationData`
   (when we should skip 'start code length' bytes instead).

2. In `Mp4Extractor.readSample` we modify the local variable
   `sampleSize` to fix the difference between length field length and
   start code length, but **only on the first attempt to read a
   sample**. If we are resuming in the middle of reading a sample (after
   a recoverable I/O error), this fix for `sampleSize` is not done,
   which means we end up missing the last 2-3 bytes of the sample when
   the NAL length is 1-2 bytes.
     * This is fixed by moving the `sampleSize` 'fixing' code to outside
       the `if (sampleCurrentNalBytesRemaining == 0)` block.
     * `FragmentedMp4Extractor` has very similar code, but uses a
       field for `sampleSize`, rather than a local, so doesn't look
       vulnerable to the same problem (though I haven't totally
       tested this).

This change adds a test file with 2-byte NAL lengths, generated by
hacking the media3 muxer to emit 2-byte NAL lengths and transforming
`sample.mp4` using the transformer demo app.

PiperOrigin-RevId: 713709203
2025-01-09 10:06:13 -08:00
shahddaghash
64462b99fc Add mediaItem durationUs to Transformer's ExportResult.ProcessedInput
This will allow us to access the duration of the input media items and collect them for metrics.

PiperOrigin-RevId: 713686613
2025-01-09 08:51:00 -08:00
tonihei
b225383958 Don't force discontinuity when clipping a merged source duration
We only care about the duration and don't want to force an initial
discontinuity.

The problem is not currently visible due to a bug in
ClippingMediaPeriod that ignores all dicontinuities if they don't
happen at the clip start position.

PiperOrigin-RevId: 713686333
2025-01-09 08:47:33 -08:00
kimvde
2df50f209e CompositionPlayerTest: increase timeout for emulator tests
Some tests are sometimes timing out because the emulator is too slow.

PiperOrigin-RevId: 713671851
2025-01-09 07:56:55 -08:00
dancho
cd511ea60b Add a test file for FragmentedMp4 captions
The previous FragmentedMp4 captions test asset doesn't have captions.
Fix a bug where captions before extractor seek were output after.

PiperOrigin-RevId: 713665817
2025-01-09 07:35:21 -08:00
tonihei
b9d12837b4 Use live providers in CompositionPlayer to remove workaround
When CompositionPlayer added repeat modes in d0afb96c40, it
changed the logic in SimpleBasePlayer to workaround the specific
scenario in CompositionPlayer that didn't seem to work correctly.
The workaround is not really generically applicable though. The
source of the original problem was that the position values of
all state objects were connected to the "live" source of the
current player so that the repetition case couldn't be detected
(the position before and after the seek looked the same). The
solution is to use the newly added LivePositionSuppliers and
disconnect them before seeking.

PiperOrigin-RevId: 713659638
2025-01-09 07:10:14 -08:00
tonihei
9608ae4e3d Add LivePositionSupplier util to SimpleBasePlayer
In some cases the position is supplied from a "live" source
that keeps changing its value at repeated calls. This typically
happens when forwarding to another backend with unpredictable
position values. The problem is that as soon as the backend
system has a position discontinuity, any previously created
PositionSupplier now returns a position that no longer makes
sense in the context of the State object it belongs to.

ForwardingSimpleBasePlayer already works around this issue by
having a util class to disconnect these live sources. This
change moves the same util to SimpleBasePlayer itself so it
can be reused by other implementations.

PiperOrigin-RevId: 713658046
2025-01-09 07:05:21 -08:00
Googler
8a709a7d76 Remove setPendingVideoEffects from VideoSink.
VideoSink#onInputStreamChanged(int, Format, List<Effect>) should now be used to set video effects on a new input stream.

PiperOrigin-RevId: 713627389
2025-01-09 04:48:21 -08:00
andrewlewis
e1b57c130d Make auto frame registration test non-flaky
Wait for each frame to be rendered before unblocking queueing the next one.

PiperOrigin-RevId: 713621811
2025-01-09 04:21:39 -08:00
michaelkatz
0e6d39de29 Add DefaultRenderersFactory api for experimental MCVR prewarming
If `experimentalSetEnableMediaCodecVideoRendererPrewarming` is set with `true`, `DefaultRenderersFactory` will provide `ExoPlayer` with a secondary `MediaCodecVideoRenderer` for use in pre-warming through its `createSecondaryRenderer` and `buildSecondaryVideoRenderer` implementations. `ExoPlayer` will then pre-process video of subsequent media items to reduce media item transition latency.

PiperOrigin-RevId: 713605911
2025-01-09 03:08:41 -08:00
kimvde
04ff17d939 CompositionPlayerSeekTest: skip some tests on API 31 emulator
The audio decoder is sometimes failing with error "previous call to
queue exceeded timeout - Codec reported err 0x80000000, actionCode 0,
while in state 6/STARTED". This is probably because the emulator is too
slow.

PiperOrigin-RevId: 713564117
2025-01-09 00:24:31 -08:00
jbibik
709d3fd35e [demo-compose] Refactor modifier with better Kotlin syntax
PiperOrigin-RevId: 713476190
2025-01-09 00:22:17 -08:00
michaelkatz
314413365b Implement transfer of resources API for renderer pre-warming
At the point of playing period transition pre-warming has completed and the renderers should receive necessary resources for playback. This CL adds the `Renderer.MessageType` `MSG_TRANSFER_RESOURCES` to direct a renderer to transfer relevant resources to another renderer.

PiperOrigin-RevId: 713372754
2025-01-08 12:12:48 -08:00
tonihei
7d4ddfbb91 Don't force discontinuities for server-side ad insertion transitions
We currently force discontinuities for all clipped content periods
that don't start from zero. This shouldn't be done for server-side
ad insertion streams where we are guaranteed to get a continuous
underlying stream.

To enable the right decision, we need to add a flag to
MediaPeriodInfo for isPrecededByTransitionFromSameStream, which
mirrors the existing isFollowedByTransitionToSameStream.

The problem is currently not visible due to a bug in
ClippingMediaPeriod that automatically ignores most discontinuities
that don't match the start of the clip.

PiperOrigin-RevId: 713315398
2025-01-08 09:23:13 -08:00
kimvde
d9776e74c8 PlayerListener: do not swallow exceptions thrown before waiting
If an error occurred in the player before the test was calling one of
the waitUntilSomething() methods, a timeout exception was thrown instead
of the actual error.

PiperOrigin-RevId: 713292292
2025-01-08 08:03:46 -08:00
tonihei
b321c8d3bd Discard already written sample data for clipped DASH periods
DASH periods can have a duration that is less than the end of the
last chunk in the period. In these cases, the sample data needs to
be clipped to the declared period duration. This already happens
IF the period duration is known at the point where we start loading
the media chunk. However, if the duration becomes known later or is
reduced (e.g. in a live stream), the existing media chunks are not
clipped. This causes unclean transitions across periods where the
player tries to transition to the next period, but renderers struggle
to output all the remaining surplus samples that should have been
clipped.

This can be fixed by asking ChunkSampleStream to discard surplus
samples that were loaded beyond a clipped duration when evaluating
the sample queue between chunk loads.

Issue: androidx/media#1698
PiperOrigin-RevId: 713288221
2025-01-08 07:47:54 -08:00
kimvde
bb3b85a359 CompositionPlayerSeekTest: don't hide exception while waiting on latch
If a playback exception was thrown before or during awaiting the
frameCountBeforeBlockLatch, a TimeoutException was thrown instead of the
playback exception, hiding the actual cause of the failing test.

PiperOrigin-RevId: 713279627
2025-01-08 07:10:09 -08:00
kimvde
30038079c4 Split CompositionPlayerSeekTest.playSequenceAndGetTimestampsUs
This method is already quite complex and I will need to add more
complexity, so split it into multiple smaller methods.

This CL is a refactoring. There are no functional changes.

PiperOrigin-RevId: 713266816
2025-01-08 06:18:48 -08:00
jbibik
79d41aac7e [ui-compose] Fix PlayerSurface's use of Player
The new `currentPlayer` was only used to check the available command. It should also be used for setting and clearing the Surface.

The PlayerSurface was still behaving correctly, perhaps due to the lambda being reevaluated with the new player (since `currentPlayer` is of type MutableState). Which meant it was also using the latest `player` that `PlayerSurface` was recomposed with (in the argument), rather than holding onto the original object.

PiperOrigin-RevId: 713264041
2025-01-08 06:07:14 -08:00
kimvde
48e3eaa623 CompositionPlayerSeekTest: increase test timeout for emulators
Some tests are sometimes timing out because the emulator is too slow.

PiperOrigin-RevId: 713259939
2025-01-08 05:48:18 -08:00
kimvde
3a00960831 Remove stale Javadoc
PiperOrigin-RevId: 713253227
2025-01-08 05:16:01 -08:00
dancho
0cf52ed45d Read sample dependencies for H.265 in MP4
Add a new Mp4Extractor.FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES_H265
Read two bytes from H.265 videos to determine NAL unit type and
temporal layer id.

PiperOrigin-RevId: 713248154
2025-01-08 04:55:31 -08:00
dancho
b54d8737cf Add number of temporal layers to Format
The number of temporal sub-layers is required for
H.265 non-reference frame identification as
only frames from the highest temporal sub-layer can be
discarded.

PiperOrigin-RevId: 713247354
2025-01-08 04:50:45 -08:00
dancho
281a0e7ac8 Populate HevcConfig with number of temporal layers
The number of temporal sub-layers is required for
H.265 non-reference frame identification as
only frames from the highest temporal sub-layer can be
discarded.

PiperOrigin-RevId: 713242894
2025-01-08 04:31:24 -08:00
dancho
b3e18729d3 H.265 parse number of temporal layers from SPS
Expose NalUnitUtil.H265SpsData.maxSubLayersMinus1
Required for H.265 non-reference frame identification as
only frames from the highest temporal sub-layer can be
discarded.

PiperOrigin-RevId: 713232825
2025-01-08 03:48:24 -08:00
shahddaghash
1bea11637b Add setting final progress at export error or cancellation
The change includes setting the final progress percentage when the export completes with error or is cancelled. The value for the progress is collected by calling `Transformer.getProgress()` before `transformerInternal` is set to null.

PiperOrigin-RevId: 713227568
2025-01-08 03:24:18 -08:00
shahddaghash
d894217a4e Fix typo for precreateEditingEndedEventBuilder method
PiperOrigin-RevId: 712969879
2025-01-07 10:56:15 -08:00
sheenachhabra
bcae7abde9 Remove TrackToken and replace with int trackId
This is to make API simpler and to have parity with `MediaMuxer`

PiperOrigin-RevId: 712954669
2025-01-07 10:16:31 -08:00
shahddaghash
8dca430e42 Add setting final progress when export success for metrics
Set the progress to 100% for a successful export operation.

PiperOrigin-RevId: 712946218
2025-01-07 09:52:43 -08:00
shahddaghash
6f187a3859 Add confetti overlay to Effect demo
Added the first overlay effect to the Effect demo. It includes an emitter of confetti that drops from the center of the frame.

PiperOrigin-RevId: 712940163
2025-01-07 09:33:36 -08:00
dancho
229aadc91b Update javadoc for FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES
Reflects that FLAG_READ_WITHIN_GOP_SAMPLE_DEPENDENCIES only parses
H.264 bitstream, and that H.265 parsing will be controlled with
another flag.

PiperOrigin-RevId: 712921990
2025-01-07 08:33:14 -08:00
bachinger
ec50358784 Do not override pending info when masking
PiperOrigin-RevId: 712919739
2025-01-07 08:26:19 -08:00
andrewlewis
e11aabb794 Allow RawAssetLoader media to have unset duration
This will be useful for recording use cases, including screen recording with
audio queued via `RawAssetLoader`, where the duration is unknown.

PiperOrigin-RevId: 712895577
2025-01-07 06:59:21 -08:00
ivanbuper
871381288c Use static methods for getSpeedAdjustedTimeAsync and getMediaDurationUs
This change simplifies SpeedChangingAudioProcessor by removing unneeded
heuristics and synchronization added as workarounds to estimate input
and output frame counts.

The synchronization between the video processing and audio processing
threads cannot be completely removed yet because the static methods
depend on the input sample rate for the calculations. However, once
`SpeedChangingAudioProcessor` has been configured, then
`#getSpeedAdjustedTimeAsync()` should invoke the callback immediately.

PiperOrigin-RevId: 712893246
2025-01-07 06:49:49 -08:00
jbibik
2dc6af1fae [ui-compose] Add PresentationState for first-frame info
It captures some information needed for the UI logic related to rendering of the video track (and later images) to the surface.

Supporting `EVENT_RENDERED_FIRST_FRAME` helps improve the UX by covering the surface with an overlay (scrim/shutter) until the first frame is ready. This helps avoid sudden flickering during MediaItem transitions.

PiperOrigin-RevId: 712889568
2025-01-07 06:34:02 -08:00
ibaker
31e5142b72 Restrict SubRip and WebVTT parsing to exactly 3 decimal places
We previously parsed an arbitrary number of decimal places, but assumed
the value was in milliseconds, which doesn't make sense if there is
greater or fewer than 3. This change restricts the parsing to match
exactly 3, meaning the millisecond assumption is always true.

The WebVTT spec requires there to be exactly 3 decimal places:
https://www.w3.org/TR/webvtt1/#webvtt-timestamp

The SubRip spec is less clearly defined, but the Wikipedia article
defines it as having exactly 3 decimal places
(https://en.wikipedia.org/wiki/SubRip#Format) and ExoPlayer has always
assumed 3 decimal places (anything else is already handled incorrectly),
so this change just ensures we don't show subtitles at the wrong time.

Issue: androidx/media#1997
PiperOrigin-RevId: 712885023
2025-01-07 06:13:15 -08:00
andrewlewis
9ac91aaadd Return concrete SurfaceAssetLoader from factory
If the caller is another asset loader (or another asset loader factory) that is
delegating to a `SurfaceAssetLoader`, it may want to call methods on the
`SurfaceAssetLoader`. Return the concrete type so that a cast isn't necessary
at the call site.

PiperOrigin-RevId: 712881130
2025-01-07 06:02:24 -08:00
Copybara-Service
38363acc8d Merge pull request #1785 from DolbyLaboratories:dlb/dovi-supplemental-codecs/dev
PiperOrigin-RevId: 712867412
2025-01-07 04:58:21 -08:00
tonihei
a9f9928eb3 Temporarily remove test class to avoid build breakage
PiperOrigin-RevId: 712862960
2025-01-07 04:40:28 -08:00
andrewlewis
5a87aab2f7 Use Util to request permissions in Transformer demo
This avoids requesting storage permissions for URLs that don't require it.

Also tidy clean-up into `cleanUpExport`, rename `releasePlayer` to
`releasePlayers` as there are players for both input and output, and reduce
live range of `uri` variable.

PiperOrigin-RevId: 712857115
2025-01-07 04:13:36 -08:00
shahddaghash
0074a97333 Remove unnecessary released condition in getProgress
Removed the check for `released` flag to be able to pass the actual progress when the export completes.

Also, removed resetting the `progressState` and `progressValue` to be able to get the actual progress. This block is also not necessary to have at this point.

PiperOrigin-RevId: 712851526
2025-01-07 03:53:06 -08:00
andrewlewis
0044d0cebc Fix GLES31 javadoc reference to be unambiguous and link correctly
PiperOrigin-RevId: 712848161
2025-01-07 03:35:30 -08:00
Googler
b2aa8d6d21 Add sample rate fallback to AudioSampleExporter
After this change, if the sample rate supported by the encoder differs from the requested sample rate and enableFallback is true, the AudioSampleExporter will convert audio to a sample rate supported by the encoder. This fixes a bug where the audio track is distorted when an unsupported sample rate is requested.

PiperOrigin-RevId: 712822358
2025-01-07 01:52:57 -08:00
Googler
6c2d25184c Make FragmentedMp4Muxer use OutputStream instead of FileOutputStream.
This lets us provide a append-only output stream with overridden write() methods - unlocking use cases where we process the muxed data in a streaming fashion, as it's generated by the fragmented muxer.

PiperOrigin-RevId: 712581859
2025-01-06 10:46:00 -08:00
jbibik
575a2ebbd8 [ui-compose] Add gradle version to androidx.compose.foundation
This will ensure that the new `ui-compose` module gets published on Maven

The fix is not necessary for `demo-effect` and `demo-compose` because they are not publishable

PiperOrigin-RevId: 712555702
2025-01-06 09:34:44 -08:00
Copybara-Service
8fe0b7ac69 Merge pull request #1987 from ojoNetgem:Support_for_origin_and_extent_declared_in_ttml_styles
PiperOrigin-RevId: 712554507
2025-01-06 09:30:15 -08:00
jbibik
ff80ab220f [demo-compose] Add Activity lifecycle methods
Take care of releasing the player and re-initialising when returning to the app to prevent memory leaks.

Instead of overriding onStart, onPause, onResume, onStop - use Lifecycle*Effects for a more native compose cleanup. Requires a higher version of the lifecycle library.

PiperOrigin-RevId: 712542884
2025-01-06 08:49:41 -08:00
Ian Baker
8d9cb7e5d0 Resolve some TODO comments that are now fixed by the new parsing support 2025-01-06 15:13:32 +00:00
Ian Baker
618c2cf952 Add a release note and format with google-java-format 2025-01-06 15:13:32 +00:00
Olivier Jouvenaux
82bed39140 Add unit tests for TTML region attrs in style, chained styles UT 2025-01-06 15:13:32 +00:00