2487 Commits

Author SHA1 Message Date
jbibik
d022b570f2 Upgrade Kotlin to 2.0.20
This upgrade allows us to use https://developer.android.com/develop/ui/compose/compiler as specified in https://developer.android.com/jetpack/androidx/releases/compose-kotlin#pre-release_kotlin_compatibility

kotlinOptions is considered deprecated in preference of kotlin.compilerOptions (https://kotlinlang.org/docs/gradle-compiler-options.html#how-to-define-options)

PiperOrigin-RevId: 725266131
2025-02-10 10:32:47 -08:00
andrewlewis
1a996d87ca Add MediaProjectionAssetLoader
The new asset loader is a wrapper around a provided `MediaProjection` and
`SurfaceAssetLoader`.

The test relies on automating the UI to get a `MediaProjection` instance, which
doesn't work reliably on all devices, so it's restricted to Pixel devices from
API 29 onwards.

For now only video is supported. The plan is to add support for audio playback
capture (also using `MediaProjection`) in a later change(s).

PiperOrigin-RevId: 725241962
2025-02-10 09:23:34 -08:00
tianyifeng
1190980616 Remove deprecated DownloadHelper constructor and util method
PiperOrigin-RevId: 724300907
2025-02-07 04:50:49 -08:00
dancho
a56a0bd928 MCVR: drop decoder input buffers when the decoder is late
* Add experimentalSetMinEarlyUsToDropDecoderInput to DefaultRenderersFactory
and MediaCodecVideoRenderer
* Enable dropping decoder input buffers inside MCVR.shouldIgnoreFrame
* Track consecutive dropped buffers via priority queue for reordering

PiperOrigin-RevId: 723837356
2025-02-06 01:40:28 -08:00
rohks
6a4aa4515e Update release notes for Media3 1.6.0-alpha03 release
#cherrypick

PiperOrigin-RevId: 723512116
2025-02-05 08:03:50 -08:00
dancho
2fe92bfca5 Use the AV1 sample dependency parser in MCVR
Parsing AV1 bitstreams allows us to identify frames that are
not used as reference, and improve seeking or frame dropping
behavior.

The AV1 bitstream format is relatively quick to parse

PiperOrigin-RevId: 723462680
2025-02-05 04:51:02 -08:00
michaelkatz
97a1d31b5d Reset prewarming renderers when seek resets prewarming media period
Seeking will reset media periods following the current playing period. This includes resetting any current pre-warming media periods. Therefore while seeking, any current pre-warming should be disabled and reset.

#cherrypick

PiperOrigin-RevId: 723439145
2025-02-05 03:14:38 -08:00
dancho
f8f66bdfaa Mp4Muxer: disable sample batching and copying by default.
When sample batching is disabled, copying of the ByteBuffer data
is not necessary as samples are written as they arrive.
Copying of the BufferInfo is necessary because the info is needed
for writing the moov atom.

The input ByteBuffer can be in little endian order, or have its
position set. AnnexBUtils now ensures big endian order before
inspecting bytes, and supports reading from a non-zero position.

This change reduces the amount of memory allocations by Mp4Muxer
in its default configuration

PiperOrigin-RevId: 723401822
2025-02-05 01:05:22 -08:00
tonihei
39d0881083 Add option to ClippingMediaSource to clip unseekable media
This means we need convert some of the assertions in
ClippingMediaPeriod to contrain the output value to clipped
range instead, because unseekable media will return zero
as a start and seek position in all cases.

PiperOrigin-RevId: 721463824
2025-01-30 11:40:46 -08:00
rohks
344214d711 Fix RELEASENOTES based on style guide
PiperOrigin-RevId: 721401564
2025-01-30 08:36:39 -08:00
microkatz
ad18ae9c42 Added release note 2025-01-30 11:40:56 +00:00
rohks
045b8e6a52 Fix lint warnings in RELEASENOTES
PiperOrigin-RevId: 721326280
2025-01-30 03:35:04 -08:00
ivanbuper
fc6df77831 Remove deprecated androidx.media3.exoplayer.audio.SonicAudioProcessor
Also, make `androidx.media3.common.audio.SonicAudioProcessor` final.

PiperOrigin-RevId: 720987023
2025-01-29 08:30:09 -08:00
rohks
6e53d9b3bd Update release notes for Media3 1.6.0-alpha02 release
#cherrypick

PiperOrigin-RevId: 720963785
2025-01-29 07:16:55 -08:00
rohks
e15438322d Fix ArrayIndexOutOfBoundsException in MP4 edit lists
The exception occurred when an edit list started at a non-sync frame with no preceding sync frame. The fix searches forward for the next sync frame in such cases, preventing the out-of-bounds access.

Issue: androidx/media#2062

#cherrypick

PiperOrigin-RevId: 720642687
2025-01-28 11:13:38 -08:00
ibaker
a7a5d6e92b Suppress (and log) subtitle errors in SubtitleTranscodingTrackOutput
This is equivalent to the error suppression for legacy subtitles in
`TextRenderer`:
76088cd6af/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/TextRenderer.java (L357-L359)

This new suppression only affects errors thrown from files with
subtitles muxed together with audio/video. Standalone subtitle
files, and containers containing only text tracks, are handled
by the existing error suppression/reporting added in
49dec5db8b.

Issue: androidx/media#2052
PiperOrigin-RevId: 718930243
2025-01-23 10:49:23 -08:00
Copybara-Service
c1242ffef1 Merge pull request #1235 from DolbyLaboratories:dlb/dovi-transformer/dev
PiperOrigin-RevId: 718856455
2025-01-23 07:26:21 -08:00
Copybara-Service
916018d9fe Merge pull request #1936 from colinkho:eval-buf
PiperOrigin-RevId: 718809019
2025-01-23 04:27:16 -08:00
microkatz
b6d4886887 Reevaluate ongoing chunk loading when pausing 2025-01-22 16:23:55 +00:00
ibaker
9bb254f697 Skip SSA cues where end time is before or equal to start time
The file in Issue: androidx/media#2052 contains a cue with the following timecode:

```
0:00:00:00,0:00:00:00
```

The content of this cue seems to be some 'converted by' metadata, i.e.
it's basically a comment and clearly not intended to be shown on
screen (since it has zero duration).

There is some fiddly logic later in `SsaParser` to support overlapping
cues with the old `Subtitle` structure [1], and this logic gets tripped
up by the start and end time being equal, which results in a
**single**, empty `List<Cue>` being added - which trips up another
assumption that every SSA cue line results in at least two `List<Cue>`
entries (one containing the cue text, and another containing an empty
list to signal the end of the cues).

This fiddly logic is no longer required, because overlapping
`CuesWithTiming` objects can now be merged in `TextRenderer`, so there
is a possible future simplification to `SsaParser` which removes a lot
of this complexity.

[1] Added in <unknown commit>

PiperOrigin-RevId: 718380386
2025-01-22 07:41:24 -08:00
sheenachhabra
a31c7ad9a8 Move Muxer.java interface into transformer module
Muxer interface is used only in transformer.

PiperOrigin-RevId: 717538306
2025-01-20 08:13:42 -08:00
sheenachhabra
fb58bdfd52 Refactor: Mp4Muxer and FragmentedMp4Muxer no longer implement Muxer
Mp4Muxer and FragmentedMp4Muxer has different contracts
and they can not implement same interface.

PiperOrigin-RevId: 717526288
2025-01-20 07:20:48 -08:00
tonihei
190563b8eb Move StreamVolumeManager system calls to playback thread
This requires some additional state handling to update the full
state atomically and guess placeholder states while updates are
in progress, using the newly added BackgroundThreadStateHander.

Some tests also needed to be adjusted to account for the fact
that the actual audio system change doesn't happen inline
anymore.

PiperOrigin-RevId: 716702141
2025-01-17 09:47:33 -08:00
sheenachhabra
4ac4f7e2e0 Split InAppMuxer into InApp Mp4Muxer and FragmentedMp4Muxer
This is pre work required to remove `Muxer.java` interface
from the muxer module.
`Mp4Muxer` and `FragmentedMp4Muxer` will no longer implement
the `Muxer` interface.

PiperOrigin-RevId: 716669531
2025-01-17 08:01:28 -08:00
bachinger
b49eaf9e87 Add two MetadataRenderer instances by default
To receive multiple schemes of metadata emitted by a stream, multiple
`MetadataRenderer` instances need to be used. This change makes
`DefaultRenderersFactory` add two metadata renderers by default.

PiperOrigin-RevId: 715790821
2025-01-15 07:31:13 -08:00
tonihei
a2016f03c6 Remove ExoPlayer components
They have been deprecated since ExoPlayer 2.16.0 and can be easily
replaced by the exact same call in ExoPlayer directly.

PiperOrigin-RevId: 715755105
2025-01-15 05:11:09 -08:00
ibaker
736c7528cb Ignore EOS buffer timestamps in CeaDecoder.queueInputBuffer
This is aligned with the documentation of `MediaCodec` which says the
timestamp of a buffer with `BUFFER_FLAG_END_OF_STREAM` should be
ignored:
https://developer.android.com/reference/android/media/MediaCodec#end-of-stream-handling

Add a test that exercises this by clipping off the end of a sample with
CEA-608 captions, because this creates an EOS-flagged buffer with a
non-EOS timestamp.

Also add a straightforward playback test for the
`fragmented_captions.mp4` sample.

PiperOrigin-RevId: 715716036
2025-01-15 02:40:07 -08:00
michaelkatz
2eb8e53f8c Fix getDurationToProgress for audio renderers to reset after seeking
Currently, if a seek occurs when the audio sink was providing back pressure, the audio renderers will provide a durationToProgress based on the last non-writable sample prior to the seek.

Solution is to reset the value used for the `getDurationToProgress` when onPositionReset occurs.

This CL also makes sure to reset the value whenever the audiosink is flushed or reset.

PiperOrigin-RevId: 715361834
2025-01-14 06:49:43 -08:00
Copybara-Service
d18ad57e30 Merge pull request #1979 from wischnow:main
PiperOrigin-RevId: 714911017
2025-01-13 04:09:58 -08:00
jbibik
28027c64fd [ui-compose] Add aspect ratio to PresentationState
It captures the information needed for the UI logic related to rendering of the video track (and later images) to the surface.

The video size will be correct only after the Player decoded the video onto the surface and can't be reliably extracted from MediaItem's metadata. The information about the video's true aspect ratio helps inform the UI elements (such as PlayerSurface Composable) how to customize the Modifiers.

Use this state in demo-compose to show off functionality of changing `PlayerSurface`'s aspectRatio

PiperOrigin-RevId: 714104260
2025-01-10 10:50:53 -08:00
Ian Baker
4744f082af Add release note 2025-01-10 16:04:04 +00:00
tonihei
71cb246913 Fix bug where changing index does not reevaluate derived metadata
When the current MediaMetadata is automatically derived from the
MediaItem and Tracks, the result may change when state.buildUpon()
is used and new input data is provided (e.g. new current index).
To avoid reusing the previously derived MediaMetadata, we need to
reset it to null and re-evaluate it on every call to build()

Issue: androidx/media#1940
PiperOrigin-RevId: 714021424
2025-01-10 05:59:45 -08:00
tonihei
f6eb2e6dd5 Fix discontinuity reporting in ClippingMediaPeriod
The initial discontinuity is currently only reported if
the period is prepared at the clip start position. However,
we need the discontinuity whenever we prepare at a non-zero
position (unless we know all samples are sync samples).

PiperOrigin-RevId: 713994155
2025-01-10 04:04:03 -08:00
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
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
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
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
bachinger
ec50358784 Do not override pending info when masking
PiperOrigin-RevId: 712919739
2025-01-07 08:26:19 -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
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
Ian Baker
618c2cf952 Add a release note and format with google-java-format 2025-01-06 15:13:32 +00:00
Copybara-Service
871c15946b Merge pull request #1947 from totallyunknown:fix/dash-playlist-infinite-loop
PiperOrigin-RevId: 712494399
2025-01-06 05:28:26 -08:00
ivanbuper
7ecaebe3d6 Fix underflow in Sonic#getOutputSize() after #queueEndOfStream()
For the [0.5; 1) speed range, the combination of having a "slow down"
speed (i.e. more output frames than input frames), and Sonic potentially
needing to copy more input frames that are available in the input buffer
can lead to an unexpected underflow.

Specifically, the underflow happens in Sonic#queueEndOfStream() when the
following conditions are met (skipping some minor ones):

1. `inputFrameCount < remainingInputToCopyFrameCount`
2. `0.5f <= speed < 1`.
3. `outputFrameCount <
    (inputFrameCount / remainingInputToCopyFrameCount) / 2`.

This underflow caused `SonicAudioProcessor#isEnded()` to return a false
negative (because `getOutputSize() != 0`), which would stall the
`DefaultAudioSink` waiting for processing to end after EOS.

In practical terms, the underflow is relatively easy to reproduce if we
consume all of Sonic's output and then immediately queue EOS without
queueing any more input in between. This should cause both
`inputFrameCount` and `outputFrameCount` to drop to 0.

PiperOrigin-RevId: 711773565
2025-01-03 09:26:32 -08:00
ivanbuper
d6e4642bcf Rollback of 5ab9a7856f
PiperOrigin-RevId: 710770581
2024-12-30 12:24:05 -08:00
rohks
3b9737f88a Fix release notes based on Devsite linter warnings
PiperOrigin-RevId: 709329498
2024-12-24 06:17:43 -08:00
rohks
5c40498054 Fix quotes around parameter name in release notes
PiperOrigin-RevId: 708334464
2024-12-20 08:47:17 -08:00
sheenachhabra
1b0e2fb75e Rename "setSampleCopyEnabled" to "setSampleCopyingEnabled" in muxer
PiperOrigin-RevId: 708322440
2024-12-20 07:57:59 -08:00
shahddaghash
915130eb00 Add usePlatformDiagnostics in Transformer.
Added a new `usePlatformDiagnostics` in Transformer. This parameter enables/disables forwarding editing events and performance data to the platform.

This is pre-work for metrics support in Transformer. In the following CLs, metrics collection and forwarding will be implemented.

PiperOrigin-RevId: 707930368
2024-12-19 09:03:19 -08:00
tonihei
cb578c0f37 Additional comments and limit update interval to manifest value 2024-12-19 16:20:44 +00:00